-
-
Notifications
You must be signed in to change notification settings - Fork 535
Expand file tree
/
Copy pathnext.config.ts
More file actions
134 lines (121 loc) · 4.09 KB
/
Copy pathnext.config.ts
File metadata and controls
134 lines (121 loc) · 4.09 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
import type { NextConfig } from 'next'
import legacyUrlManifest from './content/legacy-url-manifest.json'
import {
adminSecurityHeader,
googleOAuthFormSecurityHeader,
securityHeaders,
} from './lib/security/headers'
const legacyRedirects = legacyUrlManifest.entries.flatMap((entry) =>
entry.kind === 'redirect' && typeof entry.destination === 'string'
? [
{
source: entry.source,
destination: entry.destination,
permanent: true,
},
]
: [],
)
const legacyRewrites = legacyUrlManifest.entries.flatMap((entry) =>
entry.kind === 'rewrite' && typeof entry.destination === 'string'
? [{ source: entry.source, destination: entry.destination }]
: [],
)
const ogRuntimeAssets = [
'./app/_fonts/FrexSansGB-OG-*.ttf',
]
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
// Posts and newsletters are read from the repository at render time. The
// slug is dynamic, so output tracing cannot discover these files from the
// readFile calls on its own when packaging serverless functions.
outputFileTracingIncludes: {
'/og': [
...ogRuntimeAssets,
'./content/blog/**/*',
'./content/newsletters/**/*',
'./public/images/headshot.jpg',
],
'/blog/**': ['./content/blog/**/*', ...ogRuntimeAssets],
'/en/blog/**': ['./content/blog/**/*', ...ogRuntimeAssets],
'/newsletters/**': ['./content/newsletters/**/*', ...ogRuntimeAssets],
'/en/newsletters/**': [
'./content/newsletters/**/*',
...ogRuntimeAssets,
],
'/content/\\[\\.\\.\\.path\\]': [
'./content/blog/**/*',
'./content/newsletters/**/*',
],
},
// Pin the project root: when developing from a git worktree nested inside
// another checkout, Next's lockfile-based root inference walks too far up.
turbopack: { root: import.meta.dirname },
// Shared-element morphs (cover/title) on route navigation; browsers
// without the View Transitions API just navigate instantly.
experimental: {
authInterrupts: true,
globalNotFound: true,
useTypeScriptCli: true,
sri: { algorithm: 'sha256' },
},
images: {
// Post images are served from content/ via app/content/[...path]/route.ts;
// site portraits/avatars live in public/images
localPatterns: [
{ pathname: '/content/**' },
{ pathname: '/images/**' },
{ pathname: '/_next/static/**' },
],
},
headers: async () => [
{
source: '/:path*',
headers: [
...securityHeaders,
{
key: 'Link',
value: '</llms.txt>; rel="describedby"',
},
],
},
{
// The global policy is intentionally useful for public navigation, but
// admin API responses must never disclose their origin to another site.
source: '/api/admin/:path*',
headers: [{ key: 'Referrer-Policy', value: 'no-referrer' }],
},
{
// Admin pages ship clerk-js for background session-token refresh, so
// their policy alone allows the Clerk instance origins. The AMA
// settings entry below overrides this for its Google OAuth form.
source: '/admin/:path*',
headers: [adminSecurityHeader],
},
{
// The native connect form receives a same-origin 303 whose destination
// is Google's OAuth page. Limit that form destination to this one page.
source: '/admin/ama/settings',
headers: [googleOAuthFormSecurityHeader],
},
{
// Proxied link media (favicons, Open Graph images) are never a
// document that may run in this origin. Same-key entries later in
// this list override the global policy above, so exactly one
// Content-Security-Policy header is sent.
source: '/link-media/:path*',
headers: [
{
key: 'Content-Security-Policy',
value: "default-src 'none'; sandbox",
},
],
},
],
// The checked-in manifest is the v3 cutover contract for every preserved,
// replaced or retired public URL from the legacy site.
redirects: async () => legacyRedirects,
rewrites: async () => legacyRewrites,
}
export default nextConfig