Skip to content

feat(js): Next.js Pages Router support#393

Merged
nicklasl merged 6 commits into
mainfrom
pages-router-support
May 5, 2026
Merged

feat(js): Next.js Pages Router support#393
nicklasl merged 6 commits into
mainfrom
pages-router-support

Conversation

@andreas-karlsson
Copy link
Copy Markdown
Contributor

Summary

Adds three subexports under ./pages-router/* for the Next.js Pages Router, parallel to the existing react-server/react-client pair for App Router:

  • pages-router/serverwithConfidence(config, gssp?) HOC that resolves the flag bundle in getServerSideProps (no exposure) and merges it into pageProps. Plus a low-level resolveConfidence helper.
  • pages-router/client<ConfidencePagesProvider> for _app.tsx. The existing useFlag / useFlagDetails from react-client work unchanged.
  • pages-router/apiapplyHandler({ providerName? }?) factory for the /api/confidence/apply POST route the client uses to log exposure.

The resolve token is sealed with AES-256-GCM (key from CONFIDENCE_TOKEN_KEY env var) before reaching the client, since Pages Router has no encrypted-closure equivalent to App Router server actions. The apply route opens it server-side.

README-REACT.md gets a new "Next.js Pages Router" section. The App Router quick-start was also moved to instrumentation.ts since that's router-agnostic and avoids the build-time side-effect issue with top-level-await setup files.

Test plan

  • yarn typecheck clean
  • yarn test — 7 token tests + 6 apply-handler tests pass
  • yarn build emits dist/pages-router/{server,client,api}.{js,d.ts}
  • Existing react-server / react-client builds unchanged
  • Verified end-to-end against a Pages Router demo app (server-side resolve → client hook reads → apply route fires exposure)

🤖 Generated with Claude Code

Comment thread openfeature-provider/js/src/pages-router/server.ts Outdated
Comment thread openfeature-provider/js/src/pages-router/server.ts
Comment thread openfeature-provider/js/src/pages-router/constants.ts Outdated
Comment thread openfeature-provider/js/src/pages-router/client.tsx Outdated
Comment thread openfeature-provider/js/src/pages-router/api.ts
@nicklasl nicklasl changed the title feat: Next.js Pages Router support feat(js): Next.js Pages Router support May 5, 2026
Copy link
Copy Markdown
Member

@nicklasl nicklasl left a comment

Choose a reason for hiding this comment

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

Jedi Council ignites green saber 🟢

LGTM — both blocking concerns addressed (errorCode gate in applyHandler + dev-warn on apply failures), and the withConfidence(gssp, opts?) refactor is genuinely nicer than what I first reviewed. Approving.


One follow-up — the Build & Test failure is the bundle-split sentinel in Dockerfile:340. It uses find ... ! -name <basename>, which matches basename only, so:

  • dist/pages-router/server.js and dist/pages-router/client.js slip through by sheer naming coincidence (the existing ! -name 'server.js' ! -name 'client.js' entries match them too)
  • dist/pages-router/api.js has no api.js twin elsewhere → caught as "unexpected"

Quick fix is to add ! -name 'api.js', but that just papers over the lie. Suggest switching to ! -path so the allowlist is explicit and the check actually tells the truth:

RUN set -e; \
    echo "Verifying no bundle splitting in JS artifacts..."; \
    UNEXPECTED_FILES=$(find dist -name '*.js' \
      ! -path 'dist/index.node.js' \
      ! -path 'dist/index.inlined.js' \
      ! -path 'dist/index.fetch.js' \
      ! -path 'dist/server.js' \
      ! -path 'dist/client.js' \
      ! -path 'dist/pages-router/server.js' \
      ! -path 'dist/pages-router/client.js' \
      ! -path 'dist/pages-router/api.js' | head -10); \
    if [ -n "\$UNEXPECTED_FILES" ]; then \
      echo ""; \
      echo "❌ ERROR: Bundle splitting detected!"; \
      echo ""; \
      echo "Found unexpected JavaScript files in dist/:"; \
      echo "\$UNEXPECTED_FILES"; \
      echo ""; \
      echo "Only expected entry point files should be present."; \
      echo "Check tsdown.config.ts configuration to prevent code splitting."; \
      echo ""; \
      exit 1; \
    fi; \
    echo "✅ No bundle splitting detected - only expected files present"

Catches actual chunk-splits (which the check was meant to find) instead of relying on basename collisions to hide them. 🛠️

@nicklasl nicklasl merged commit 8efd0ae into main May 5, 2026
10 checks passed
@github-actions github-actions Bot mentioned this pull request May 5, 2026
@nicklasl nicklasl deleted the pages-router-support branch May 5, 2026 14:30
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.

2 participants