Skip to content

feat: add 'use client' directive to bundles for RSC support - #1179

Open
gyaneshgouraw-okta wants to merge 4 commits into
mainfrom
rsc-support-pr
Open

feat: add 'use client' directive to bundles for RSC support#1179
gyaneshgouraw-okta wants to merge 4 commits into
mainfrom
rsc-support-pr

Conversation

@gyaneshgouraw-okta

@gyaneshgouraw-okta gyaneshgouraw-okta commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds React Server Components support so @auth0/auth0-react works with the Next.js App Router. The published ESM and CommonJS bundles now ship a top-level 'use client' directive, letting you import Auth0Provider directly into a Server Component (e.g. app/layout.tsx) without writing a custom 'use client' wrapper. Components that call hooks like useAuth0() are still Client Components, per standard RSC rules.

Changes

  • Inject a 'use client' directive at the top of the built ESM and CommonJS bundles via Rollup's output.banner (the UMD <script> builds intentionally omit it).
  • Add a test that asserts the directive is present on the RSC bundles and absent from the UMD bundles, checking the built output rather than source.
  • Make that test fail-closed in CI (hard error when bundles are missing) while skipping locally when dist/ is not built, so the guarantee can never silently pass.
  • Wire a dedicated CI job that builds the bundles and runs the directive assertions on every PR.
  • Add a test:dist script that builds then runs the directive test.
  • Document App Router usage, including passing an explicit redirect_uri from the Server Component instead of window.location.origin.

Example

// app/layout.tsx — Server Component, no 'use client' wrapper needed
import { Auth0Provider } from '@auth0/auth0-react';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Auth0Provider
          domain={process.env.NEXT_PUBLIC_AUTH0_DOMAIN as string}
          clientId={process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID as string}
          authorizationParams={{ redirect_uri: process.env.NEXT_PUBLIC_BASE_URL as string }}
        >
          {children}
        </Auth0Provider>
      </body>
    </html>
  );
}

Testing

  • npm run test:dist — builds the bundles and runs the directive suite (4 passing: 2 RSC bundles carry the directive, 2 UMD bundles don't).
  • Negative check: removing a banner from the Rollup config and rebuilding makes the corresponding RSC assertion fail.
  • Fail-closed check: CI=true with no dist/ throws instead of skipping; without CI it skips with a warning.
  • npm test full unit suite passes (147 tests); npm run lint clean.

Summary by CodeRabbit

  • New Features
    • Improved Next.js App Router + React Server Components compatibility by ensuring the 'use client' directive is preserved in supported distribution bundle formats.
  • Documentation
    • Expanded guidance and examples for using Auth0Provider in App Router Server Components while keeping hook consumers as Client Components.
  • Tests
    • Added a distribution-level automated check that verifies 'use client' placement in built artifacts.
  • Chores
    • Added a CI job and npm script to run the distribution directive verification during builds.

@gyaneshgouraw-okta
gyaneshgouraw-okta requested a review from a team as a code owner July 27, 2026 15:12
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e662dedc-73b5-4aca-bcb3-bcc8e2ad9ac9

📥 Commits

Reviewing files that changed from the base of the PR and between 82b5c08 and 6006a02.

📒 Files selected for processing (1)
  • .github/workflows/test.yml
💤 Files with no reviewable changes (1)
  • .github/workflows/test.yml

📝 Walkthrough

Walkthrough

Rollup adds 'use client'; to CJS and ESM bundles, with Jest and CI verification. Provider documentation and examples describe Next.js App Router Server Component configuration and Client Component hook usage.

Changes

Client Directive Support

Layer / File(s) Summary
Bundle client directive injection
rollup.config.mjs
CJS and ESM outputs receive a 'use client'; banner, while UMD output remains unchanged.
Bundle directive validation
__tests__/use-client-directive.test.tsx, package.json, .github/workflows/test.yml
Built bundle assertions run through test:dist, with a dedicated CI job validating directive behavior.
Next.js App Router guidance
src/auth0-provider.tsx, EXAMPLES.md
Provider documentation and examples describe Server Component configuration and Client Component hook usage.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the core change: adding a 'use client' directive to ESM/CJS bundles for RSC support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rsc-support-pr

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@__tests__/use-client-directive.test.tsx`:
- Around line 54-60: Replace the generic process.env.CI guard in the
missing-bundle check of use-client-directive.test.tsx with an explicit
directive-verification environment flag. In .github/workflows/test.yml lines
86-87, set that flag only on the rsc-directive npm run test:dist step; leave the
unit job unchanged.

In @.github/workflows/test.yml:
- Around line 74-75: Update the actions/checkout step in the workflow to disable
persisted credentials by setting persist-credentials to false, ensuring the
checkout token is not retained for later project-controlled steps.

In `@EXAMPLES.md`:
- Line 497: Update the Server Components guidance in EXAMPLES.md to specifically
state that useAuth0() must be called from a Client Component because it depends
on Auth0 context and browser APIs. Remove the broad claim that any hook call
requires a Client Component, while preserving the instruction to use 'use
client' for components invoking useAuth0().
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f68b6605-f252-475a-9691-994e43e04f29

📥 Commits

Reviewing files that changed from the base of the PR and between 2a2e930 and 7688362.

📒 Files selected for processing (6)
  • .github/workflows/test.yml
  • EXAMPLES.md
  • __tests__/use-client-directive.test.tsx
  • package.json
  • rollup.config.mjs
  • src/auth0-provider.tsx

Comment thread __tests__/use-client-directive.test.tsx
Comment on lines +74 to +75
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Do not persist the checkout token.

No later step needs Git credentials, but npm ci can run project-controlled lifecycle scripts. Disable persisted credentials for this new job.

Proposed fix
       - name: Checkout code
         uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 74-75: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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 @.github/workflows/test.yml around lines 74 - 75, Update the actions/checkout
step in the workflow to disable persisted credentials by setting
persist-credentials to false, ensuring the checkout token is not retained for
later project-controlled steps.

Source: Linters/SAST tools

Comment thread EXAMPLES.md
}
```

Any component that **calls** a hook such as `useAuth0()` runs on the client, so that component must be a Client Component. This is a standard React Server Components rule (hooks cannot execute during server render), not something the SDK can remove: mark the file with `'use client'`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Locate EXAMPLES.md ==="
fd -a '^EXAMPLES\.md$' . || true

echo "=== Relevant lines around 497 ==="
if [ -f EXAMPLES.md ]; then
  sed -n '470,515p' EXAMPLES.md | nl -ba -v470
else
  fd -a '^EXAMPLES\.md$' . -x sh -c 'echo "--- $1"; sed -n "470,515p" "$1" | nl -ba -v470' sh {}
fi

echo "=== Nearby useAuth0/useAuth docs ==="
rg -n "useAuth0|useAuth|Server Components|Client Component|hook|hooks" EXAMPLES.md || true

Repository: auth0/auth0-react

Length of output: 287


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== EXAMPLES.md around line 497 ==="
sed -n '485,505p' EXAMPLES.md

echo "=== Hooks/auth-related nearby docs ==="
python3 - <<'PY'
from pathlib import Path
p = Path('EXAMPLES.md')
text = p.read_text()
lines = text.splitlines()
for i, line in enumerate(lines, 1):
    low = line.lower()
    if any(k in low for k in ('useauth0', 'use auth0', 'server components', 'client component', 'hooks cannot', 'hooks cannot execute')):
        print(f"{i:04d}: {line}")
PY

Repository: auth0/auth0-react

Length of output: 5236


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Section title and surrounding example ==="
sed -n '458,528p' EXAMPLES.md

echo "=== All occurrences of '(hooks cannot|standard React Server Components rule)' ==="
python3 - <<'PY'
from pathlib import Path
for i, line in enumerate(Path('EXAMPLES.md').read_text().splitlines(), 1):
    if 'standard React Server Components rule' in line or 'hooks cannot execute during server render' in line:
        print(f'{i}: {line}')
PY

Repository: auth0/auth0-react

Length of output: 3200


Narrow the Server Components hook statement.

useAuth0() needs to run in a Client Component because it reads the Auth0 context/browser APIs, but React Server Components can still use certain hooks like useId. Avoid calling hooks generally unsupported during server rendering.

Suggested wording
-This is a standard React Server Components rule (hooks cannot execute during server render), not something the SDK can remove: mark the file with `'use client'`.
+Because `useAuth0()` reads the client-side Auth0 context, the component that calls it must be marked with `'use client'`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Any component that **calls** a hook such as `useAuth0()` runs on the client, so that component must be a Client Component. This is a standard React Server Components rule (hooks cannot execute during server render), not something the SDK can remove: mark the file with `'use client'`.
Any component that **calls** a hook such as `useAuth0()` runs on the client, so that component must be a Client Component. Because `useAuth0()` reads the client-side Auth0 context, the component that calls it must be marked with `'use client'`.
🤖 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 `@EXAMPLES.md` at line 497, Update the Server Components guidance in
EXAMPLES.md to specifically state that useAuth0() must be called from a Client
Component because it depends on Auth0 context and browser APIs. Remove the broad
claim that any hook call requires a Client Component, while preserving the
instruction to use 'use client' for components invoking useAuth0().

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