Skip to content

refactor(app-browser-entry): dedupe encoded JSON header parsing#1070

Merged
james-elicx merged 1 commit intomainfrom
refactor/dedupe-encoded-json-header
May 5, 2026
Merged

refactor(app-browser-entry): dedupe encoded JSON header parsing#1070
james-elicx merged 1 commit intomainfrom
refactor/dedupe-encoded-json-header

Conversation

@james-elicx
Copy link
Copy Markdown
Collaborator

Summary

  • Extract the repeated try { JSON.parse(decodeURIComponent(headerValue)) } catch { ... } pattern used to hydrate params from the X-Vinext-Params header into a single local helper, parseEncodedJsonHeader<T>(value: string | null): T | null.
  • Both call sites in packages/vinext/src/server/app-browser-entry.ts (the initial RSC hydration path and the in-flight navigation path) now share the helper.
  • Pure refactor — no behavior change.

Follow-up to #1049.

Files changed

  • packages/vinext/src/server/app-browser-entry.ts — adds the helper at the top of the file and updates the two call sites.

Notes on behavior preservation

The two original blocks had a subtle difference:

  • The first call site (initial RSC response) parsed the header and called applyClientParams(params) inside the same try, so the catch silently swallowed any error from applyClientParams as well.
  • The second call site only parsed.

The helper itself only handles parsing. To preserve the original error-swallowing semantics at the first call site, applyClientParams is wrapped in a small dedicated try/catch there. The helper does not log or surface errors — silent by design, matching the pre-existing behavior.

A quick grep -rn "JSON.parse(decodeURIComponent" packages/vinext/src/ confirmed the pattern only appears in this file, so a module-private helper (rather than a shared utility) is sufficient.

Test plan

  • pnpm vp test run tests/app-router.test.ts — 308 tests pass
  • pnpm fmt --write on the touched file
  • Manual diff review to confirm structural-only change

🤖 Generated with Claude Code

Extract the repeated try/catch JSON.parse(decodeURIComponent(...))
block into a single helper. Follow-up to #1049.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 5, 2026

Open in StackBlitz

npm i https://pkg.pr.new/vinext@1070

commit: 7e0b27c

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original

@james-elicx
Copy link
Copy Markdown
Collaborator Author

/bigbonk review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean refactor. The helper is well-scoped, the two call sites read better, and the behavioral nuance (separating applyClientParams from the parse try/catch at the first call site) is handled correctly.

Two minor observations, neither blocking:

  1. !value guard treats "" as missingparseEncodedJsonHeader("") returns null because the empty string is falsy. That's fine here since headers.get() returns null for absent headers and an empty X-Vinext-Params value would fail JSON.parse anyway, so the short-circuit is just saving a wasted decode+parse. Worth noting in case the helper is ever promoted to a shared utility where an empty string might carry different semantics.

  2. The generic as T cast is unchecked at runtime — the caller trusts that the JSON payload matches Record<string, string | string[]>. That's inherited from the original code and not a regression, just a note that if this helper ever gets reused for other header shapes, a runtime schema check (or at least a comment about the trust boundary) would be warranted.

LGTM — all CI green, behavior preserved, code is cleaner.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented May 5, 2026

Review posted and PR approved. The refactor is straightforward and correct:

  • The parseEncodedJsonHeader<T> helper cleanly deduplicates the repeated try { JSON.parse(decodeURIComponent(...)) } catch pattern from both call sites.
  • The subtle behavioral difference (first call site previously swallowed applyClientParams errors inside the same try/catch) is properly preserved with a dedicated try/catch wrapper.
  • All 30 CI checks pass. No behavior change, just cleaner code.

github run

@james-elicx james-elicx marked this pull request as ready for review May 5, 2026 18:22
@james-elicx james-elicx merged commit 9997ee7 into main May 5, 2026
33 checks passed
@james-elicx james-elicx deleted the refactor/dedupe-encoded-json-header branch May 5, 2026 18:22
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