[GH-ISSUE #920] NextJS Pages Router API Route Doesn't work with Node Handler #8500

Closed
opened 2026-04-13 03:35:15 -05:00 by GiteaMirror · 8 comments
Owner

Originally created by @daveycodez on GitHub (Dec 17, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/920

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Error: ⨯ TypeError: Response body object should not be disturbed or locked

/pages/api/auth/[...all]

import { NextApiRequest, NextApiResponse } from "next"
import { toNodeHandler } from "better-auth/node"
import { auth } from "@/lib/auth"

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    await toNodeHandler(auth)(req, res)
}

When I convert it to an "edge" endpoint, I can get the NextRequest object and use the toNextJSHandler, but the Edge config doesn't support Crypto for JWT's and is broken there as stated from a previous issue.

For some of us.. the App Router is not great. Please consider adding documentation for Pages Router installation and Edge support

Current vs. Expected behavior

Support for NextJS Pages Router

What version of Better Auth are you using?

1.0.21

Provide environment information

NextJS 15 Pages Router API Route

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
import { jwt, bearer } from "better-auth/plugins"
import { NeonHTTPDialect } from "kysely-neon"

import { getURL } from "@/lib/utils"

export const auth = betterAuth({
    baseURL: getURL(),
    database: {
        dialect: new NeonHTTPDialect({
            connectionString: process.env.DATABASE_URL!,
        }),
        type: "postgres"
    },
    emailAndPassword: { enabled: true },
    plugins: [
        jwt(),
        bearer()
    ]
})

Additional context

No response

Originally created by @daveycodez on GitHub (Dec 17, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/920 ### Is this suited for github? - [X] Yes, this is suited for github ### To Reproduce Error: ⨯ TypeError: Response body object should not be disturbed or locked /pages/api/auth/[...all] ```ts import { NextApiRequest, NextApiResponse } from "next" import { toNodeHandler } from "better-auth/node" import { auth } from "@/lib/auth" export default async function handler(req: NextApiRequest, res: NextApiResponse) { await toNodeHandler(auth)(req, res) } ``` When I convert it to an "edge" endpoint, I can get the NextRequest object and use the toNextJSHandler, but the Edge config doesn't support Crypto for JWT's and is broken there as stated from a previous issue. For some of us.. the App Router is not great. Please consider adding documentation for Pages Router installation and Edge support ### Current vs. Expected behavior Support for NextJS Pages Router ### What version of Better Auth are you using? 1.0.21 ### Provide environment information ```bash NextJS 15 Pages Router API Route ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" import { jwt, bearer } from "better-auth/plugins" import { NeonHTTPDialect } from "kysely-neon" import { getURL } from "@/lib/utils" export const auth = betterAuth({ baseURL: getURL(), database: { dialect: new NeonHTTPDialect({ connectionString: process.env.DATABASE_URL!, }), type: "postgres" }, emailAndPassword: { enabled: true }, plugins: [ jwt(), bearer() ] }) ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-13 03:35:15 -05:00
Author
Owner

@KastanDay commented on GitHub (Dec 20, 2024):

Hey @daveycodez Can you confirm that BetterAuth works for you in /pages router in the Node runtime and it only breaks when you convert it to Edge runtime? Are you able to authenticate pages running in /pages router?

<!-- gh-comment-id:2557870222 --> @KastanDay commented on GitHub (Dec 20, 2024): Hey @daveycodez Can you confirm that BetterAuth works for you in /pages router in the Node runtime and it only breaks when you convert it to Edge runtime? Are you able to authenticate pages running in /pages router?
Author
Owner

@daveycodez commented on GitHub (Dec 20, 2024):

@KastanDay

It's the opposite actually. If I use edge runtime in the Pages API Route, everything works EXCEPT /api/auth/token which gives crypto errors, likely due to edge limitations which I hope we can resolve.

But for straight up Pages API Routes it's not working

import { NextApiRequest, NextApiResponse } from "next"
import { toNodeHandler } from "better-auth/node"
import { auth } from "@/lib/auth"

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    await toNodeHandler(auth)(req, res)
}

Gives errors about locking the response body.

<!-- gh-comment-id:2557880834 --> @daveycodez commented on GitHub (Dec 20, 2024): @KastanDay It's the opposite actually. If I use edge runtime in the Pages API Route, everything works EXCEPT /api/auth/token which gives crypto errors, likely due to edge limitations which I hope we can resolve. But for straight up Pages API Routes it's not working ```ts import { NextApiRequest, NextApiResponse } from "next" import { toNodeHandler } from "better-auth/node" import { auth } from "@/lib/auth" export default async function handler(req: NextApiRequest, res: NextApiResponse) { await toNodeHandler(auth)(req, res) } ``` Gives errors about locking the response body.
Author
Owner

@KastanDay commented on GitHub (Dec 20, 2024):

Very interesting, thank you for the details.

I'm unable to get /pages router working at all. /app router works fine, but if I try to move any part of it into my existing /pages code base, I'm plagued by ERR_REQUIRE_ESM errors due to require() instead of import {}.

Sad to see you also can't get any form of pages router working even though @Bekacru mentioned pages "should" be supported: https://github.com/better-auth/better-auth/issues/850

I'd love any advice possible to get /pages working - we have a legacy codebase.

<!-- gh-comment-id:2557882380 --> @KastanDay commented on GitHub (Dec 20, 2024): Very interesting, thank you for the details. I'm unable to get /pages router working at all. /app router works fine, but if I try to move any part of it into my existing /pages code base, I'm plagued by `ERR_REQUIRE_ESM` errors due to `require()` instead of `import {}`. Sad to see you also can't get any form of pages router working even though @Bekacru mentioned pages "should" be supported: https://github.com/better-auth/better-auth/issues/850 I'd love any advice possible to get /pages working - we have a legacy codebase.
Author
Owner

@daveycodez commented on GitHub (Dec 20, 2024):

Heheh I'm one of the special ones who still think the Pages router is superior. But I work with hybrid static export projects and App Router is not very compatible with that. But yes Pages router is still real, proper support and documentation would be great

<!-- gh-comment-id:2557883722 --> @daveycodez commented on GitHub (Dec 20, 2024): Heheh I'm one of the special ones who still think the Pages router is superior. But I work with hybrid static export projects and App Router is not very compatible with that. But yes Pages router is still real, proper support and documentation would be great
Author
Owner

@Bekacru commented on GitHub (Dec 21, 2024):

export const config = {
	api: {
		bodyParser: false,
	},
};

hey @daveycodez and @KastanDay I think if you prevent the api route from pre-parsing the body it should work as expected.

<!-- gh-comment-id:2558039581 --> @Bekacru commented on GitHub (Dec 21, 2024): ```ts export const config = { api: { bodyParser: false, }, }; ``` hey @daveycodez and @KastanDay I think if you prevent the api route from pre-parsing the body it should work as expected.
Author
Owner

@daveycodez commented on GitHub (Dec 21, 2024):

@Bekacru

Yea bodyParser was the issue thanks! Although it would be great if we can get edge support working with JWT's sometime

<!-- gh-comment-id:2558046502 --> @daveycodez commented on GitHub (Dec 21, 2024): @Bekacru Yea bodyParser was the issue thanks! Although it would be great if we can get edge support working with JWT's sometime
Author
Owner

@KastanDay commented on GitHub (Dec 21, 2024):

I cannot thank you enough @Bekacru - that's phenomenal. I'm really impressed by this library and how you seem to be a CRACKED developer. Cheers!

<!-- gh-comment-id:2558211450 --> @KastanDay commented on GitHub (Dec 21, 2024): I cannot thank you enough @Bekacru - that's phenomenal. I'm really impressed by this library and how you seem to be a CRACKED developer. Cheers!
Author
Owner

@KastanDay commented on GitHub (Dec 21, 2024):

@Bekacru I spoke too soon - I'm still facing an ERR_REQUIRE_ESM error from nanostores.

I'm upgraded to better-auth@1.1.1.

Error: require() of ES Module /Users/kvday2/code/ai-ta/b/uiuc-chat-frontend/node_modules/nanostores/index.js from /Users/kvday2/code/ai-ta/b/uiuc-chat-frontend/node_modules/better-auth/dist/react.cjs not supported.
Instead change the require of index.js in /Users/kvday2/code/ai-ta/b/uiuc-chat-frontend/node_modules/better-auth/dist/react.cjs to a dynamic import() which is available in all CommonJS modules.

Here's our fairly minimal code.

I first thought it worked because un-commenting it works. But a page refresh causes the ESM error. Here's 20 second video showing the behavior:

CleanShot 2024-12-21 at 11 42 25

This behavior is identical if I use /app router (with toNextjsHandler) and import that into pages, or keep everything in /pages (with toNodeHandler).

Any advice greatly appreciated! Any luck @daveycodez ?

<!-- gh-comment-id:2558218833 --> @KastanDay commented on GitHub (Dec 21, 2024): @Bekacru I spoke too soon - I'm still facing an `ERR_REQUIRE_ESM` error from `nanostores`. I'm upgraded to `better-auth@1.1.1`. ``` Error: require() of ES Module /Users/kvday2/code/ai-ta/b/uiuc-chat-frontend/node_modules/nanostores/index.js from /Users/kvday2/code/ai-ta/b/uiuc-chat-frontend/node_modules/better-auth/dist/react.cjs not supported. Instead change the require of index.js in /Users/kvday2/code/ai-ta/b/uiuc-chat-frontend/node_modules/better-auth/dist/react.cjs to a dynamic import() which is available in all CommonJS modules. ``` Here's our [fairly minimal code](https://github.com/CAII-NCSA/uiuc-chat-frontend/pull/225). I first thought it worked because un-commenting it works. But a page refresh causes the `ESM` error. Here's 20 second video showing the behavior: ![CleanShot 2024-12-21 at 11 42 25](https://github.com/user-attachments/assets/d5e6d658-d0c0-4418-8ecb-1186b71cff02) This behavior is identical if I use /app router (with `toNextjsHandler`) and import that into pages, or keep everything in /pages (with `toNodeHandler`). Any advice greatly appreciated! Any luck @daveycodez ?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8500