Skip to content

Conversation

@mandarini
Copy link
Contributor

@mandarini mandarini commented Nov 10, 2025

Problem

Next.js 16 enforces deterministic rendering for Server Components and blocks all non-deterministic operations during pre-rendering, including:

  • Math.random()
  • crypto.randomUUID()
  • crypto.getRandomValues()

This causes build errors when instantiating createBrowserClient():

  Error: Route "/" used Math.random() before accessing uncached data

Root cause: The uuid() function uses Math.random() to generate unique IDs for auth state change callback subscriptions. When GoTrueClient initializes, it calls onAuthStateChange() which generates these IDs during SSR, triggering Next.js 16's deterministic rendering check.

Solution

Replaced uuid() with generateCallbackId() that uses JavaScript Symbols instead of random number generation.

Why Symbols?

Symbols are a good solution for internal callback identifiers:

  • Guaranteed unique by the JavaScript runtime (no randomness needed)
  • Work everywhere -> browser, SSR, Node.js, Deno
  • Deterministic -> no conflicts with Next.js pre-rendering requirements
  • Semantically correct -> for internal, non-serializable identifiers
  • Simpler code

When we call supabase.auth.onAuthStateChange(callback), the library needs to track the callback among potentially many others. The id is an internal key used in a Map to identify which callback to invoke or remove. So no need for cryptographically secure id's.

Changes

  1. Renamed function: uuid()generateCallbackId()

    • Make it clear this is not for general uuid generation
    • Prevents future misuse for security-critical operations
  2. Implementation: Return Symbol('auth-callback') instead of uuid string

  3. Type updates: Subscription.id changed from string to string | symbol

  4. Documentation: Clarified that id is an internal identifier not meant for application use

Acknowledgements

Thanks to @7ttp and @BOXNYC for raising the issue and suggesting solutions!

@coveralls
Copy link

coveralls commented Nov 10, 2025

Coverage Status

coverage: 95.276% (+13.5%) from 81.727%
when pulling 390ce3c on fix/next16-ssr-uuid-generation
into 0379c98 on master.

@mandarini mandarini changed the title fix(auth): make uuid() SSR-aware for Next.js 16 compatibility fix(auth): use Symbols for callback IDs to resolve Next.js 16 compatibility Nov 11, 2025
@mandarini mandarini self-assigned this Nov 11, 2025
@mandarini mandarini marked this pull request as ready for review November 11, 2025 09:54
@mandarini mandarini requested review from a team as code owners November 11, 2025 09:54
@mandarini mandarini merged commit e9e44a3 into master Nov 11, 2025
36 of 37 checks passed
@mandarini mandarini deleted the fix/next16-ssr-uuid-generation branch November 11, 2025 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth-js Related to the auth-js library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Next.js 16: createBrowserClient() used Math.random() inside a Client Component without a Suspense boundary above it

4 participants