feat(nextjs): add cache-safe optimization handoff support#379
Draft
Charles Hudson (phobetron) wants to merge 1 commit into
Draft
feat(nextjs): add cache-safe optimization handoff support#379Charles Hudson (phobetron) wants to merge 1 commit into
Charles Hudson (phobetron) wants to merge 1 commit into
Conversation
Charles Hudson (phobetron)
force-pushed
the
NT-3708_implement-ssg-isr-esr-handoff-support
branch
2 times, most recently
from
July 16, 2026 16:59
e07aef3 to
5850191
Compare
Add explicit optimization handoff primitives for rendering personalized Contentful Optimization experiences through static, ISR, request-time, and edge-owned routes without relying on implicit browser-only state. Core SDK: - Add framework-neutral handoff types for selected optimization state, managed entry snapshots, and cache metadata. - Add deterministic selection fingerprints and cache-key helpers. - Add helpers for resolving baseline entries from customer-owned selections. - Add cache-safety warnings for public/static handoffs that accidentally carry private profile state or omit public permutation cache keys. Web SDK: - Add browser-facing content and analytics handoff types. - Add handoff hydration for preserving server-rendered content or hiding client-only content until browser state is ready. - Add an analytics-only runtime for routes that render optimized markup on the server/static/edge side but still need browser analytics and interaction tracking. React Web SDK: - Add handoff, analytics, and tracking-attributes subpath exports. - Teach OptimizationRoot to accept handoff state, hydration mode, route keys, and initial page event payload builders. - Add OptimizationAnalyticsRoot for analytics-only hydration. - Keep tracking attributes available independently from the full React runtime. Next.js SDK: - Add canonical handoff helpers for App Router and Pages Router integrations. - Add the edge entrypoint with createNextjsEdgeOptimization and createEdgeRequestHandoff. - Add cache middleware for customer-owned public permutation routing while preserving forwarded Next middleware request headers. - Update App Router and Pages Router server/client APIs to pass handoff state through the public root components. - Replace the previous /esr export with /edge. Node SDK: - Add createRequestHandoffFromData for framework-neutral request handoff creation from completed Node request optimization data. Reference implementations and tests: - Expand the Next.js App Router implementation with request handoff, customer-owned selection handoff, analytics-only, hidden-until-ready, edge request, edge selection, and cache middleware routes. - Refresh the Next.js Pages Router implementation for the new handoff contract. - Add unit coverage for core, web, React Web, Next.js, and Node handoff behavior. - Add E2E coverage for the new Next.js handoff routes. Documentation: - Add handoff and cache-safe rendering concept documentation. - Add a dedicated guide for rendering personalized Next.js routes with static, ISR, and edge handoffs. - Refresh Next.js App Router and Pages Router guides to focus the quick-starts and route advanced rendering modes to the new guide. - Update SDK knowledge files, guide indexes, package READMEs, and authoring guidance to reflect the new public APIs. Bundle policy: - Add budgets for new public entrypoints. - Remove budgets for removed entrypoints. - Reset affected budgets to match the current handoff-capable bundle outputs. BREAKING CHANGE: @contentful/optimization-nextjs/esr is removed. Use @contentful/optimization-nextjs/edge and the new edge handoff APIs instead. [[NT-3708](https://contentful.atlassian.net/browse/NT-3708)]
Charles Hudson (phobetron)
force-pushed
the
NT-3708_implement-ssg-isr-esr-handoff-support
branch
from
July 16, 2026 19:36
5850191 to
51ae699
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements explicit, cache-safe Optimization SDK handoff support for Next.js static, ISR, request-time, and edge rendering flows.
This PR adds framework-neutral handoff primitives in Core, browser handoff hydration in Web, React handoff roots, canonical Next.js handoff APIs, an edge-safe Next.js runtime, a Node request handoff helper, updated reference implementations, E2E coverage, and public/internal documentation for the supported rendering modes.
Jira: NT-3708
Why
Optimized content rendering needs to support more than browser-owned runtime state. This PR makes the state handoff explicit for:
The implementation separates:
Review map
Suggested review order:
Core model:
packages/universal/core-sdk/src/handoff.tspackages/universal/core-sdk/src/handoff.test.tsBrowser hydration/runtime behavior:
packages/web/web-sdk/src/handoff.tspackages/web/web-sdk/src/analytics.tspackages/web/web-sdk/src/handoff-state.tspackages/web/web-sdk/src/*handoff*.test.tspackages/web/web-sdk/src/analytics.test.tsReact Web integration:
packages/web/frameworks/react-web-sdk/src/root/OptimizationRoot.tsxpackages/web/frameworks/react-web-sdk/src/root/OptimizationAnalyticsRoot.tsxpackages/web/frameworks/react-web-sdk/src/provider/OptimizationProvider.tsxpackages/web/frameworks/react-web-sdk/src/**Next.js public APIs and edge behavior:
packages/web/frameworks/nextjs-sdk/src/handoff.tspackages/web/frameworks/nextjs-sdk/src/edge.tspackages/web/frameworks/nextjs-sdk/src/cache-middleware.tspackages/web/frameworks/nextjs-sdk/src/forwarded-request-headers.tspackages/web/frameworks/nextjs-sdk/src/app-router-server.tsxReference implementations and E2E evidence:
implementations/nextjs-sdk_app-router/**implementations/nextjs-sdk_pages-router/**implementations/web-sdk_angular/src/app/services/optimization.tslib/e2e-web/e2e/handoff.spec.tsDocumentation:
documentation/concepts/optimization-handoff-and-cache-safe-rendering.mddocumentation/guides/rendering-personalized-nextjs-routes-with-static-isr-and-edge-handoffs.mddocumentation/internal/sdk-knowledge/**Public API changes
Core SDK
Adds
@contentful/optimization-corehandoff support:OptimizationSelectionStateOptimizationCacheScopeOptimizationCacheMetadataOptimizationHandoffOptimizationCacheSafetyWarningcreateSelectionFingerprintcreateOptimizationCacheKeyresolveEntriesForSelectionscreateHandoffFromSelectionsgetOptimizationCacheSafetyWarningsThese APIs let SDKs and customer integrations describe the optimization state used during server/static/edge rendering and attach cache-safety metadata to the rendered output.
Web SDK
Adds browser handoff and analytics-only runtime support:
ContentOptimizationHydrationModeOptimizationHydrationModeContentOptimizationHandoffAnalyticsOptimizationHandoffBrowserOptimizationHandoffhydrateOptimizationHandoffcreateOptimizationAnalyticsRuntimehydrateOptimizationAnalyticsHandoffNew subpath exports:
@contentful/optimization-web/handoff@contentful/optimization-web/analyticsReact Web SDK
Adds handoff-aware root support:
OptimizationRootaccepts handoff state, hydration behavior, route identity, and initial page event payload builders.OptimizationAnalyticsRootsupports analytics-only hydration.initialPagePayloadfor server-framework bridges that cannot pass functions into client components.New subpath exports:
@contentful/optimization-react-web/handoff@contentful/optimization-react-web/analytics@contentful/optimization-react-web/tracking-attributesNext.js SDK
Adds canonical Next.js handoff helpers:
createHandoffFromSelectionsaddBrowserHandoffMetadatacreateNextjsEdgeOptimizationcreateEdgeRequestHandoffcreateNextjsCacheMiddlewareAdds App Router server support for request-local handoff state so server
OptimizedEntrycan resolve entries from the active request or selection handoff. Analytics-only handoffs intentionally do not drive server content resolution.The App Router bound root keeps
buildPagePayloadas the developer-facing API and converts it to serializableinitialPagePayloadbefore crossing the Server Component to Client Component boundary.Adds the new package subpath:
@contentful/optimization-nextjs/edgeRemoves the previous package subpath:
@contentful/optimization-nextjs/esrNode SDK
Adds:
createRequestHandoffFromDataThis lets Node/server integrations create framework-neutral handoff payloads from completed request optimization data.
Rendering strategies covered
Private request handoff
For request-bound rendering where profile state may be private to the visitor.
private-requestPublic permutation handoff
For customer-owned cacheable variants such as ISR routes keyed by segment, audience, campaign, or other non-private dimensions.
public-permutationStatic handoff
For build-time or otherwise static optimized routes where selections are known without per-visitor private state.
staticAnalytics-only handoff
For routes where optimized markup is already rendered and the browser only needs analytics, profile continuity, and interaction tracking.
analytics-onlyOptimizationAnalyticsRootor the Web SDK analytics runtimeEdge request handoff
For edge routes that resolve optimization state, emit or skip initial page events, persist anonymous IDs, and hand state to the browser.
@contentful/optimization-nextjs/edgeentrypointpersist(response)helper for cookie persistenceBreaking and migration notes
/esrwas replaced by/edge@contentful/optimization-nextjs/esrhas been removed.Use:
The new edge API is the supported path for edge-owned request handoff behavior.
Handoff is explicit
Next.js integrations should pass explicit handoff payloads into the React/Web hydration layer instead of relying on implicit browser-only state for server/static/edge-rendered personalized content.
Cache ownership is explicit
Public or static rendered output must not carry private profile state. Public permutation routes should provide a customer-owned cache key. The Core SDK exposes warning helpers to make these cases visible.
App Router server content resolution is handoff-aware
App Router server
OptimizedEntryresolves from the active request or selection handoff. This keeps the consumer API centered on the bound SDK components instead of requiring route code to manually thread selected optimizations through every server-rendered entry.Reference implementation updates
The App Router reference implementation demonstrates:
OptimizedEntryrendering through the bound App Router SDK componentsThe Pages Router reference implementation aligns with the handoff contract and shared utility behavior.
The Angular Web SDK reference implementation hydrates server-provided snapshot state through
hydrateOptimizationHandoff, keeping it aligned with the Web SDK handoff API instead of using lower-level snapshot hydration directly.E2E and test coverage
Adds or updates coverage for:
OptimizationRoothandoff behaviorOptimizationAnalyticsRootOptimizedEntryresolution from request and selection handoff statePrimary new E2E file:
lib/e2e-web/e2e/handoff.spec.tsDocumentation updates
Adds:
documentation/concepts/optimization-handoff-and-cache-safe-rendering.mddocumentation/guides/rendering-personalized-nextjs-routes-with-static-isr-and-edge-handoffs.mdUpdates:
Bundle-size policy
This PR adds bundle budgets for new public entrypoints and removes budgets for removed entrypoints.
Notable changes include:
handoffandanalyticsentrypoint budgetshandoff,analytics, andtracking-attributesentrypoint budgetsesr.*toedge.*Bundle budget overruns were treated as validation evidence during implementation. The budget changes reflect the current public entrypoint shape; future budget tightening should be handled as separate optimization work.
Validation
Validation evidence for this branch includes:
114 passed,12 skippedpnpm --filter @contentful/optimization-nextjs typecheckpnpm --filter @contentful/optimization-nextjs test:unitpnpm --filter @contentful/optimization-nextjs buildpnpm --filter @contentful/optimization-nextjs size:checkpnpm --filter @contentful/optimization-react-web typecheckgit diff --checkAdditional branch validation performed during the implementation included package, implementation, documentation, and knowledge-base checks documented in the branch work.
Reviewer checklist
Please pay particular attention to:
initialPageEvent: "emit" | "skip"is assigned consistently across server, edge, and browser ownership/edgeAPI shape is the right replacement for the removed/esrsubpathinitialPagePayloadbridge is clearly an adapter/runtime serialization mechanism whilebuildPagePayloadremains the normal consumer-facing APIRisk areas
/esrsubpath removal is a breaking package export change.buildPagePayloadon the server and passesinitialPagePayloadto React Web.