Turbopack build omits __NEXT_DATA__.dynamicIds for next/dynamic({ ssr: true }) declared in pages/_app — server HTML discarded on hydration
@andrewimm is already working on this.
Since Sep 5, 2026.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/milosz-gustawski/next16-turbopack-app-dynamicids-repro
To Reproduce
npm installnpm run build(Turbopack, the Next 16 default) and inspect__NEXT_DATA__.dynamicIdsin.next/server/pages/index.html:node -e "const m=require('fs').readFileSync('.next/server/pages/index.html','utf8').match(/__NEXT_DATA__\" type=\"application\/json\">(.*?)<\/script>/s); console.log(JSON.parse(m[1]).dynamicIds)" # => [ 704 ] <- only the page-level dynamic; the _app-level one is missingnpm run build:webpack(same app,next build --webpack) and run the same command:# => [ 6227, 3867 ] <- both dynamics presentnpm run starton the Turbopack build and open the browser console: hydration mismatch ("Expected server HTML to contain a matching in ", minified React #418/#423) and the server-rendered chrome is discarded. The webpack build is clean.
Current vs. Expected behavior
The repro has two next/dynamic({ ssr: true }) components:
- one declared in
pages/index.tsx→ its module id is emitted in__NEXT_DATA__.dynamicIds - one declared in
pages/_app.tsx→ its module id is missing fromdynamicIdsunder Turbopack builds (present under--webpack)
In both builds the _app-level component's markup is server-rendered into the HTML — only the dynamicIds entry differs. Because the id is missing, the client treats the loadable as not-yet-loaded, renders its fallback during hydration, React detects the mismatch and replaces the server HTML for the subtree.
Expected: dynamicIds includes ids for ssr: true loadables regardless of whether they are declared in a page module or in pages/_app, matching webpack behavior.
Declaring next/dynamic in _app is the standard pattern for persistent site chrome (header/footer/cookie banner), so this silently breaks SSR/SEO for exactly the always-visible parts of a site. Non-page shared components and named-export variants (.then(m => m.X)) are unaffected — it is specifically the pages/_app declaration point.
Also reproduced on next@16.3.3, with react@18.3.1, and the equivalent mismatch is logged by next dev (Turbopack).
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.4.0
Available memory (MB): 16384
Available CPU cores: 10
Binaries:
Node: 24.9.0
npm: 11.6.0
pnpm: 10.34.4
Relevant Packages:
next: 16.3.4 // Latest available version is detected (16.3.4).
react: 19.2.8
react-dom: 19.2.8
typescript: 7.0.2
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Turbopack, Lazy Loading
Which stage(s) are affected? (Select all that apply)
next build (local), next start (local), next dev (local)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.