Coupled major-version upgrade. These can't be done independently:
| Package |
Current |
Target |
next |
14.2.x |
16.x |
nextra |
3.3.x |
4.x |
nextra-theme-docs |
3.3.x |
4.x |
react / react-dom |
18.3.x |
19.x |
@types/react |
18.x |
19.x |
Nextra 4 requires Next.js 15+, which requires React 19 — so all four must move together.
Migration scope
Nextra 4 is not a drop-in bump. The substantive changes:
- App Router instead of Pages Router. Move all content from
pages/ to content/. The catch-all route lives under app/.
mdx-components.tsx at the repo root becomes the canonical place for component overrides. Today our overrides sit in theme.config.tsx's components field (light- and dark-mode-aware Link, Embed, Columns, Column).
_meta.{js,jsx,ts,tsx} files survive but with some behavior changes (e.g. how display: \"children\" and display: \"hidden\" interact with the App Router).
theme.config.tsx schema has shifted slightly (banner, footer, search props).
- Migration scripts in
scripts/ (migrate-content.mjs, build-meta.mjs, promote-folder-indexes.mjs, etc.) were tailored to the Pages Router tree and would not match the new directory structure. They're historical now; not load-bearing for the upgrade itself.
Next.js 15→16 has changes around async params and default caching, but for a static-export docs site (output: \"export\") most of those don't apply.
Verification checklist
Why this is worth doing eventually
No functional bug today; benefits are: current versions, Nextra 4's improved theming and search, React 19 features available if we ever need them, no looming EOL concerns.
Why this isn't urgent
Nothing's broken on Nextra 3. Estimated effort: ~half a day if the content moves cleanly; longer if any of the custom-component overrides need rework.
Coupled major-version upgrade. These can't be done independently:
nextnextranextra-theme-docsreact/react-dom@types/reactNextra 4 requires Next.js 15+, which requires React 19 — so all four must move together.
Migration scope
Nextra 4 is not a drop-in bump. The substantive changes:
pages/tocontent/. The catch-all route lives underapp/.mdx-components.tsxat the repo root becomes the canonical place for component overrides. Today our overrides sit intheme.config.tsx'scomponentsfield (light- and dark-mode-awareLink,Embed,Columns,Column)._meta.{js,jsx,ts,tsx}files survive but with some behavior changes (e.g. howdisplay: \"children\"anddisplay: \"hidden\"interact with the App Router).theme.config.tsxschema has shifted slightly (banner, footer, search props).scripts/(migrate-content.mjs,build-meta.mjs,promote-folder-indexes.mjs, etc.) were tailored to the Pages Router tree and would not match the new directory structure. They're historical now; not load-bearing for the upgrade itself.Next.js 15→16 has changes around async params and default caching, but for a static-export docs site (
output: \"export\") most of those don't apply.Verification checklist
pnpm buildsucceeds<Callout>,<Embed>,<Columns>/<Column>,<Steps>prose-linkstyling on internal/external links survives.github/workflows/pr-check.yml) still passes against the new build outputWhy this is worth doing eventually
No functional bug today; benefits are: current versions, Nextra 4's improved theming and search, React 19 features available if we ever need them, no looming EOL concerns.
Why this isn't urgent
Nothing's broken on Nextra 3. Estimated effort: ~half a day if the content moves cleanly; longer if any of the custom-component overrides need rework.