-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnext.config.mjs
More file actions
49 lines (47 loc) · 2.14 KB
/
Copy pathnext.config.mjs
File metadata and controls
49 lines (47 loc) · 2.14 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
/** @type {import('next').NextConfig} */
// Deliberately not a script-src CSP. This page pulls artwork from 13k publisher
// domains and audio from as many again, and the ad and analytics loaders inject
// their own markup — a source allowlist over that is a list nobody can keep
// correct, and getting it wrong takes the artwork out silently. The headers
// here are the ones that are unambiguous on a site with no user-generated HTML.
// frame-ancestors is the clickjacking control and constrains only who may embed
// us, so it costs nothing to set.
const securityHeaders = [
{
key: "Strict-Transport-Security",
// Safe here: http already 301s to https, and the apex has no subdomains.
// No preload — that list is one-way and its own operator discourages it.
value: "max-age=31536000; includeSubDomains",
},
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Content-Security-Policy", value: "frame-ancestors 'self'" },
// The legacy half of the same control, for browsers that predate it.
{ key: "X-Frame-Options", value: "SAMEORIGIN" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
// Features this site does not use. WebAuthn is intentionally absent from the
// list: naming publickey-credentials-* here would disable passkey sign-in.
{
key: "Permissions-Policy",
value: "camera=(), microphone=(), geolocation=(), payment=(), usb=()",
},
];
const nextConfig = {
reactStrictMode: true,
// The database client (and pg underneath it) runs in the Node server only;
// keep them external so the bundler never tries to pull them in.
serverExternalPackages: ["@profullstack/libsql-pg", "pg"],
images: { unoptimized: true },
poweredByHeader: false,
async headers() {
return [
{ source: "/:path*", headers: securityHeaders },
// The podcaster's OpenProfile.md, discoverable from the show page
// without parsing it (logicsrc.com/openprofile, discovery rule 2).
{
source: "/podcast/:slug",
headers: [{ key: "Link", value: '<https://p0dcasters.com/podcast/:slug/openprofile.md>; rel="openprofile"' }],
},
];
},
};
export default nextConfig;