Upgrade Next.js to 15, React to 19, and related deps#409
Upgrade Next.js to 15, React to 19, and related deps#409
Conversation
shilman
commented
Apr 13, 2026
- next: ^14 → ^15 (frontpage, addon-catalog, ui)
- react/react-dom: ^18 → ^19 (all workspace packages)
- framer-motion: ^11 → ^12 (fix AnimationControls type, 'pop'→'spring', RefObject null)
- next-plausible: ^3 → ^4 (add src param, simplify PlausibleProvider)
- @storybook/nextjs: ^8.1.1 → ^8.6
- Await async params in releases, recipes, docs slug pages
- Await headers() in versions route and docs footer actions
- Extract getLlmsBannerLines to lib/ (Next.js 15 disallows non-route exports)
- Remove JSX.Element return types (removed from @types/react@19)
- Add legacy-peer-deps=true to .npmrc
- next: ^14 → ^15 (frontpage, addon-catalog, ui) - react/react-dom: ^18 → ^19 (all workspace packages) - framer-motion: ^11 → ^12 (fix AnimationControls type, 'pop'→'spring', RefObject null) - next-plausible: ^3 → ^4 (add src param, simplify PlausibleProvider) - @storybook/nextjs: ^8.1.1 → ^8.6 - Await async params in releases, recipes, docs slug pages - Await headers() in versions route and docs footer actions - Extract getLlmsBannerLines to lib/ (Next.js 15 disallows non-route exports) - Remove JSX.Element return types (removed from @types/react@19) - Add legacy-peer-deps=true to .npmrc Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
❌ Deploy Preview for storybook-addon-catalog failed. Why did it fail? →
|
❌ Deploy Preview for storybook-frontpage failed. Why did it fail? →
|
There was a problem hiding this comment.
Pull request overview
Upgrades the monorepo’s Next.js/React ecosystem (Next 15 + React 19) and updates code to match new framework/library type and runtime requirements (async params/headers(), React 19 typing changes, framer-motion + next-plausible updates).
Changes:
- Bump Next.js to
^15, React/ReactDOM +@types/*to^19, and update related deps (framer-motion, next-plausible, Storybook Next integration). - Update Next.js app-router code to await async inputs (
params,headers()), and adjust components for React 19 typing changes (removeJSX.Elementannotations). - Refactor LLM banner helper into a shared lib module and update Plausible configuration.
Reviewed changes
Copilot reviewed 24 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/utils/package.json | Updates React + React type packages for the utils workspace. |
| packages/ui/src/footer/top-section.tsx | Removes JSX.Element return annotation for React 19 types compatibility. |
| packages/ui/src/dropdown-menu/index.tsx | Removes JSX.Element return annotation for React 19 types compatibility. |
| packages/ui/package.json | Upgrades Next/React/types + next-plausible for the UI package. |
| package.json | Adds root React/ReactDOM deps to align workspace resolution. |
| apps/frontpage/package.json | Upgrades Next/React/types + framer-motion/next-plausible + Storybook Next integration for frontpage. |
| apps/frontpage/next.config.js | Updates withPlausibleProxy configuration to v4 API. |
| apps/frontpage/next-env.d.ts | Adds Next.js 15 routes types reference and updates doc link. |
| apps/frontpage/lib/get-llms-banner-lines.ts | Extracts shared LLM banner line generator into lib/. |
| apps/frontpage/components/home/share/player.tsx | Updates framer-motion transition type (pop → spring). |
| apps/frontpage/components/home/develop/demo/controls.tsx | Updates framer-motion control typing for v12. |
| apps/frontpage/components/home/automate/ui-tests/ui-tests.tsx | Adjusts ref typing for React 19/framer-motion integration. |
| apps/frontpage/components/docs/footer/actions.ts | Awaits headers() per Next.js 15 API expectations. |
| apps/frontpage/app/versions/route.ts | Awaits headers() per Next.js 15 API expectations. |
| apps/frontpage/app/releases/iframe/[slug]/page.tsx | Updates route params typing/usage to async per Next.js 15. |
| apps/frontpage/app/releases/[slug]/page.tsx | Updates route params typing/usage to async per Next.js 15. |
| apps/frontpage/app/recipes/[...name]/page.tsx | Updates route params typing/usage to async per Next.js 15. |
| apps/frontpage/app/providers.tsx | Simplifies PlausibleProvider usage for next-plausible v4. |
| apps/frontpage/app/llms.txt/route.ts | Imports extracted LLM banner helper (removes non-route export). |
| apps/frontpage/app/llms-full.txt/route.ts | Switches LLM banner helper import to new shared lib module. |
| apps/frontpage/app/layout.tsx | Removes JSX.Element return annotation for React 19 types compatibility. |
| apps/frontpage/app/docs/[...slug]/page.tsx | Updates route params typing/usage to async per Next.js 15. |
| apps/addon-catalog/package.json | Upgrades Next/React/types + framer-motion/next-plausible for addon-catalog. |
| apps/addon-catalog/app/providers.tsx | Simplifies PlausibleProvider usage for next-plausible v4. |
| .npmrc | Adds legacy-peer-deps=true to bypass peer-dependency resolution failures during upgrade. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| export function UITests() { | ||
| const ref = useRef(null); | ||
| const ref = useRef<HTMLDivElement>(null); |
There was a problem hiding this comment.
useRef<HTMLDivElement>(null) is incompatible with strictNullChecks (null isn’t assignable to HTMLDivElement) and will fail typecheck. Use useRef<HTMLDivElement | null>(null) (or useRef<HTMLDivElement>(null!) if you truly never expect null) to match the RefObject<HTMLDivElement | null> prop type and useInView usage.
| const ref = useRef<HTMLDivElement>(null); | |
| const ref = useRef<HTMLDivElement | null>(null); |
| "@next/mdx": "^14.2.4", | ||
| "@next/third-parties": "^14.2.4", |
There was a problem hiding this comment.
These @next/* packages are still pinned to ^14.2.4 while next has been upgraded to ^15. They typically track Next’s major version and may enforce it via peer deps; consider bumping them to ^15 as well to avoid incompatibilities / relying on legacy-peer-deps.
| "@next/mdx": "^14.2.4", | |
| "@next/third-parties": "^14.2.4", | |
| "@next/mdx": "^15", | |
| "@next/third-parties": "^15", |
| "graphql-request": "^7.1.0", | ||
| "human-format": "^1.2.0", | ||
| "next": "^14.2.4", | ||
| "next-plausible": "^3.12.0", | ||
| "next": "^15", | ||
| "next-plausible": "^4.0.0", | ||
| "next-themes": "^0.3.0", |
There was a problem hiding this comment.
With next upgraded to ^15, this app still has @next/third-parties pinned to ^14.2.4 (earlier in this file). @next/* packages generally track Next’s major version and may enforce it via peer deps; consider bumping @next/third-parties to ^15 to keep the Next toolchain consistent.
| "@types/react": "^19", | ||
| "@types/react-dom": "^19", | ||
| "eslint": "^8", | ||
| "eslint-config-next": "14.2.4", |
There was a problem hiding this comment.
eslint-config-next is still pinned to 14.2.4 while next has been upgraded to ^15. This can cause peer dependency conflicts and mismatched lint rules; consider upgrading eslint-config-next to the matching 15.x version (or switching to @next/eslint-plugin-next consistently) so linting aligns with the installed Next version.
| "eslint-config-next": "14.2.4", | |
| "eslint-config-next": "^15", |
| @@ -0,0 +1 @@ | |||
| legacy-peer-deps=true | |||
There was a problem hiding this comment.
Setting legacy-peer-deps=true repo-wide disables peer dependency resolution errors for all installs, which can mask real version incompatibilities (especially during a major Next/React upgrade) and make runtime issues harder to diagnose. Prefer resolving peer conflicts directly (align @next/*/Storybook versions, use npm overrides, etc.) or scope this to CI/workarounds with clear justification.
| legacy-peer-deps=true |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>