Skip to content

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Dec 5, 2025

Description

Fixes: USER-3389

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Added Show for flexible conditional rendering (supports 'signedIn', 'signedOut', auth objects, and predicate functions) with optional fallback.
  • Refactor

    • Replaced client-side Protect usage with Show; Protect is now server-only and will error if used on the client. Exports updated to surface Show in client bundles.
  • Types

    • Introduced ProtectParams, ShowWhenCondition, ShowProps; ProtectProps retained as deprecated alias.
  • Tests / Tools

    • Added server tests and a codemod with fixtures to migrate Protect → Show.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Dec 5, 2025

🦋 Changeset detected

Latest commit: 73637d8

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

This PR includes changesets to release 20 packages
Name Type
@clerk/upgrade Minor
@clerk/react Major
@clerk/nextjs Major
@clerk/expo Major
@clerk/chrome-extension Major
@clerk/shared Minor
@clerk/astro Patch
@clerk/vue Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/agent-toolkit Patch
@clerk/backend Patch
@clerk/clerk-js Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nuxt Patch
@clerk/testing Patch
@clerk/ui 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 Dec 5, 2025

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

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Dec 11, 2025 4:18am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2025

Walkthrough

Replaces client-facing Protect with a new Show API across packages, introduces ProtectParams and ShowWhenCondition types, updates exports and component implementations (client/server variants), adds a jscodeshift codemod and tests to migrate Protect → Show, and makes Protect server-only in Next.js client barrels. (34 words)

Changes

Cohort / File(s) Summary
Shared types
packages/shared/src/types/protect.ts
Added ProtectParams (canonical) and deprecated alias ProtectProps; introduced ShowWhenCondition and ShowProps; updated docs and exported types to support Show and the new param shapes.
React components
packages/react/src/components/controlComponents.tsx, packages/react/src/components/index.ts
Replaced Protect/ProtectProps with Show/ShowProps; added checkAuthorization helper; implemented when handling (string/object/function) and adjusted isLoaded/treatPendingAsSignedOut behavior; updated exports.
Framework re-exports & type tweaks
packages/chrome-extension/src/react/re-exports.ts, packages/expo/src/components/controlComponents.tsx, packages/astro/src/react/controlComponents.tsx, packages/vue/src/components/controlComponents.ts
Swapped re-exports: removed Protect, added Show; updated astro and vue to consume ProtectParams for server Protect props; minor typing/import adjustments (Astro PropsWithChildren inline, useEffect call site tweak).
Next.js (App Router server)
packages/nextjs/src/app-router/server/controlComponents.tsx, packages/nextjs/src/app-router/server/__tests__/controlComponents.test.tsx
Added server Show and AppRouterShowProps; Protect now accepts ProtectParams; new server tests cover signedIn/signedOut, fallback, object auth, and predicate conditions.
Next.js client/server boundaries & barrels
packages/nextjs/src/client-boundary/controlComponents.ts, packages/nextjs/src/components.client.ts, packages/nextjs/src/components.server.ts, packages/nextjs/src/index.ts
Exposed Show in client/server boundaries; removed client re-export of functional Protect and added a client-side placeholder Protect that throws a server-only error at runtime; updated server exports/types to include Show.
Codemod & tests
packages/upgrade/src/codemods/transform-protect-to-show.cjs, packages/upgrade/src/codemods/__tests__/transform-protect-to-show.test.js, packages/upgrade/src/codemods/__tests__/__fixtures__/transform-protect-to-show.fixtures.js, .changeset/migrate-to-show.md
New jscodeshift transformer converting <Protect><Show> (aggregates auth props into when, respects package groups and use-client directives), plus fixture-heavy tests and a changeset documenting the codemod.
Integration template updates
integration/templates/.../page.tsx, integration/templates/.../pricing-table/page.tsx, integration/templates/.../settings/*
Replaced Protect usages with Show and adapted props to when forms across example templates (no behavioral change).
Barrel/export sync across packages
packages/react/src/components/index.ts, packages/chrome-extension/src/react/re-exports.ts, packages/expo/src/components/controlComponents.tsx, packages/nextjs/src/components.server.ts, packages/nextjs/src/components.client.ts, packages/nextjs/src/index.ts
Removed Protect from public client export lists, added Show, introduced client-side placeholder Protect in Next.js client barrel, and synchronized exported type names across packages.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus areas:
    • packages/shared/src/types/protect.ts — union shapes, deprecated alias correctness, downstream type compatibility.
    • packages/react/src/components/controlComponents.tsxShow branching logic, checkAuthorization, and isLoaded / treatPendingAsSignedOut semantics.
    • packages/nextjs/* — client/server boundary behavior, client-side Protect placeholder message, exported type consistency.
    • packages/upgrade/src/codemods/transform-protect-to-show.cjs — RSC/use-client detection, import alias handling, JSX attribute aggregation into when, and fixture coverage.

Poem

🐇 I swapped Protect for Show with cheer,
I nudged the types and hopped quite near.
I stitched a "when" and fallbacks tight,
A codemod danced by day and night.
Hop on — the garden's safe to peer!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(repo): Migrate Protect to Show' clearly and concisely summarizes the main change: renaming/migrating the Protect component to Show.
Linked Issues check ✅ Passed The PR successfully addresses USER-3389 by renaming Protect to Show, treating it as breaking change, and adding documentation clarifying the component's non-security nature.
Out of Scope Changes check ✅ Passed All changes are within scope: component renaming (Protect→Show), API updates, codemod for migration, test fixtures, and template updates directly support the objective to deprecate/rename Protect.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/protect-refactor

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

@jacekradko jacekradko changed the title feat(repo): Protect -> Show feat(repo): Protect -> Show - WIP Dec 8, 2025
@jacekradko jacekradko marked this pull request as ready for review December 8, 2025 15:28
@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 8, 2025

Open in StackBlitz

@clerk/agent-toolkit

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

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 73637d8

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

🧹 Nitpick comments (1)
packages/upgrade/src/codemods/transform-protect-to-show.cjs (1)

197-205: Return logic and semicolon cleanup are correct.

The return logic correctly guards against no-op transformations, and the regex at line 203 adequately handles the double semicolon artifact that can occur when jscodeshift reprints directive prologues.

The regex pattern could be made more robust to handle quoted strings with different quote types, but given that directive prologues are typically simple strings like "use client" or "use strict", the current implementation is sufficient.

If you want a more precise pattern:

- result = result.replace(/^(['"`][^'"`]+['"`]);;/gm, '$1;');
+ result = result.replace(/^(["']use (client|server|strict)["']);;/gm, '$1;');

This explicitly matches known directives and is more restrictive, reducing the chance of false positives.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f774e21 and fdbb5cd.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • packages/upgrade/src/codemods/transform-protect-to-show.cjs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (3)
packages/upgrade/src/codemods/transform-protect-to-show.cjs (3)

1-44: LGTM! Comprehensive directive detection.

The package constants and hasUseClientDirective function are well-implemented. The function correctly handles multiple parser representations of the 'use client' directive (expression statements, directive fields, and program-level directives), ensuring robust detection across different AST formats.


66-88: LGTM! RSC guard logic is correct.

The setup and RSC detection logic properly identifies hybrid package imports and skips transformation for server components. This ensures that server-side Protect usage in frameworks like Next.js remains unchanged, which aligns with the PR's goal to only transform client-side components.


90-111: LGTM! Import transformation correctly handles aliases.

The import transformation logic properly handles both standard and aliased imports:

  • Standard: import { Protect }import { Show }
  • Aliased: import { Protect as MyProtect }import { Show as MyProtect }

The tracking of effectiveLocalName ensures JSX transformation can locate usage of both standard and aliased components.

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: 0

♻️ Duplicate comments (1)
packages/react/src/components/controlComponents.tsx (1)

79-104: JSDoc should include @param and @returns tags per coding guidelines.

The existing JSDoc provides good usage examples but is missing formal parameter documentation. A previous review already raised this concern with specific suggestions for improvement.

🧹 Nitpick comments (1)
packages/react/src/components/controlComponents.tsx (1)

105-135: Implementation logic is correct and consistent with server-side Show.

The authorization flow handles all ShowWhenCondition cases properly:

  1. signedOut string condition renders based on absence of userId
  2. Early return for unauthenticated users on authorization checks
  3. signedIn string condition renders when userId exists
  4. Delegate to checkAuthorization for ProtectParams and function conditions

Minor: Line 114's resolvedWhen = when assignment is redundant since when could be used directly, but this doesn't affect functionality.

-  const resolvedWhen = when;
   const authorized = children;
   const unauthorized = fallback ?? null;

-  if (resolvedWhen === 'signedOut') {
+  if (when === 'signedOut') {
     return userId ? unauthorized : authorized;
   }

   if (!userId) {
     return unauthorized;
   }

-  if (resolvedWhen === 'signedIn') {
+  if (when === 'signedIn') {
     return authorized;
   }

-  if (checkAuthorization(resolvedWhen, has)) {
+  if (checkAuthorization(when, has)) {
     return authorized;
   }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 88f3e35 and aba8aad.

📒 Files selected for processing (2)
  • packages/nextjs/src/app-router/server/controlComponents.tsx (3 hunks)
  • packages/react/src/components/controlComponents.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/nextjs/src/app-router/server/controlComponents.tsx
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

All code must pass ESLint checks with the project's configuration

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{js,jsx,ts,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/react/src/components/controlComponents.tsx
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Follow established naming conventions (PascalCase for components, camelCase for variables)

Files:

  • packages/react/src/components/controlComponents.tsx
packages/**/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

packages/**/src/**/*.{ts,tsx,js,jsx}: Maintain comprehensive JSDoc comments for public APIs
Use tree-shaking friendly exports
Validate all inputs and sanitize outputs
All public APIs must be documented with JSDoc
Use dynamic imports for optional features
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Implement proper logging with different levels

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.ts?(x)

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.tsx: Use error boundaries in React components
Minimize re-renders in React components

**/*.tsx: Use proper type definitions for props and state in React components
Leverage TypeScript's type inference where possible in React components
Use proper event types for handlers in React components
Implement proper generic types for reusable React components
Use proper type guards for conditional rendering in React components

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{md,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Update documentation for API changes

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/react.mdc)

**/*.{jsx,tsx}: Always use functional components with hooks instead of class components
Follow PascalCase naming for components (e.g., UserProfile, NavigationMenu)
Keep components focused on a single responsibility - split large components
Limit component size to 150-200 lines; extract logic into custom hooks
Use composition over inheritance - prefer smaller, composable components
Export components as named exports for better tree-shaking
One component per file with matching filename and component name
Separate UI components from business logic components
Use useState for simple state management in React components
Use useReducer for complex state logic in React components
Implement proper state initialization in React components
Use proper state updates with callbacks in React components
Implement proper state cleanup in React components
Use Context API for theme/authentication state management
Implement proper state persistence in React applications
Use React.memo for expensive components
Implement proper useCallback for handlers in React components
Use proper useMemo for expensive computations in React components
Implement proper virtualization for lists in React components
Use proper code splitting with React.lazy in React applications
Implement proper cleanup in useEffect hooks
Use proper refs for DOM access in React components
Implement proper event listener cleanup in React components
Use proper abort controllers for fetch in React components
Implement proper subscription cleanup in React components
Use proper HTML elements for semantic HTML in React components
Implement proper ARIA attributes for accessibility in React components
Use proper heading hierarchy in React components
Implement proper form labels in React components
Use proper button types in React components
Implement proper focus management for keyboard navigation in React components
Use proper keyboard shortcuts in React components
Implement proper tab order in React components
Use proper ...

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details in classes
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Use mixins for shared behavior across unrelated classes in TypeScript
Use generic constraints with bounded type parameters like <T extends { id: string }>
Use utility types like Omit, Partial, and Pick for data transformation instead of manual type construction
Use discriminated unions instead of boolean flags for state management and API responses
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation at the type level
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Document functions with JSDoc comments including @param, @returns, @throws, and @example tags
Create custom error classes that extend Error for specific error types
Use the Result pattern for error handling instead of throwing exceptions
Use optional chaining (?.) and nullish coalescing (??) operators for safe property access
Let TypeScript infer obvious types to reduce verbosity
Use const assertions with as const for literal types
Use satisfies operator for type checking without widening types
Declare readonly arrays and objects for immutable data structures
Use spread operator and array spread for immutable updates instead of mutations
Use lazy loading for large types...

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use ESLint with custom configurations tailored for different package types

Files:

  • packages/react/src/components/controlComponents.tsx
**/*.{js,ts,jsx,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use Prettier for code formatting across all packages

Files:

  • packages/react/src/components/controlComponents.tsx
🧬 Code graph analysis (1)
packages/react/src/components/controlComponents.tsx (4)
packages/shared/src/types/protect.ts (2)
  • ShowProps (110-113)
  • ShowWhenCondition (82-86)
packages/shared/src/types/session.ts (1)
  • PendingSessionOptions (35-42)
packages/nextjs/src/app-router/server/controlComponents.tsx (1)
  • Show (114-138)
packages/react/src/hooks/useAuth.ts (1)
  • useAuth (95-124)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
packages/react/src/components/controlComponents.tsx (3)

2-2: LGTM!

Import correctly sources types from @clerk/shared/types as recommended by the coding guidelines.


72-77: LGTM!

Type definition is well-structured. Using React.ReactNode for fallback is the appropriate narrowing of the shared type's unknown for React context.


137-145: LGTM!

The helper function correctly handles the narrowed ShowWhenCondition type after string literals are excluded. The type signature using Exclude<ShowWhenCondition, 'signedIn' | 'signedOut'> is accurate, and the logic properly delegates to either the predicate function or the has helper for object-based authorization.

@jacekradko jacekradko changed the title feat(repo): Protect -> Show - WIP feat(repo): Protect -> Show Dec 10, 2025
@jacekradko jacekradko changed the title feat(repo): Protect -> Show feat(repo): Migrate Protect to Show Dec 10, 2025
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: 0

🧹 Nitpick comments (2)
integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx (1)

3-11: Show usage and when-condition look good; consider explicit return type

The Show wrapper with fallback and when={{ role: 'org:admin' }} correctly mirrors the previous Protect semantics for this template, and the UI messages are consistent with the role check.

As an optional cleanup to align with stricter TSX guidelines, you could add an explicit return type to the page component:

-export default function Page() {
+export default function Page(): JSX.Element {
integration/templates/next-app-router/src/app/page.tsx (1)

12-26: Show usage is correct; consider updating stale “protect” copy

The Show blocks with when='signedIn' and plan-based when={{ plan: ... }} look aligned with the new API. The fallback/content strings ('SignedOut from protect', SignedIn from protect) still mention “protect”, which could be confusing in a Show-based template—consider renaming to reference Show or use neutral wording.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between aba8aad and 8db6d35.

📒 Files selected for processing (4)
  • integration/templates/next-app-router/src/app/page.tsx (2 hunks)
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx (2 hunks)
  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx (1 hunks)
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

All code must pass ESLint checks with the project's configuration

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{js,jsx,ts,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Follow established naming conventions (PascalCase for components, camelCase for variables)

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.ts?(x)

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.tsx: Use error boundaries in React components
Minimize re-renders in React components

**/*.tsx: Use proper type definitions for props and state in React components
Leverage TypeScript's type inference where possible in React components
Use proper event types for handlers in React components
Implement proper generic types for reusable React components
Use proper type guards for conditional rendering in React components

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{md,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Update documentation for API changes

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/react.mdc)

**/*.{jsx,tsx}: Always use functional components with hooks instead of class components
Follow PascalCase naming for components (e.g., UserProfile, NavigationMenu)
Keep components focused on a single responsibility - split large components
Limit component size to 150-200 lines; extract logic into custom hooks
Use composition over inheritance - prefer smaller, composable components
Export components as named exports for better tree-shaking
One component per file with matching filename and component name
Separate UI components from business logic components
Use useState for simple state management in React components
Use useReducer for complex state logic in React components
Implement proper state initialization in React components
Use proper state updates with callbacks in React components
Implement proper state cleanup in React components
Use Context API for theme/authentication state management
Implement proper state persistence in React applications
Use React.memo for expensive components
Implement proper useCallback for handlers in React components
Use proper useMemo for expensive computations in React components
Implement proper virtualization for lists in React components
Use proper code splitting with React.lazy in React applications
Implement proper cleanup in useEffect hooks
Use proper refs for DOM access in React components
Implement proper event listener cleanup in React components
Use proper abort controllers for fetch in React components
Implement proper subscription cleanup in React components
Use proper HTML elements for semantic HTML in React components
Implement proper ARIA attributes for accessibility in React components
Use proper heading hierarchy in React components
Implement proper form labels in React components
Use proper button types in React components
Implement proper focus management for keyboard navigation in React components
Use proper keyboard shortcuts in React components
Implement proper tab order in React components
Use proper ...

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details in classes
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Use mixins for shared behavior across unrelated classes in TypeScript
Use generic constraints with bounded type parameters like <T extends { id: string }>
Use utility types like Omit, Partial, and Pick for data transformation instead of manual type construction
Use discriminated unions instead of boolean flags for state management and API responses
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation at the type level
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Document functions with JSDoc comments including @param, @returns, @throws, and @example tags
Create custom error classes that extend Error for specific error types
Use the Result pattern for error handling instead of throwing exceptions
Use optional chaining (?.) and nullish coalescing (??) operators for safe property access
Let TypeScript infer obvious types to reduce verbosity
Use const assertions with as const for literal types
Use satisfies operator for type checking without widening types
Declare readonly arrays and objects for immutable data structures
Use spread operator and array spread for immutable updates instead of mutations
Use lazy loading for large types...

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use ESLint with custom configurations tailored for different package types

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
**/*.{js,ts,jsx,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use Prettier for code formatting across all packages

Files:

  • integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx
  • integration/templates/next-app-router/src/app/page.tsx
  • integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx
  • integration/templates/next-app-router/src/app/pricing-table/page.tsx
🧬 Code graph analysis (3)
integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx (1)
integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx (1)
  • Page (3-12)
integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx (3)
integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx (1)
  • Page (4-13)
integration/templates/next-app-router/src/app/settings/auth-protect/page.tsx (1)
  • Page (3-6)
integration/templates/next-app-router/src/app/settings/useAuth-has/page.tsx (1)
  • Page (4-13)
integration/templates/next-app-router/src/app/pricing-table/page.tsx (2)
packages/nextjs/src/index.ts (1)
  • Show (17-17)
packages/react/src/components/index.ts (1)
  • Show (31-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (6)
integration/templates/next-app-router/src/app/settings/rsc-protect/page.tsx (1)

1-1: Show import migration looks correct

Switching the import to Show from @clerk/nextjs matches the new API surface and PR intent; no issues with the import itself.

Please confirm your installed @clerk/nextjs version exposes Show from the root entrypoint so this template stays in sync with the published package.

integration/templates/next-app-router/src/app/settings/rcc-protect/page.tsx (2)

2-2: LGTM: Import updated correctly.

The import statement correctly migrates from Protect to Show, aligning with the PR's objective to rename the component for better clarity about its visual show/hide purpose.


6-11: This is a template file correctly demonstrating the Show component's client-side usage. The page is intentionally designed to show permission-based conditional rendering in a client component, which is a valid pattern that Clerk's Show component supports. The template appropriately includes separate examples (like auth-protect) for server-side protection approaches. No changes needed.

Likely an incorrect or invalid review comment.

integration/templates/next-app-router/src/app/pricing-table/page.tsx (2)

1-1: LGTM: Import updated for Protect → Show migration.

The import correctly reflects the migration to the semantically clearer Show component, which better conveys that this component only controls visibility rather than providing security guarantees.


11-19: LGTM: Show component usage is correct.

The migration to Show with the when={{ plan: 'value' }} syntax is clean and consistent across all three usage instances. The object-based when prop correctly follows the API pattern for plan-based conditional rendering, which is fully supported by the async server component implementation in @clerk/nextjs.

integration/templates/next-app-router/src/app/page.tsx (1)

1-1: Import swap to Show from @clerk/nextjs looks consistent

The import change aligns with the Protect → Show migration and matches the rest of the file’s usage; no issues from a typing or linting perspective.

@jacekradko
Copy link
Member Author

!allow-major

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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a603b43 and 671c0f1.

📒 Files selected for processing (2)
  • .changeset/migrate-to-show.md (1 hunks)
  • .changeset/show-the-guards.md (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
  • GitHub Check: Static analysis
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (4)
.changeset/show-the-guards.md (3)

2-8: Version bump strategy aligns well with the breaking API change.

The major version bumps for user-facing packages (@clerk/react, @clerk/nextjs, @clerk/expo, @clerk/chrome-extension) correctly reflect the breaking change of replacing Protect with Show on the client side. The minor bump for @clerk/shared appropriately captures new type additions, and patch bumps for wrapper packages (astro, vue) are suitable for mirroring public API changes without introducing new breaking changes at that layer.


11-11: Changeset description clearly communicates the scope of the migration.

The summary effectively captures the dual nature of this breaking change: restricting Protect to App Router server usage while introducing Show as the client-side authorization component. This should adequately inform consumers during upgrade.


1-11: Ensure migration guidance and deprecation notices are documented separately.

Changesets are lightweight version-bump announcements. For a migration of this magnitude (Protect → Show API), verify that comprehensive migration guidance, deprecation notices, and codemod instructions are documented in:

  • CHANGELOG entries or migration guides in clerk-docs
  • README or upgrade guide in the packages
  • Any deprecation warnings in runtime code (e.g., console warnings or JSDoc deprecation tags on Protect exports)

Can you confirm that migration guidance and deprecation notices are in place outside this changeset file (e.g., in documentation or inline code deprecations)?

.changeset/migrate-to-show.md (1)

1-3: The changeset is correct as written. The Protect→Show breaking change is documented with appropriate major version bumps in the show-the-guards.md changeset. The migrate-to-show.md changeset appropriately documents only the new codemod tool addition to @clerk/upgrade with a minor version bump.

'@clerk/upgrade': minor
---

Add a `transform-protect-to-show` codemod that migrates client-side `<Protect>` usage to `<Show>` with automatic prop and import updates.
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 11, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Changeset description is incomplete for user-facing breaking changes.

The description focuses only on the migration codemod but omits the user-facing breaking changes:

  • Deprecation/removal of <Protect /> from client-side exports
  • Introduction of <Show /> as the replacement component
  • Clarification that the component only visually hides/shows content (not cryptographically secure)
  • Server-only restriction of Protect in Next.js and related packages

Consider expanding the description to communicate the breaking change impact and direct users to migration guidance.

Suggested revision:

- Add a `transform-protect-to-show` codemod that migrates client-side `<Protect>` usage to `<Show>` with automatic prop and import updates.
+ **BREAKING**: Renamed client-side `<Protect />` component to `<Show />` across packages. The `<Protect />` component is now server-only in Next.js. Use the provided `transform-protect-to-show` codemod to automatically migrate client-side usage. Note: The `<Show />` component visually hides/shows content and does not cryptographically secure data; sensitive content should not rely on this component for protection.
📝 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
Add a `transform-protect-to-show` codemod that migrates client-side `<Protect>` usage to `<Show>` with automatic prop and import updates.
**BREAKING**: Renamed client-side `<Protect />` component to `<Show />` across packages. The `<Protect />` component is now server-only in Next.js. Use the provided `transform-protect-to-show` codemod to automatically migrate client-side usage. Note: The `<Show />` component visually hides/shows content and does not cryptographically secure data; sensitive content should not rely on this component for protection.
🤖 Prompt for AI Agents
In .changeset/migrate-to-show.md around line 5, the changeset text only mentions
the migration codemod but omits the user-facing breaking change details; update
the description to explicitly state that client-side <Protect /> is
deprecated/removed, that a new <Show /> component replaces it (and imports/props
will be migrated by the codemod), that <Show /> only toggles visual visibility
(not cryptographically secure), and that Protect remains server-only in
Next.js/related packages; also add a short pointer to the migration
guidance/codemod and mark this as a breaking change so users know they must run
the migration.

Copy link
Member Author

Choose a reason for hiding this comment

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

This PR contains multiple changesets that are scoped to appropriate packages. This changeset is specifically addressing changes to @clerk/upgrade which are non-breaking

Copy link
Contributor

Choose a reason for hiding this comment

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

@jacekradko You're absolutely right, thank you for the clarification. I see now that this changeset is correctly scoped to @clerk/upgrade and documents the non-breaking addition of the migration codemod (marked as minor). The breaking changes for the component rename/deprecation are appropriately documented in the separate show-the-guards.md changeset for the affected packages.

My suggestion to expand this changeset was incorrect. The current description accurately reflects the changes to @clerk/upgrade specifically. Apologies for the confusion!

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.

4 participants