diff --git a/Dockerfile b/Dockerfile index 64d8a57..8b17faa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,9 @@ WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . ARG NEXT_PUBLIC_API_BASE_URL +ARG NEXT_PUBLIC_SECURITY_KEY ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL +ENV NEXT_PUBLIC_SECURITY_KEY=$NEXT_PUBLIC_SECURITY_KEY RUN npm run build FROM base AS runner diff --git a/next.config.ts b/next.config.ts index 95db85b..e74a59d 100644 --- a/next.config.ts +++ b/next.config.ts @@ -58,12 +58,16 @@ const nextConfig: NextConfig = { ], }, { - // Static pages – moderate cache - source: "/:path((?!api/).*)", + // Application HTML pages – no-store to prevent HTML/shell caching in WebView + source: "/:path((?!api/|_next/|fonts/|assets/).*)", headers: [ { key: "Cache-Control", - value: "public, max-age=3600, stale-while-revalidate=86400", + value: "no-store, no-cache, must-revalidate, max-age=0", + }, + { + key: "Pragma", + value: "no-cache", }, ], }, @@ -76,6 +80,17 @@ const nextConfig: NextConfig = { }, ], }, + { + // Images and icons are not content-hashed, so revalidate instead of + // pinning them for a year. + source: "/assets/:path*", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=86400, stale-while-revalidate=604800", + }, + ], + }, ]; }, }; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b176178..6c3f6b3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -24,6 +24,14 @@ const amiri = Amiri({ fallback: ["Arial", "sans-serif"], }); +const isDevelopment = process.env.NODE_ENV !== "production"; + +// Never ship a fallback token to production: without it a real user whose +// Flutter token has not been injected yet would silently browse a test account. +const developmentFallbackToken = isDevelopment + ? (process.env.NEXT_PUBLIC_DEFAULT_TOKEN ?? "") + : ""; + export const metadata: Metadata = { title: "Habib Marriage", description: "Islamic Marriage Platform", @@ -117,7 +125,7 @@ export default function RootLayout({ } }, get: function() { - return this._habib_token || readCookie(HABIB_TOKEN_COOKIE) || sessionStorage.getItem(HABIB_TOKEN_COOKIE) || '${process.env.NEXT_PUBLIC_DEFAULT_TOKEN || "f3a7543b44ef0a713d1ee0d4f7866b3825cf1308"}'; + return this._habib_token || readCookie(HABIB_TOKEN_COOKIE) || sessionStorage.getItem(HABIB_TOKEN_COOKIE) || undefined; } }); } @@ -163,14 +171,14 @@ export default function RootLayout({