Migrate site to Next.js 16 (App Router on OpenNext/Cloudflare)

Draft
SE
3mo ago
+4447-1870

Summary

Migrates the website from TanStack Start + Vite to Next.js 16 (App Router), deployed via @opennextjs/cloudflare (workerd). The old src/ app, Vite config, and TanStack/Vite dependencies are removed.

Note: this branch also carries the earlier docs content work (KO translations, frontend/native guides, references cleanup) that was already committed on it.

Migration

  • Routing / i18n — app/[lang]/… with fumadocs i18n middleware (hideLocale: 'default-locale' → English at unprefixed URLs, Korean under /ko). Pure locale helpers live in lib/i18n.ts (server+client safe); React context in lib/locale.tsx.
  • UI — landing, docs (notebook layout), and 404 ported from src/layouts/** to components/** (client components where interactive).
  • Changelog — rendered as an async Server Component (app/[lang]/docs/changelog), fetching GitHub releases server-side (replaces the old createServerFn).
  • Search API — moved to a Next Route Handler (app/api/search).
  • Middleware — fumadocs i18n + Cloudflare Access (guarded to *.workers.dev previews, wrapped so it can't break i18n routing).

Follow-up polish (in this branch)

  • Last-updated — git commit time shown on docs pages via PageLastUpdate.
  • Error screens + Sentry — localized error.tsx / global-error.tsx (components/ErrorScreen.tsx) that call Sentry.captureException; client Sentry init in instrumentation-client.ts (no-op unless NEXT_PUBLIC_SENTRY_DSN is set).
  • Favicon — from the wvb logo (app/icon.png 256×256, app/apple-icon.png 180×180).
  • garu removed — dropped the garu-ko Korean WASM tokenizer + inlined model. Korean search now uses a lightweight eojeol tokenizer (lowercase + split on whitespace/punctuation, keeps Hangul) — no WASM, no extra deps.
  • Cleanup — removed all remaining TanStack/Vite code, config, and deps.

Notable decisions

  • Docs catch-all is force-dynamic. With no OpenNext incremental cache configured, serving a prerendered page through the default-locale rewrite (/docs/* → /en/docs/*) hangs. SSR is fast (MDX is bundled). SSG can be restored later by configuring an incremental cache in open-next.config.ts.
  • No server-side Sentry wired (workerd needs @sentry/cloudflare); client capture only.

Verification

next build (Turbopack) + opennextjs-cloudflare build green, oxlint + tsc pass. Smoke-tested on the workerd preview (yarn preview): home / docs / changelog / search (EN + KO) / 404 / error screen / last-updated / favicon all confirmed.

Caveats

  • Search does not work under next dev (Turbopack) — use yarn preview to test it locally on workerd.
  • Next 16 warns to rename middleware.ts → proxy.ts (deprecation warning only; works as-is).

🤖 Generated with Claude Code

https://claude.ai/code/session_01AFm8T7PNfkxNcN9yFTCe8J


Summary by cubic

Migrated the site from TanStack Start + Vite to Next.js 16 App Router on Cloudflare (@opennextjs/cloudflare), with bilingual i18n routing, SSR docs/changelog, localized error handling with @sentry/nextjs, and a CI link validator to prevent broken /docs routes and anchors.

  • Migration

    • App Router with app/[lang] and fumadocs i18n: EN unprefixed, KO at /ko; locale helpers and context split for server/client.
    • Middleware: fumadocs i18n rewrite and Cloudflare Access for *.workers.dev previews.
    • Docs: SSR via force-dynamic with notebook layout, mobile TOC, and “Last updated” timestamp; redirects /docs and /docs/guide to the first Guide page.
    • Changelog: async Server Component fetching GitHub releases; standalone shell without the docs sidebar.
    • Search API: Next Route Handler, forced Node runtime; Korean uses a lightweight tokenizer (no WASM) instead of garu-ko.
    • Errors: per-locale error boundaries (error.tsx, global-error.tsx) with client @sentry/nextjs; localized 404.
    • UI: landing and header components ported; favicon and apple icon added.
    • CI: adds yarn check:links (via next-validate-link) job to block bad /docs URLs and #anchors.
    • Notes: search doesn’t run under next dev (use yarn preview); Next 16 warns to rename middleware.ts → proxy.ts.
  • Dependencies

    • Added next@16, @opennextjs/cloudflare, fumadocs-*, @sentry/nextjs, @tailwindcss/postcss.
    • Removed TanStack Start, Vite tooling, and garu-ko.
    • Added open-next.config.ts, updated wrangler.jsonc for .open-next output, and a link-check script (scripts/validate-links.ts).