Skip to content

🐞 fix(nextjs): Fix Next.js server page context/state handoff for query-parameters#339

Open
Charles Hudson (phobetron) wants to merge 1 commit into
mainfrom
NT-3568_fix-missing-query-bug
Open

🐞 fix(nextjs): Fix Next.js server page context/state handoff for query-parameters#339
Charles Hudson (phobetron) wants to merge 1 commit into
mainfrom
NT-3568_fix-missing-query-bug

Conversation

@phobetron

@phobetron Charles Hudson (phobetron) commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

This fixes server-side audience matching for rules that depend on URL query parameters. The supported Next.js server optimization path can now populate context.page from the current request URL, including query parameters, so a request such as /?test=true can evaluate query-based audience rules instead of silently rendering baseline content.

While investigating the bug, the issue turned out to span more than URL parsing. Next.js App Router splits request handling, Server Component rendering, and browser startup across different boundaries. The previous request-handler API mixed request context capture, page() execution, consent resolution, and cookie persistence in middleware/proxy code, which made it hard for Server Components to reliably receive page URL context without duplicating work. This PR separates those responsibilities and documents the supported integration paths.

What changed

  • Added shared page-context creation in Core so request URLs are normalized into SDK-compatible page.path, page.search, page.query, page.referrer, and page.url.
  • Updated the Next.js server helpers to derive page context from:
    • direct request objects,
    • sanitized proxy/middleware-forwarded request URL headers,
    • explicit App Router route state via createNextjsPageContext().
  • Replaced the page-producing Next.js request handler with createNextjsOptimizationContextHandler(), which only forwards sanitized request context for Server Components.
  • Added @contentful/optimization-nextjs/esr for edge/request-rendered flows that own both the incoming Request and outgoing Response, including anonymous ID persistence.
  • Added explicit server-to-browser Optimization state handoff through:
    • serverOptimizationState on React Web provider/root APIs,
    • NextjsOptimizationState for shared App Router layouts where page data is produced below the provider.
  • Introduced internal first-party bridge-support entry points for controlled state hydration and preview-panel access, replacing public symbol/register-preview wiring.
  • Added diagnostics for conflicting explicit page context versus page event properties.
  • Updated Next.js SSR and hybrid reference implementations to use the new request-context and state-handoff model.
  • Updated package READMEs, Next.js integration guides, and related concepts for consent, profile synchronization, locale handling, and server/stateless interaction tracking.

Why the scope expanded

A narrow fix that only parsed query strings would not have made the supported Next.js App Router flow reliable. Server Components do not naturally receive the full request URL, and the old middleware helper tried to solve that by performing SDK work at the request layer. That created unclear ownership over consent, page events, cookie persistence, and browser handoff.

This PR makes the boundaries explicit:

  • proxy/middleware captures request URL context only;
  • Server Components own getNextjsServerOptimizationData() and the initial server page() call;
  • ESR helpers own request/response-based rendering flows;
  • React/Next client code receives server-returned Optimization data through an explicit handoff API;
  • preview and state hydration use internal bridge support instead of consumer-visible Core internals.

Test coverage added or updated

  • Core stateless page-event tests cover forwarding request page query context.
  • EventBuilder tests cover context.page construction and explicit page-context precedence.
  • Core bridge tests cover first-party bridge access and Optimization data hydration.
  • Next.js server tests cover forwarded request URL headers, explicit page options, App Router searchParams, and duplicate query value normalization.
  • Next.js request-handler tests cover sanitized context forwarding and existing-response preservation.
  • Next.js ESR tests cover plain Request, NextRequest, cookie reads, cookie persistence, and persistence cleanup.
  • React Web provider tests cover server Optimization state being applied before onStatesReady and before children render.
  • Next.js client tests cover NextjsOptimizationState hydration behavior.

[NT-3568]

…y-parameters

### Summary

This fixes server-side audience matching for rules that depend on URL query parameters. The supported Next.js server optimization path can now populate `context.page` from the current request URL, including query parameters, so a request such as `/?test=true` can evaluate query-based audience rules instead of silently rendering baseline content.

While investigating the bug, the issue turned out to span more than URL parsing. Next.js App Router splits request handling, Server Component rendering, and browser startup across different boundaries. The previous request-handler API mixed request context capture, `page()` execution, consent resolution, and cookie persistence in middleware/proxy code, which made it hard for Server Components to reliably receive page URL context without duplicating work. This PR separates those responsibilities and documents the supported integration paths.

### What changed

- Added shared page-context creation in Core so request URLs are normalized into SDK-compatible `page.path`, `page.search`, `page.query`, `page.referrer`, and `page.url`.
- Updated the Next.js server helpers to derive page context from:
  - direct request objects,
  - sanitized proxy/middleware-forwarded request URL headers,
  - explicit App Router route state via `createNextjsPageContext()`.
- Replaced the page-producing Next.js request handler with `createNextjsOptimizationContextHandler()`, which only forwards sanitized request context for Server Components.
- Added `@contentful/optimization-nextjs/esr` for edge/request-rendered flows that own both the incoming `Request` and outgoing `Response`, including anonymous ID persistence.
- Added explicit server-to-browser Optimization state handoff through:
  - `serverOptimizationState` on React Web provider/root APIs,
  - `NextjsOptimizationState` for shared App Router layouts where page data is produced below the provider.
- Introduced internal first-party `bridge-support` entry points for controlled state hydration and preview-panel access, replacing public symbol/register-preview wiring.
- Added diagnostics for conflicting explicit page context versus page event properties.
- Updated Next.js SSR and hybrid reference implementations to use the new request-context and state-handoff model.
- Updated package READMEs, Next.js integration guides, and related concepts for consent, profile synchronization, locale handling, and server/stateless interaction tracking.

### Why the scope expanded

A narrow fix that only parsed query strings would not have made the supported Next.js App Router flow reliable. Server Components do not naturally receive the full request URL, and the old middleware helper tried to solve that by performing SDK work at the request layer. That created unclear ownership over consent, page events, cookie persistence, and browser handoff.

This PR makes the boundaries explicit:

- proxy/middleware captures request URL context only;
- Server Components own `getNextjsServerOptimizationData()` and the initial server `page()` call;
- ESR helpers own request/response-based rendering flows;
- React/Next client code receives server-returned Optimization data through an explicit handoff API;
- preview and state hydration use internal bridge support instead of consumer-visible Core internals.

### Test coverage added or updated

- Core stateless page-event tests cover forwarding request page query context.
- EventBuilder tests cover `context.page` construction and explicit page-context precedence.
- Core bridge tests cover first-party bridge access and Optimization data hydration.
- Next.js server tests cover forwarded request URL headers, explicit page options, App Router `searchParams`, and duplicate query value normalization.
- Next.js request-handler tests cover sanitized context forwarding and existing-response preservation.
- Next.js ESR tests cover plain `Request`, `NextRequest`, cookie reads, cookie persistence, and persistence cleanup.
- React Web provider tests cover server Optimization state being applied before `onStatesReady` and before children render.
- Next.js client tests cover `NextjsOptimizationState` hydration behavior.

[[NT-3568](https://contentful.atlassian.net/browse/NT-3568)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant