This document describes the migration of apps/design-library from Vite + React Router to Next.js (App Router), including folder structure and token strictness decisions.
What changed (baseline → target)
- App:
apps/design-library— Next.js 16 withsrc/approutes; removed Vite,index.html,main.tsx, andApp.tsx. - Routing: URLs under
/library/...are implemented assrc/app/library/**/page.tsxfiles plussrc/app/library/layout.tsxwrappingLibraryAppLayout. - Tokens import: Vite alias
@tokensreplaced by package export@spring/ds-react/tokens(packages/spring-ds-react/package.json). - Tailwind:
tailwind.config.mjsimports tokens from@spring/ds-react/tokens(no deep relative path toindex.mjs). - CSS variables: Root
src/app/layout.tsximports@spring/ds-react/tokens/generated/css-variables.css(SSR-friendly; no runtime<style>injection). - Fonts: Inter via
next/font/google;globals.cssno longer@imports Google Fonts. Tailwind:root--font-sansusesvar(--font-inter), …. - Token validation:
scripts/sync-tokens.jsruns Zod shape checks and verifies every string path infigmaMapsections resolves viagetByPath(root devDependencyzod). - Logos:
SpringLogoassets live inpackages/spring-ds-react/src/assets/(no Vite?url, no dependency onapps/design-librarypaths).
Target folder structure
Monorepo unchanged: apps/*, packages/*.
Inside the design-library app:
apps/design-library/
next.config.ts
postcss.config.js
tailwind.config.mjs
tsconfig.json
package.json
public/ # static assets (if any)
src/
app/ # Next.js App Router
layout.tsx # root: metadata, Inter, token CSS, globals.css
page.tsx # redirect → /library/getting-started
not-found.tsx
library/
layout.tsx # LibraryAppLayout + {children}
page.tsx # redirect → getting-started
getting-started/page.tsx
design-tokens/...
icons/page.tsx
components/.../page.tsx
patterns/.../page.tsx
design-libraries/.../page.tsx
gallery/ # existing docs UI (layouts, nav, pages)
lib/ # tokenDatasets, useHash, utils
styles/globals.css
middleware.ts # at src/middleware.ts — redirects / and non-/library/*
Note: middleware.ts lives under src/ per Next.js. Next 16 may warn that the middleware file convention is deprecated in favor of “proxy”; revisit when upgrading.
Token strictness
-
Single source of truth (unchanged):
design-tokens.mjs/core.mjs; generation vianpm run tokens:sync→generated/css-variables.css. -
Public export:
@spring/ds-react/tokensand@spring/ds-react/tokens/generated/css-variables.cssare declared in packageexports. -
sideEffects:@spring/ds-reactlists**/*.cssand token**/*.mjsso bundlers do not drop CSS side effects. -
Build-time Zod validation: On
node scripts/sync-tokens.js build, after importing the token bundle,validateTokenBundleruns:- Zod schema for
primitive,semantic, andfigmaMap(with passthrough for extra keys). - For each
figmaMapsection (exceptnodes), every string value must resolve withgetByPath(tokens, path)(non-undefined).
- Zod schema for
-
TypeScript: App
tsconfig.jsonremainsstrict: true(Next may adjustjsx/ includes automatically).
Next.js wiring (checklist)
transpilePackages: ['@spring/ds-react']—next.config.ts.- Path aliases:
@/*→./src/*; explicit@spring/ds-react/tokensandiconspaths in tsconfig. - Tailwind
content:src/**/*andpackages/spring-ds-react/src/**/*(see tailwind config). - Client boundaries: Interactive gallery modules use
'use client'(including pages that pass render props into client components, e.g. input anatomy blocks).
Migration sequence (as executed)
- Add
@spring/ds-react/tokensexport; switch Tailwind and TS imports off@tokens/ relativeindex.mjs. - Scaffold Next (
layout,page,librarylayout,transpilePackages, token CSS import). - Port every React Router segment to
src/app/library/.../page.tsx; remove Vite entry and router. - Add Zod validation to
scripts/sync-tokens.js; addzodto rootdevDependencies. - Update manual browser preview script for
next starton port 5180. - Record this document at
docs/history/migration-vite-to-next.md.
Risks and follow-ups
| Topic | Notes |
|---|---|
| Next middleware deprecation | Next 16 warns about middleware → “proxy”; monitor upgrade guide. |
| Duplicate logo assets | apps/design-library/src/assets/SpringLogo*.svg may still exist; canonical copies are under packages/spring-ds-react/src/assets/. |
| React Server Components | Prefer server page.tsx wrappers; keep interactive docs in client gallery modules. |
Out of scope (still)
- Repo-wide RSC refactors for every
spring-ds-reactcomponent. - Splitting tokens into a dedicated
@spring/tokenspackage. - Deploy /
basePathspecifics (Vercel, static export, etc.).