vercel / vercel/next.js

Soft navigation leaves the previous route's metadata mounted in head (duplicate og/twitter tags) on Vercel with 16.3

Open
#97,472 2 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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/brookton/next-soft-nav-metadata-repro

To Reproduce
  1. Deploy the linked app to Vercel.
  2. As soon as the deployment is READY, open / in a browser.
  3. Click "Article one" (client-side navigation; the link prefetches).
  4. In devtools, run:
[...document.head.querySelectorAll('meta[property="og:type"]')].map((m) => m.content);

Buggy result: ["website", "article"]. Every og:*, twitter:*, and description tag is present twice, previous route's values plus new route's values.

Timing matters: reproduction is reliable in the first minutes after a deployment, while the route's prefetch responses are served cold (x-vercel-cache: PRERENDER). Once those entries warm, the same flow is usually clean, so redeploy to re-enter the window. In our production app's CI, where Playwright runs minutes after each preview deployment, the failure reproduced on 100% of attempts including retries.

Current vs. Expected behavior

Current: after a soft navigation, the previous route's entire resolved metadata block stays mounted in <head> alongside the new route's block, so meta[property="og:type"] resolves to two elements (website and article). The state persists (verified 8+ seconds after navigation) and never self-corrects.

Expected: the new route's metadata replaces the previous route's, matching what a hard load of the same URL produces (a single correct set).

Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.6.0
Binaries:
  Node: 24.11.1
  npm: 11.6.2
Relevant Packages:
  next: 16.3.1
  react: 19.2.7
  react-dom: 19.2.7
  typescript: 5.9.3

Affected: 16.3.0 and 16.3.1. Not affected: 16.2.12 (same app, same fresh-deployment CI window, all browsers pass).

Which area(s) are affected?

Metadata, Navigation

Which stage(s) are affected?

Vercel (Deployed)

Additional context

Evidence gathered on a production app (five-browser Playwright CI plus scripted Chromium against the preview deployment):

  • Server HTML is always correct. Curling the deployed pages and a local next build && next start render shows exactly one metadata set, and hard reloads in the browser are always clean. The defect is purely client-side head reconciliation during soft navigation.
  • Blocking prefetch requests in the browser (aborting requests carrying Next-Router-Prefetch: 1) makes the identical navigation clean, implicating the prefetch payload path. Artificially delaying prefetch responses does not reproduce it, so it is not a simple in-flight race.
  • In the failing runs, the destination route's RSC prefetches were served with x-vercel-cache: PRERENDER. We could never reproduce against local next start, with cold or warm caches.
  • Browser split in the same CI pipeline on the same commit: chrome, ios (iPhone 12 emulation), and android (Pixel 5 emulation) failed on every retry while desktop safari and firefox passed, consistent with per-job prefetch/cache state rather than engine differences.
  • 16.3.1's client segment-cache changes relative to 16.3.0 (metadata-only request tree guard, per-navigation cache map) do not fix it.
  • Closest existing report appears to be #95347 (metadata boundary resume mismatch), but the signature differs.

Happy to provide Playwright traces (DOM snapshots and network logs) from the failing CI runs.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Deploy the linked next-soft-nav-metadata-repro app to Vercel and reproduce the issue during the cold prefetch window. Compare soft navigation with a hard load and with Next.js 16.2.12, inspecting the document head and prefetch responses. Done means the destination route replaces the previous metadata with one correct set, matching hard-load behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nextjs, react
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.