MEGAINFRA-WEBAPP/next.config.js

84 lines
3.6 KiB
JavaScript
Raw Normal View History

/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: "standalone",
images: {
remotePatterns: [
// Allow image optimisation from any host. Lock this down once we
// know exactly which sources we'll pull attachments from.
{ protocol: "http", hostname: "**" },
{ protocol: "https", hostname: "**" },
],
},
// Allow any host / IP / tunneled domain so the app is reachable from
// LAN devices, reverse proxies and custom hostnames. Next 16's
// internal matcher rejects the literal "*", so we also rely on the
// `scripts/patch-next-dev-blocker.cjs` postinstall hook to neuter
// the dev-only cross-site guard. Production behaviour is unaffected
// because the patch only runs in development.
allowedDevOrigins: ["*", "192.168.50.126"],
experimental: {
serverActions: {
allowedOrigins: ["*"],
},
},
// pdfmake's server-side PdfPrinter pulls in pdfkit -> @foliojs-fork/fontkit,
// which loads font-shaping tables (data.trie etc.) from a path relative to
// its own installed location at runtime. Webpack-bundled into a Server
// Component/Route Handler chunk, that relative lookup 404s (ENOENT) because
// the .trie files never get copied alongside the bundle. Left as native
// Node `require`, the real node_modules layout resolves them correctly —
// the same reason `sharp` and `@react-pdf/renderer` ship in Next's own
// default external-packages list.
serverExternalPackages: ["pdfmake", "pdfkit", "@foliojs-fork/fontkit", "unpdf"],
// Maps moved from Sites to Surveying; keep old bookmarks working.
async redirects() {
return [
{ source: "/dashboard/sites/maps", destination: "/dashboard/surveying/maps", permanent: false },
{ source: "/dashboard/sites/:id/:map(map|map2|map3)", destination: "/dashboard/surveying/maps/:id/:map", permanent: false },
];
},
};
const withPWA = require("@ducanh2912/next-pwa").default({
// Development and production share public/sw.js. Never let a build-generated
// worker control HMR assets or rewrite the worker during local recompilation.
disable: process.env.NODE_ENV === "development",
dest: "public",
cacheOnFrontEndNav: false,
aggressiveFrontEndNavCaching: false,
reloadOnOnline: true,
register: true,
extendDefaultRuntimeCaching: true,
workboxOptions: {
cleanupOutdatedCaches: true,
clientsClaim: true,
skipWaiting: true,
runtimeCaching: [
// Account and site access can change at any time. A service worker
// must not replay another user's dashboard after sign-out.
{
urlPattern: ({ sameOrigin, url }) =>
sameOrigin && (/^\/(dashboard|clock|login|change-password)(\/|$)/.test(url.pathname) ||
url.pathname.startsWith("/api/")),
handler: "NetworkOnly",
},
// The QR confirmation must always use the server's current local-day
// decision. A cached yesterday lookup can say OUT while a POST writes IN.
{
urlPattern: ({ sameOrigin, url }) =>
sameOrigin && url.pathname === "/api/clock/employee-lookup",
handler: "NetworkOnly",
},
],
},
// The Web App Manifest lives at public/manifest.json (static file).
// next-pwa does NOT generate it — the `manifest` option was silently
// ignored in @ducanh2912/next-pwa@10.2.9. The dashboard metadata lives
// in public/manifest.json; the chat metadata lives in
// public/chat.webmanifest. Both are referenced from the per-route
// metadata blocks in src/app/layout.tsx and src/app/dashboard/chat/page.tsx.
});
module.exports = withPWA(nextConfig);