next.config は各イベントで手書きしない。@event/core の createNextConfig() が 全イベント共通の既定を供給する。spikes はヘッダ皆無、ivs は CSP 無し、xdeal だけが CSP/HSTS を持つ、 という3実装のばらつきをこの factory で一本化した(@harvested-from xdeal-lp / ivs-cms next.config.ts)。
starter の実配線
import { createNextConfig } from "@event/core";
const nextConfig = createNextConfig({
transpilePackages: [
"@event/schema", "@event/fours-sdk", "@event/core", "@event/cms",
"@event/session-card", "@event/shell", /* … @event/* を列挙 … */
],
security: { csp: { fourS: true, vercelBlob: true } },
});
export default nextConfig;
security を省くと堅い既定 CSP がそのまま付く。security: false で全ヘッダを外せる。
createNextConfig が黙って供給する既定
| 既定 | 中身 | 根治した事故 |
|---|---|---|
| distDir 分離 | NEXT_DIST_DIR / BUILD_LOCAL=1 → .next-local | dev と build が同じ .next を共有して dev が壊れる |
| dev memory cache | webpack dev 時 cache = { type: "memory" } | .next/cache 破損 → 全 route 500 |
| removeConsole | 本番で console.log/info/debug 除去(error/warn は残す) | 本番ログ漏れ |
| reactStrictMode | true 固定 | — |
| security headers | buildSecurityHeaders() を /(.*) に適用 | ヘッダ未設定アプリ |
CreateNextConfigOptions の残りの knob: tracingExcludes(onnxruntime 等の tracing 除外・Vercel 250MB 対策)、 imageHosts(images.remotePatterns を https 前提で生成)、extend(最後に浅マージ・headers/webpack は上書き注意)。 BUILD_LOCAL=1 は「dev 稼働中にローカル build を打つ」ときの distDir を分けるスイッチで、dev の .next を壊さない。
buildSecurityHeaders — 常時付くヘッダ
security に SecurityHeadersOptions を渡す(csp / cspReportOnly(既定 true)/ frameOptions(既定 SAMEORIGIN))。 CSP 以外は無条件で付く:
| ヘッダ | 値 |
|---|---|
Strict-Transport-Security | max-age=63072000; includeSubDomains; preload |
X-Content-Type-Options | nosniff |
Referrer-Policy | strict-origin-when-cross-origin |
Permissions-Policy | camera=() microphone=() geolocation=() interest-cohort=() payment=() usb=() …(全無効) |
Cross-Origin-Opener-Policy | same-origin |
Cross-Origin-Resource-Policy | same-origin |
X-Frame-Options | SAMEORIGIN(frameOptions で DENY / false) |
cspReportOnly(既定 true)だと enforce と同一の CSP を Content-Security-Policy-Report-Only にも二重出力する。 違反を観察しつつ強制もかける構えである。
buildCsp — フラグで connect-src が伸びる
CSP は self ベースの堅い構成が既定で、外部サービスを使うぶんだけフラグで開ける。既定 ON は fourS / vercelBlob / googleFonts、既定 OFF はアナリティクス系・unsafeEval / captureExport 等:
security: {
csp: {
fourS: true, // connect-src に api.4s.link / static.4s.link / cognito-idp を許可(既定 true)
vercelBlob: true, // *.public.blob.vercel-storage.com(既定 true)
vercelAnalytics: false, googleAnalytics: false, metaPixel: false,
turnstile: false, sentry: false, googleFonts: true,
unsafeEval: false, // html2canvas 系 capture / dev でのみ true
captureExport: false, // connect-src に data:/blob:(modern-screenshot の inline capture 用)
extra: { "img-src": ["https://cdn.example.com"] }, // 同 key は空白結合で追記
},
},
| フラグ | 既定 | 開く先(抜粋) |
|---|---|---|
fourS | true | connect-src: api.4s.link api-staging2/-develop2.4s.link static.4s.link cognito-idp.ap-northeast-1.amazonaws.com |
vercelBlob | true | connect-src: https://*.public.blob.vercel-storage.com |
googleFonts | true | style-src fonts.googleapis.com / font-src fonts.gstatic.com |
turnstile sentry googleAnalytics metaPixel vercelAnalytics | false | 各サービスの script/connect/frame |
unsafeEval | false | script-src に 'unsafe-eval' |
captureExport | false | connect-src に data: blob: |
固定の骨格は毎回同じ: default-src 'self' / img-src 'self' data: blob: https: / object-src 'none' / frame-ancestors 'self' / form-action 'self' / base-uri 'self' / upgrade-insecure-requests。 script-src は 'self' 'unsafe-inline'(Next の inline スクリプト都合)を基本とし、フラグで足す。 csp に文字列を直接渡せば buildCsp を通さず生の CSP を使える。csp: false で CSP だけ外す(他ヘッダは残る)。