Skip to content

feat(nextjs): add Pages Router support via /pages module#169

Merged
halvaradop merged 2 commits into
masterfrom
feat/add-pages-handler
May 25, 2026
Merged

feat(nextjs): add Pages Router support via /pages module#169
halvaradop merged 2 commits into
masterfrom
feat/add-pages-handler

Conversation

@halvaradop
Copy link
Copy Markdown
Member

@halvaradop halvaradop commented May 24, 2026

Description

This pull request introduces a dedicated /pages entry module in @aura-stack/next to provide first-class support for the Next.js Pages Router.

With this addition, the package now supports both routing strategies:

  • App Router (recommended)
    • based on Web Standards APIs (Request, Response, Headers, etc.)
  • Pages Router
    • based on Node.js request/response objects (IncomingMessage, ServerResponse)

The new /pages entry module exposes utilities specifically designed for the Pages Router runtime and request lifecycle.


Architecture Decision

The decision to introduce a dedicated /pages entry module was primarily driven by two architectural differences between the App Router and Pages Router.

1. Different Request and Runtime Models

The App Router and Pages Router manage request data differently.

The App Router supports:

  • Server Components
  • Server Actions
  • built-in access to headers and cookies through next/headers

This makes it possible for the package to provide an api object with built-in request context handling and automatic session management.

In contrast, the Pages Router requires request data to be passed manually through APIs such as:

  • getServerSideProps
  • API route handlers

Because of this difference, the App Router and Pages Router cannot share the same internal request abstraction cleanly.

Packages such as:

  • @aura-stack/next
  • @aura-stack/react-router
  • @aura-stack/tanstack-start

expose both:

  • api
  • core

where:

  • api provides framework-aware utilities with built-in request handling
  • core exposes the low-level utilities from @aura-stack/auth

Without a dedicated Pages Router entry module, Pages Router users would need to rely on createAuth.core.api, while App Router users would use createAuth.api.

This creates unnecessary inconsistency and increases developer friction.

To solve this, a dedicated /pages module was introduced so Pages Router users can use a router-specific createAuth implementation with the same high-level API experience.


2. next/headers Is Not Supported in Pages Router

The built-in App Router implementation relies on the next/headers module to access:

  • cookies
  • headers
  • request metadata

However, next/headers is not supported in the Pages Router runtime.

Because of this limitation, the existing App Router implementation cannot be reused safely inside Pages Router environments.

Note

An alternative workaround was explored internally, but it introduced unnecessary complexity and did not align with the intended developer experience for the package.


Key Changes

  • Added /pages entry module for Pages Router support
  • Added dedicated createAuth implementation for Pages Router
  • Added toHandler helper for handling IncomingMessage and ServerResponse
  • Added Pages Router-specific request and response management

Usage

import { createAuth } from "@aura-stack/next/pages"

export const auth = createAuth({
  oauth: [],
})

export const { api, toHandler } = auth

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
auth Skipped Skipped May 25, 2026 12:14am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

Warning

Review limit reached

@halvaradop, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 35 minutes and 51 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 851ce8c6-4b54-4602-9d55-16fd35f48b9a

📥 Commits

Reviewing files that changed from the base of the PR and between 2f6c84f and 6c9e489.

📒 Files selected for processing (3)
  • apps/nextjs/pages-router/src/pages/client/index.tsx
  • packages/next/src/createAuth.ts
  • packages/next/src/pages/handler.ts
📝 Walkthrough

Walkthrough

This PR introduces full Next.js Pages Router support to @aura-stack/next by adding a createAuth factory and Web-to-NextJS request adapter, then migrates the Pages Router demo app from @aura-stack/react to use the new integrated package, simplifying server routes and modernizing client-side authentication imports.

Changes

Pages Router Support Implementation & Demo Migration

Layer / File(s) Summary
Pages Router Handler Adapter
packages/next/src/lib/utils.ts, packages/next/src/pages/handler.ts
Introduces isPagesRouter() utility to detect router type, and toHandler to adapt Web Fetch API handlers into Next.js Pages Router API routes, including URL derivation from forwarded headers, method routing, Request/Response translation, redirects, and error handling.
Pages Router Auth Factory & Type Updates
packages/next/src/createAuth.ts, packages/next/src/pages/createAuth.ts, packages/next/src/pages/index.ts
Creates a Pages Router-specific createAuth factory that wraps server auth with toHandler, updates App Router core createAuth type imports to include AuthInstance, and exports the new API via index.
Package Distribution & Export Wiring
packages/next/package.json, packages/next/deno.json, packages/next/tsdown.config.ts
Adds ./pages export entry and build configuration to distribute the new Pages Router support through @aura-stack/next/pages.
Demo App Server-Side Integration
apps/nextjs/pages-router/src/lib/auth.ts, apps/nextjs/pages-router/src/pages/api/auth/[...aura].ts, apps/nextjs/pages-router/src/pages/server/index.tsx
Migrates server auth imports from @aura-stack/react to @aura-stack/next, exports toHandler for use as API route handler, simplifies the auth route to re-export toHandler, adjusts getServerSideProps session typing, and updates marketing text.
Demo App Client-Side Integration
apps/nextjs/pages-router/package.json, apps/nextjs/pages-router/src/components/header.tsx, apps/nextjs/pages-router/src/contexts/auth.tsx, apps/nextjs/pages-router/src/lib/auth-client.ts, apps/nextjs/pages-router/src/pages/client/index.tsx
Adds @aura-stack/next dependency, migrates client hooks and providers from @aura-stack/react to @aura-stack/next/client, and improves form accessibility with aria-labels.
Documentation Updates
packages/next/CHANGELOG.md
Documents the introduction of createAuth for Pages Router with toHandler adapter availability via /pages entry.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • aura-stack-ts/auth#141: Implements the same Pages Router toHandler adapter and createAuth factory infrastructure that this PR integrates into the demo app.
  • aura-stack-ts/auth#145: Modifies Pages Router auth configuration in apps/nextjs/pages-router/src/lib/auth.ts; this PR updates the same file to migrate to the new @aura-stack/next API.
  • aura-stack-ts/auth#114: Centralizes client auth surface with createAuthClient; this PR consumes that work by migrating client hooks from @aura-stack/react to @aura-stack/next/client.

Suggested Labels

feature, enhancement

Poem

🐰 Pages Router, now you have your wings to fly,
A toHandler bridge that lifts requests to the sky,
From Fetch to Next, the request flows so clean,
The demo app migrates to the package in between,
Authentication's dance finds its new home! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the main change: adding Pages Router support via a new /pages module export for the @aura-stack/next package.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-pages-handler

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/nextjs/pages-router/src/pages/client/index.tsx (1)

49-50: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update stale package name in the client demo description.

This text still references @aura-stack/react even though this page now uses @aura-stack/next/client.

✏️ Suggested change
-                        Official Next.js demo to showcase `@aura-stack/react` authentication library with Client Side Rendering
+                        Official Next.js demo to showcase `@aura-stack/next` authentication library with Client Side Rendering
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/nextjs/pages-router/src/pages/client/index.tsx` around lines 49 - 50,
Update the demo description string that currently mentions "`@aura-stack/react`"
to the correct package name "`@aura-stack/next/client`" so the client demo text in
pages/client/index.tsx (the line containing the literal "Official Next.js demo
to showcase `@aura-stack/react` authentication library with Client Side Rendering
(CSR), for Server-Side Rendering (SSR) visit") reflects the current package;
simply replace the package name in that string to "`@aura-stack/next/client`".
🧹 Nitpick comments (1)
apps/nextjs/pages-router/src/pages/server/index.tsx (1)

14-16: ⚡ Quick win

Use @ts-expect-error instead of @ts-ignore for this temporary typing workaround.

@ts-ignore can hide unrelated type errors on the same line; @ts-expect-error preserves the workaround but fails once the underlying issue is fixed.

🔧 Suggested change
-            // `@todo`: Fix excessively deep type instantiation error in session typing
-            // `@ts-ignore` Type instantiation is excessively deep and possibly infinite.
+            // `@todo`: Fix excessively deep type instantiation error in session typing
+            // `@ts-expect-error` Type instantiation is excessively deep and possibly infinite.
             session: session.success ? session.session : null,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/nextjs/pages-router/src/pages/server/index.tsx` around lines 14 - 16,
Replace the temporary TypeScript suppression on the session line by swapping the
existing "`@ts-ignore`" for "`@ts-expect-error`" so the line with "session:
session.success ? session.session : null" still bypasses the deep-instantiation
error but will surface if the root typing gets fixed; keep the todo comment
above for follow-up.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/next/src/lib/utils.ts`:
- Around line 1-7: isPagesRouter currently starts an async IIFE that imports
"next/headers" but does not await or return it, so the function returns true
before the import can reject; change isPagesRouter to await (or return) the
import Promise so the try/catch can catch failures. Specifically, update the
function isPagesRouter to perform await import("next/headers") (or return the
import Promise) inside the try block instead of launching an unawaited async
IIFE so rejected imports are handled and the function reliably returns
true/false.

In `@packages/next/src/pages/handler.ts`:
- Around line 34-35: Normalize req.headers before constructing Headers and
ensure no body is sent for HEAD requests: replace the inline new
Headers(req.headers as Record<string,string>) with a normalized headers object
that iterates req.headers (which may have string | string[] | undefined), skips
undefined values, and joins string[] values with commas so every value is a
string; and change the body expression from method !== "GET" && req.body ?
JSON.stringify(req.body) : undefined to exclude HEAD as well (e.g., method !==
"GET" && method !== "HEAD" && req.body ? JSON.stringify(req.body) : undefined)
so no body is included for HEAD requests. Reference: the new Headers(...)
construction and the body assignment using method and req.body.
- Around line 42-48: Replace the non-existent res.setHeaders(...) usage by
iterating response.headers and calling res.setHeader(name, value) for each
header (use the existing res variable), and stop assuming JSON-only bodies:
after copying headers, first handle no-body statuses (e.g., response.status ===
204 || response.status === 304) by returning res.status(response.status).end();
otherwise inspect response.headers.get('content-type') — if it startsWith
'application/json' await response.json() and return
res.status(response.status).json(data); else read the body as an
ArrayBuffer/Buffer and return res.status(response.status).send(buffer) while
preserving the content-type header so non-JSON bodies are forwarded correctly.
Ensure this replaces the current unconditional await response.json() call in the
handler.

---

Outside diff comments:
In `@apps/nextjs/pages-router/src/pages/client/index.tsx`:
- Around line 49-50: Update the demo description string that currently mentions
"`@aura-stack/react`" to the correct package name "`@aura-stack/next/client`" so the
client demo text in pages/client/index.tsx (the line containing the literal
"Official Next.js demo to showcase `@aura-stack/react` authentication library with
Client Side Rendering (CSR), for Server-Side Rendering (SSR) visit") reflects
the current package; simply replace the package name in that string to
"`@aura-stack/next/client`".

---

Nitpick comments:
In `@apps/nextjs/pages-router/src/pages/server/index.tsx`:
- Around line 14-16: Replace the temporary TypeScript suppression on the session
line by swapping the existing "`@ts-ignore`" for "`@ts-expect-error`" so the line
with "session: session.success ? session.session : null" still bypasses the
deep-instantiation error but will surface if the root typing gets fixed; keep
the todo comment above for follow-up.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 81025067-2b73-4622-8d41-0bff315308ba

📥 Commits

Reviewing files that changed from the base of the PR and between a22c366 and 2f6c84f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • apps/nextjs/pages-router/package.json
  • apps/nextjs/pages-router/src/components/header.tsx
  • apps/nextjs/pages-router/src/contexts/auth.tsx
  • apps/nextjs/pages-router/src/lib/auth-client.ts
  • apps/nextjs/pages-router/src/lib/auth.ts
  • apps/nextjs/pages-router/src/pages/api/auth/[...aura].ts
  • apps/nextjs/pages-router/src/pages/client/index.tsx
  • apps/nextjs/pages-router/src/pages/server/index.tsx
  • packages/next/CHANGELOG.md
  • packages/next/deno.json
  • packages/next/package.json
  • packages/next/src/createAuth.ts
  • packages/next/src/lib/utils.ts
  • packages/next/src/pages/createAuth.ts
  • packages/next/src/pages/handler.ts
  • packages/next/src/pages/index.ts
  • packages/next/tsdown.config.ts

Comment thread packages/next/src/lib/utils.ts Outdated
Comment thread packages/next/src/pages/handler.ts Outdated
Comment thread packages/next/src/pages/handler.ts Outdated
@halvaradop halvaradop changed the title feat(nextjs): introduce dedicated /pages entry for Pages Router support feat(nextjs): add Pages Router support via /pages module May 25, 2026
@halvaradop halvaradop merged commit 11b45ce into master May 25, 2026
7 checks passed
@halvaradop halvaradop deleted the feat/add-pages-handler branch May 25, 2026 00:16
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