Skip to content

fix: deliver client-side templates to Pages Router clients#37

Merged
vklimontovich merged 4 commits into
mainfrom
fix/pages-router-templates
Jun 4, 2026
Merged

fix: deliver client-side templates to Pages Router clients#37
vklimontovich merged 4 commits into
mainfrom
fix/pages-router-templates

Conversation

@vklimontovich

Copy link
Copy Markdown
Collaborator

What

Client-side templates (used to compile script insertions) were only available to App Router clients. App Router's NextlyticsServer collects them from config and passes them via the ctx prop; Pages Router's getNextlyticsProps runs inside getInitialProps with no access to config, so its clients never received them.

This includes templates in every /api/event response and merges them on the client from whichever source supplies them (ctx prop for App Router, response for Pages Router), so script insertions compile on both routers and survive client-side navigations.

It also fixes getNextlyticsProps throwing on client-side navigations, where _app's getInitialProps re-runs without a req. It now returns an empty context in that case.

Changes

  • api-handler.ts — thread a collectTemplates callback through the handler; include templates in all /api/event responses.
  • client.tsx — hold templates in state, merging from the ctx prop and the /api/event response.
  • pages-router.ts — return an empty context when req is absent instead of throwing.
  • middleware.ts / server.tsx — wire up the collectTemplates callback.
  • types.ts — add optional templates to ClientRequestResult.

Testing

  • bun run typecheck passes.

🤖 Generated with Claude Code

vklimontovich and others added 4 commits June 3, 2026 18:07
Pages Router's getNextlyticsProps runs in getInitialProps without access
to config, so it can't collect client-side templates the way App Router's
NextlyticsServer does. Include templates in the /api/event response and
merge them on the client from whichever source supplies them, so script
insertions compile on both routers.

Also stop getNextlyticsProps from throwing on client-side navigations,
where _app's getInitialProps re-runs with no req.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The client now sends the template ids it already holds in a header, and
the server diffs against the templates resolved for the request, returning
only the new ones. App Router clients hold the full set from the ctx prop,
so they get an empty response; a Pages Router client receives each template
once instead of on every event. The diff is per-request, so it stays correct
when backend resolution (and thus the template set) varies by request.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
getNextlyticsProps now tolerates a missing req, so the _app example no
longer needs to guard ctx.req itself — call it directly, which doubles as
the documented usage.

Add an initial-load test (both routers) asserting the client-side script
templates compile and run. On Pages Router this only works once templates
arrive via /api/event, so it guards the fix; the prior script test was
App-Router-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vklimontovich vklimontovich merged commit b515be4 into main Jun 4, 2026
3 checks passed
@vklimontovich vklimontovich deleted the fix/pages-router-templates branch June 4, 2026 01:17
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