[GH-ISSUE #3207] Bear plugin enable in nextjs mode read jwt failed #9517

Closed
opened 2026-04-13 05:00:37 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @wxl306 on GitHub (Jun 28, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3207

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Following the better-with docs ,enable bear plugin in auth and authclient, however read jwt from local storage always null.

Current vs. Expected behavior

Supposed to read jwt from local storage

What version of Better Auth are you using?

1.2.9

Provide environment information

Chrome

Plus:how shall I validate jwt in nextjs middleware considering import auth reading got error(relied library not shop on edge mode)

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

Other

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { bearer } from "better-auth/plugins";
 
export const auth = betterAuth({
    plugins: [bearer()]
});

Additional context

No response

Originally created by @wxl306 on GitHub (Jun 28, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3207 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Following the better-with docs ,enable bear plugin in auth and authclient, however read jwt from local storage always null. ### Current vs. Expected behavior Supposed to read jwt from local storage ### What version of Better Auth are you using? 1.2.9 ### Provide environment information ```bash Chrome Plus:how shall I validate jwt in nextjs middleware considering import auth reading got error(relied library not shop on edge mode) ``` ### Which area(s) are affected? (Select all that apply) Other ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { bearer } from "better-auth/plugins"; export const auth = betterAuth({ plugins: [bearer()] }); ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-13 05:00:37 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jun 28, 2025):

Hi @wxl306! I'm Dosu and I’m helping the better-auth team.

The Bearer plugin doesn't read JWTs directly from localStorage. Instead, it expects the JWT (bearer token) to be sent in the Authorization header of your API requests. In Next.js, localStorage is only available on the client side, so if you're trying to access it in middleware or server code, it will always be null docs.

The correct flow is: after sign-in, get the session token from the response header (usually set-auth-token), store it in localStorage on the client, and configure your auth client to send it in the Authorization header for all API requests. Example:

// After sign-in
const authToken = response.headers.get("set-auth-token");
localStorage.setItem("bearer_token", authToken);

// Configure auth client
export const authClient = createAuthClient({
  fetchOptions: {
    auth: {
      type: "Bearer",
      token: () => localStorage.getItem("bearer_token") || ""
    }
  }
});

docs

For Next.js middleware: you can't access localStorage or use most Node.js APIs in edge runtime. To validate JWTs in middleware (Next.js ≤15.1.7), fetch the session from an API route (like /get-session) using HTTP. If you're on Next.js 15.2.0+ and using the Node.js runtime in middleware, you can use the auth API directly, but this is experimental and may change reference.

If your JWT is always null in localStorage, double-check that you're storing it after sign-in and only trying to read it on the client side. For secure handling, always transmit tokens via headers or HTTP-only cookies, not by trying to access localStorage from server or middleware code.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

<!-- gh-comment-id:3015209305 --> @dosubot[bot] commented on GitHub (Jun 28, 2025): <!-- Greeting --> Hi @wxl306! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> The Bearer plugin doesn't read JWTs directly from localStorage. Instead, it expects the JWT (bearer token) to be sent in the Authorization header of your API requests. In Next.js, localStorage is only available on the client side, so if you're trying to access it in middleware or server code, it will always be null [docs](https://github.com/better-auth/better-auth/blob/e7eed8c848740fc22dc12e1b82cad8a42155249e/docs/content/docs/plugins/bearer.mdx). The correct flow is: after sign-in, get the session token from the response header (usually set-auth-token), store it in localStorage on the client, and configure your auth client to send it in the Authorization header for all API requests. Example: ```ts // After sign-in const authToken = response.headers.get("set-auth-token"); localStorage.setItem("bearer_token", authToken); // Configure auth client export const authClient = createAuthClient({ fetchOptions: { auth: { type: "Bearer", token: () => localStorage.getItem("bearer_token") || "" } } }); ``` [docs](https://github.com/better-auth/better-auth/blob/e7eed8c848740fc22dc12e1b82cad8a42155249e/docs/content/docs/plugins/bearer.mdx) For Next.js middleware: you can't access localStorage or use most Node.js APIs in edge runtime. To validate JWTs in middleware (Next.js ≤15.1.7), fetch the session from an API route (like `/get-session`) using HTTP. If you're on Next.js 15.2.0+ and using the Node.js runtime in middleware, you can use the auth API directly, but this is experimental and may change [reference](https://better-auth.com/docs/integrations/next). If your JWT is always null in localStorage, double-check that you're storing it after sign-in and only trying to read it on the client side. For secure handling, always transmit tokens via headers or HTTP-only cookies, not by trying to access localStorage from server or middleware code. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/70ea2597-8b50-4cf5-a89b-772c2303ae93?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3207)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9517