Skip to content

feat(nextjs): Add support for Next.js 16 cache components#7595

Merged
jacekradko merged 13 commits intomainfrom
feat/nextjs-cache-components-support
Feb 5, 2026
Merged

feat(nextjs): Add support for Next.js 16 cache components#7595
jacekradko merged 13 commits intomainfrom
feat/nextjs-cache-components-support

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Jan 14, 2026

Summary

Adds support for Next.js 16 cache components by improving error detection and providing helpful error messages when auth() or currentUser() are called inside a "use cache" function.

Changes

  • Add ClerkUseCacheError class with symbol marker to prevent double-wrapping of error messages
  • Add isNextjsUseCacheError() helper to detect "use cache" context errors with tightened regex patterns to reduce false positives
  • Add isClerkUseCacheError() helper to identify already-formatted Clerk errors
  • Update buildRequestLike() to throw ClerkUseCacheError with helpful message
  • Update auth() and currentUser() to check for already-formatted errors before wrapping
  • Update clerkClient() to re-throw ClerkUseCacheError
  • Add unit tests for error detection and handling

Problem

When a developer calls auth() or currentUser() inside a "use cache" function, they receive a cryptic error about headers() not being allowed in cache contexts.

Solution

Detect these errors and provide a helpful message with a code example showing the correct pattern:

Clerk: auth() and currentUser() cannot be called inside a "use cache" function.
These functions access `headers()` internally, which is a dynamic API not allowed in cached contexts.

To fix this, call auth() outside the cached function and pass the values you need as arguments:

  async function getCachedUser(userId: string) {
    "use cache";
    const client = await clerkClient();
    return client.users.getUser(userId);
  }

  // In your component/page:
  const { userId } = await auth();
  if (userId) {
    const user = await getCachedUser(userId);
  }

Implementation details

  • Uses a custom ClerkUseCacheError class with a symbol marker to prevent double-wrapping when errors bubble through multiple catch handlers (buildRequestLikeauthcurrentUser)
  • Tightened regex patterns in isNextjsUseCacheError() to reduce false positives - now requires specific Next.js error patterns like "use cache" combined with headers/cookies context

Test plan

  • Unit tests for ClerkUseCacheError, isClerkUseCacheError(), isNextjsUseCacheError(), and isPrerenderingBailout()
  • Integration tests for cache components
  • Build succeeds
  • All tests pass

How to verify

Setup

  1. Create or use a Next.js 16 app with cache components enabled:

    // next.config.ts
    import type { NextConfig } from 'next'
    
    const nextConfig: NextConfig = {
      cacheComponents: true, // No longer under experimental in Next.js 16
    }
    
    export default nextConfig
  2. Install the PR preview package:

    npm i https://pkg.pr.new/@clerk/nextjs@7595

Test the error detection

Create a page that calls auth() inside a "use cache" function:

// app/test-cache/page.tsx
import { auth } from '@clerk/nextjs/server';

async function getCachedData() {
  "use cache";
  const { userId } = await auth(); // This should trigger our helpful error
  return { userId };
}

export default async function TestPage() {
  const data = await getCachedData();
  return <div>{JSON.stringify(data)}</div>;
}

Expected behavior

Before this PR: Cryptic Next.js error about headers() not being allowed in cache contexts

After this PR: Clear error message explaining the issue and showing the correct pattern

Summary by CodeRabbit

  • New Features

    • Added support for Next.js 16 cache components.
  • Bug Fixes

    • Improved detection and clearer, actionable error messages when auth() or currentUser() are used inside a "use cache" context.
    • Standardized handling to surfacing original error details for easier debugging.
  • Documentation

    • Added interactive example pages demonstrating correct cache usage patterns and an error-triggering demo.
  • Tests

    • Expanded end-to-end and unit tests covering cache-component scenarios and error messaging.

- Add `isNextjsUseCacheError()` helper to detect "use cache" context errors
- Update `isPrerenderingBailout()` to detect cache component prerendering errors
- Update `buildRequestLike()` to provide helpful error message with code example
  when auth() is called inside a "use cache" function
- Update `clerkClient()` to re-throw "use cache" errors
- Add unit tests for error detection helpers
@changeset-bot
Copy link

changeset-bot bot commented Jan 14, 2026

🦋 Changeset detected

Latest commit: 9db278b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 14, 2026

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 5, 2026 7:28pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

Adds explicit detection and handling for Next.js “use cache” / cache components errors to the Clerk Next.js package. Introduces ClerkUseCacheError, isClerkUseCacheError, isNextjsUseCacheError, regex patterns for Next.js error messages, and USE_CACHE_ERROR_MESSAGE. Integrates these into server utilities and request construction, and updates clerkClient, auth, and currentUser to rethrow or wrap matched errors. Adds unit tests for the helpers, integration pages and an API route demonstrating correct/incorrect “use cache” patterns, and a changeset documenting the capability.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature: adding support for Next.js 16 cache components, which aligns with all changes including the new error detection, handling mechanisms, test coverage, and integration templates.

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


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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 14, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7595

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7595

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7595

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7595

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7595

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7595

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7595

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7595

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7595

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7595

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7595

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7595

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7595

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7595

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7595

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7595

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7595

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7595

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7595

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7595

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7595

commit: 9db278b

Wrap auth() and currentUser() in try-catch to catch "use cache" errors
that bubble up from the Next.js cache boundary. The original
implementation only caught errors inside buildRequestLike(), but Next.js
throws these errors at a higher level.
Co-authored-by: Fredrik Höglund <fredrik@clerk.dev>
Copy link
Contributor

@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: 1

🤖 Fix all issues with AI agents
In `@packages/nextjs/src/app-router/server/auth.ts`:
- Around line 138-143: The catch block in auth.ts re-wraps Next.js "use cache"
errors that buildRequestLike() already formats, causing duplicate messages;
update the catch in the function containing isNextjsUseCacheError(e) to first
detect if the thrown error is already formatted (e.g., check if e.message
startsWith or equals USE_CACHE_ERROR_MESSAGE or if a marker property exists) and
only re-wrap when it is not already formatted, or remove the catch entirely and
rely on buildRequestLike(); reference isNextjsUseCacheError, buildRequestLike,
and USE_CACHE_ERROR_MESSAGE when making the change.

- Add currentUser() server component test page and tests
- Add currentUser() with "use cache" correct pattern page
- Add error trigger page that calls auth() inside "use cache"
- Add test verifying Clerk's custom error message is shown
- Add signed-out state tests for cache and PPR pages
- Update home page navigation with new test links
- Add ClerkUseCacheError class with symbol marker to identify already-formatted errors
- Update auth() and currentUser() to check for ClerkUseCacheError before wrapping
- Tighten isNextjsUseCacheError() regex to reduce false positives
- Update clerkClient.ts to use isClerkUseCacheError
};

// Patterns for Next.js "use cache" errors - tightened to reduce false positives
const USE_CACHE_WITH_DYNAMIC_API_PATTERN =
Copy link
Member

Choose a reason for hiding this comment

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

❓ I think this regex will miss 'use cache' - shouldn't we catch this as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice catch.. updated to handle both single and double quotes

…ponents-support

# Conflicts:
#	packages/nextjs/src/app-router/server/auth.ts
@jacekradko jacekradko merged commit b40ed01 into main Feb 5, 2026
41 checks passed
@jacekradko jacekradko deleted the feat/nextjs-cache-components-support branch February 5, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants