Server & build stack
server.js
server.js is the dev and production entry. pnpm dev and pnpm start both run this file, not next dev / next start.
Its actual responsibilities (simplified):
- Load
.env.local - Prepare Next.js (
next({ dev })) - Create the HTTP server
- For each request:
- Parse with
toParsedUrl(req), writing the URL first segment (if it iszh-CN/zh-TW/en) toquery.locale(backward compatible for older hooks) - Call
app.getRequestHandler()and hand off to Next
- Parse with
- Listen for SIGTERM / SIGINT / SIGHUP with a graceful shutdown (3 s force-exit fallback)
- Listen on
process.env.PORT(default 3000)
Note: server.js does not perform locale selection — that is proxy.ts's job. server.js only passes the URL first segment as query.locale so older code can keep using useRouter().query.locale.
Optional bypass: an inline comment reserves a if (parsedUrl.pathname.startsWith('/analytics/')) block for a self-hosted analytics service proxy; enable only if needed.
next.config.js
Key fields:
NEXT_BUILD_DIR lets a deployment wrapper specify a custom output directory; do not set it normally.
In dev you must access the site via dev.arsvine.com; otherwise the COS bucket Referer check fails and images break.
remotePatterns is not declared here; it is centralized in config/image-hosts.js.
Webpack disables config.cache in Windows production builds (config.cache = false) to avoid webpack 5 + Windows cache serialization issues.
i18n plugin
i18n/request.ts is the next-intl 4 request config entry; it loads locales/<locale>.json per locale.
Entry trio
Vercel project settings:
Sub-builders
pnpm env:sync runs scripts/sync-env-files.mjs to sync .env.local into .env.example (redacted). Both docs site and main site share the same SECTIONS list; add new env vars there.
pnpm assets:prepare / build / publish are the asset publishing pipeline (see asset-pipeline).