-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnext.config.mjs
More file actions
144 lines (135 loc) · 4.39 KB
/
Copy pathnext.config.mjs
File metadata and controls
144 lines (135 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
const fallbackSupabaseOrigin = "https://*.supabase.co";
export function buildContentSecurityPolicy(
supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL,
) {
const supabaseOrigin = normalizeOrigin(supabaseUrl) ?? fallbackSupabaseOrigin;
const supabaseWebsocketOrigin = supabaseOrigin.startsWith("https://")
? supabaseOrigin.replace("https://", "wss://")
: "wss://*.supabase.co";
return [
"default-src 'self'",
"base-uri 'self'",
"form-action 'self'",
"frame-ancestors 'none'",
"object-src 'none'",
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://checkout.razorpay.com https://va.vercel-scripts.com",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: blob: https://*.supabase.co https://cdn.simpleicons.org",
"font-src 'self' data:",
`connect-src 'self' ${supabaseOrigin} ${supabaseWebsocketOrigin} https://*.supabase.co wss://*.supabase.co https://api.razorpay.com https://checkout.razorpay.com https://va.vercel-scripts.com`,
"frame-src https://api.razorpay.com https://checkout.razorpay.com",
"media-src 'self' data: blob: https://*.supabase.co",
"worker-src 'self' blob:",
"manifest-src 'self'",
].join("; ");
}
export const securityHeaders = [
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "Referrer-Policy",
value: "strict-origin-when-cross-origin",
},
{
key: "X-Frame-Options",
value: "DENY",
},
{
key: "Permissions-Policy",
value:
"camera=(), microphone=(), geolocation=(), browsing-topics=(), payment=(self)",
},
{
key: "Content-Security-Policy",
value: buildContentSecurityPolicy(),
},
];
const immutableCacheHeader = {
key: "Cache-Control",
value: "public, max-age=31536000, immutable",
};
/** @type {import('next').NextConfig} */
const nextConfig = {
allowedDevOrigins: ["127.0.0.1"],
images: {
formats: ["image/avif", "image/webp"],
},
// Escape hatch for measurement builds: `NEXT_DIST_DIR=.next-measure npm run
// build` writes to an isolated directory so a running `next dev` (which owns
// .next and rewrites it on demand) can't clobber the artifacts mid-analysis.
// Unset in CI and production, so the default output path is unchanged.
//
// Note: `next build` rewrites tsconfig.json's `include` to point at whatever
// distDir is active, so a measurement build leaves tsconfig dirty. Revert it
// (`git checkout -- tsconfig.json`) before committing.
distDir: process.env.NEXT_DIST_DIR || ".next",
// Pin the workspace root to this project. A stray lockfile in a parent
// directory (e.g. /home/user/package-lock.json) otherwise makes Turbopack
// infer the wrong root, which breaks App Router route resolution in dev
// (every route 404s). `next build` is unaffected, so this only fixes dev.
turbopack: {
root: import.meta.dirname,
},
// Tree-shake large icon/animation packages so only used exports ship.
experimental: {
optimizePackageImports: [
"lucide-react",
"framer-motion",
"@gsap/react",
],
},
compiler: {
// Strip console.* (except errors/warnings) from production bundles.
removeConsole:
process.env.NODE_ENV === "production"
? { exclude: ["error", "warn"] }
: false,
},
async headers() {
return [
{
source: "/(.*)",
headers: securityHeaders,
},
{
source: "/_next/static/:path*",
headers: [immutableCacheHeader],
},
{
source: "/:path*.woff2",
headers: [immutableCacheHeader],
},
];
},
};
function normalizeOrigin(value) {
if (!value) {
return null;
}
try {
return new URL(value).origin;
} catch {
return null;
}
}
// Opt-in bundle analysis: `ANALYZE=true npm run build` opens treemaps of the
// client/server bundles. Guarded so normal builds never touch it, and so the
// build still succeeds if @next/bundle-analyzer isn't installed.
let finalConfig = nextConfig;
if (process.env.ANALYZE === "true") {
try {
const { createRequire } = await import("node:module");
const require = createRequire(import.meta.url);
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: true,
});
finalConfig = withBundleAnalyzer(nextConfig);
} catch {
console.warn(
"[next.config] ANALYZE=true but @next/bundle-analyzer is not installed — run `npm i -D @next/bundle-analyzer`.",
);
}
}
export default finalConfig;