Releases: clerk/javascript
Release list
@clerk/agent-toolkit@0.3.1
Patch Changes
- Updated dependencies [
55ece85]:- @clerk/backend@3.0.1
@clerk/vue@2.0.0
Major Changes
-
Align experimental/unstable prefixes to use consistent naming: (#7361) by @brkalow
- Renamed all
__unstable_*methods to__internal_*(for internal APIs) - Renamed all
experimental__*andexperimental_*methods to__experimental_*(for beta features) - Removed deprecated billing-related props (
__unstable_manageBillingUrl,__unstable_manageBillingLabel,__unstable_manageBillingMembersLimit) andexperimental__forceOauthFirst
- Renamed all
-
Require Node.js 20.9.0 in all packages (#7262) by @jacekradko
-
Introduce
<Show when={...}>as the cross-framework authorization control component and remove<Protect>,<SignedIn>, and<SignedOut>in favor of<Show>. (#7373) by @jacekradko -
getToken()now throwsClerkOfflineErrorinstead of returningnullwhen the client is offline. (#7598) by @bratsosThis makes it explicit that a token fetch failure was due to network conditions, not authentication state. Previously, returning
nullcould be misinterpreted as "user is signed out," potentially causing the cached token to be cleared.To handle this change, catch
ClerkOfflineErrorfromgetToken()calls:import { ClerkOfflineError } from '@clerk/react/errors'; try { const token = await session.getToken(); } catch (error) { if (ClerkOfflineError.is(error)) { // Handle offline scenario - show offline UI, retry later, etc. } throw error; }
Minor Changes
-
Remove
clerkJSVariantoption and headless bundle. UseprefetchUI={false}instead. (#7629) by @jacekradko -
Add
uiprop toClerkProviderfor passing@clerk/ui(#7664) by @jacekradko -
Add standalone
getToken()function for retrieving session tokens outside of framework component trees. (#7325) by @bratsosThis function is safe to call from anywhere in the browser, such as API interceptors, data fetching layers (e.g., React Query, SWR), or vanilla JavaScript code. It automatically waits for Clerk to initialize before returning the token.
import { getToken } from '@clerk/nextjs'; // or any framework package
// Example: Axios interceptor
axios.interceptors.request.use(async (config) => {
const token = await getToken();
if (token) {
config.headers.Authorization =Bearer ${token};
}
return config;
}); -
Add
/typessubpath export to re-export types from@clerk/shared/typesalong with SDK-specific types. This allows importing Clerk types directly from the SDK package (e.g.,import type { UserResource } from '@clerk/react/types') without needing to install@clerk/typesas a separate dependency. (#7644) by @nikosdouvlis -
Introduce
<UNSAFE_PortalProvider>component which allows you to specify a custom container for Clerk floating UI elements (popovers, modals, tooltips, etc.) that use portals. Only Clerk components within the provider will be affected, components outside the provider will continue to use the default document.body for portals. (#7310) by @alexcarpenterThis is particularly useful when using Clerk components inside external UI libraries like Radix Dialog or React Aria Components, where portaled elements need to render within the dialog's container to remain interact-able.
'use client'; import { useRef } from 'react'; import * as Dialog from '@radix-ui/react-dialog'; import { UNSAFE_PortalProvider, UserButton } from '@clerk/nextjs'; export function UserDialog() { const containerRef = useRef<HTMLDivElement>(null); return ( <Dialog.Root> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog.Portal> <Dialog.Overlay /> <Dialog.Content ref={containerRef}> <UNSAFE_PortalProvider getContainer={() => containerRef.current}> <UserButton /> </UNSAFE_PortalProvider> </Dialog.Content> </Dialog.Portal> </Dialog.Root> ); }
-
Introduced internal composable for handling routing configuration for UI components (#7260) by @wobsoriano
Patch Changes
- Updated dependencies [
0a9cce3,e35960f,c9f0d77,1bd1747,6a2ff9e,d2cee35,0a9cce3,a374c18,466d642,5ef4a77,af85739,10b5bea,a05d130,b193f79,e9d2f2f,43fc7b7,0f1011a,cbc5618,38def4f,7772f45,a3e689f,583f7a9,965e7f1,2b76081,f284c3d,ac34168,cf0d0dc,690280e,b971d0b,22d1689,e9a1d4d,c088dde,8902e21,972f6a0,a1aaff3,d85646a,ab3dd16,4a8cb10,fd195c1,8887fac,dc886a9,428629b,8b95393,c438fa5,c438fa5,fd195c1,fd69edb,8d91225,1fc95e2, [3dac245](https://github.com/clerk/javas...
@clerk/upgrade@2.0.0
Major Changes
-
Updates the upgrade CLI to support Core 3 changes. If you need to upgrade to an older release, use the previous major version of this package. (#7385) by @brkalow
-
Add support for the latest versions of the following packages: (#6939) by @dstaley
@clerk/react(replacement for@clerk/react)@clerk/expo(replacement for@clerk/expo)@clerk/nextjs@clerk/react-router@clerk/tanstack-start-react
During the upgrade, imports of the
useSignIn()anduseSignUp()hooks will be updated to import from the/legacysubpath. -
Require Node.js 20.9.0 in all packages (#7262) by @jacekradko
-
Add a
transform-protect-to-showcodemod that migrates<Protect>,<SignedIn>,<SignedOut>usages to<Show>with automatic prop and import updates. (#7373) by @jacekradko -
Add a migration guide generator and improve scan output. (#7397) by @brkalow
-
Add
transform-satellite-auto-synccodemod for Core 3 migration that addssatelliteAutoSync: truewhereverisSatelliteis configured (#7653) by @nikosdouvlis -
getToken()now throwsClerkOfflineErrorinstead of returningnullwhen the client is offline. (#7598) by @bratsosThis makes it explicit that a token fetch failure was due to network conditions, not authentication state. Previously, returning
nullcould be misinterpreted as "user is signed out," potentially causing the cached token to be cleared.To handle this change, catch
ClerkOfflineErrorfromgetToken()calls:import { ClerkOfflineError } from '@clerk/react/errors'; try { const token = await session.getToken(); } catch (error) { if (ClerkOfflineError.is(error)) { // Handle offline scenario - show offline UI, retry later, etc. } throw error; }
-
Update
ClerkAPIError.kindvalue to match class name (#7509) by @kduprey -
Add
transform-clerk-provider-inside-bodycodemod for Next.js 16 cache components support (#7596) by @jacekradko
Patch Changes
-
Add missing Core 3 upgrade guide entries for breaking changes:
getTokenSSR behavior, React Router middleware requirement, ExpopublishableKeyrequirement, Astroasprop removal,simpletheme export change, React Routerapi.serverremoval, and Next.js minimum version bump. (#7888) by @jacekradko -
Add back the CLI header with gradient. (#7465) by @jacekradko
-
Update transform-align-experimental-unstable-prefixes to avoid prototype pollution (#7414) by @jacekradko
-
Export
Appearancetype from@clerk/uiroot entry (#7836) by @jacekradko -
Add version check warning when
@tanstack/react-startis below the minimum required v1.157.0 (#7861) by @jacekradko -
Improve CLI usability for monorepos: traverse parent directories for pnpm workspace detection and support named catalogs in version resolution (#7874) by @jacekradko
-
Fix typos in core-3 upgrade guide change files (#7679) by @jacekradko
-
Improve
generate-guidescript to support generating guides for all SDKs at once and output MDX format compatible with clerk-docs (#7454) by @jacekradko -
Fix issue where package.json files were ignored. (#7652) by @dstaley
-
Update README.md (#7413) by @jacekradko
-
Default Ready to upgrade? to yes (#7425) by @jacekradko
-
Remove
@clerk/react-router/api.serverexport (use@clerk/react-router/serverinstead). Added codemod to automatically migrate. (#7643) by @jacekradko -
fix(upgrade): add package replacement for @clerk/themes → @clerk/ui (#7932) by @jacekradko
-
Add entry for Sign-in Client Trust Status (#7446) by @tmilewski
-
Handle
catalog:protocol and other non-standard version specifiers (#7540) by @jacekradko -
Replace
globbydependency withtinyglobbyfor smaller bundle size and faster installation (#7415) by @alexcarpenter -
Add Vue-specific
transform-protect-to-show-vuecodemod that handles.vueSFC files with proper Vue v-bind syntax for the Protect to Show migration. (#7615) by @jacekradko
@clerk/ui@1.0.0
Major Changes
-
Align experimental/unstable prefixes to use consistent naming: (#7361) by @brkalow
- Renamed all
__unstable_*methods to__internal_*(for internal APIs) - Renamed all
experimental__*andexperimental_*methods to__experimental_*(for beta features) - Removed deprecated billing-related props (
__unstable_manageBillingUrl,__unstable_manageBillingLabel,__unstable_manageBillingMembersLimit) andexperimental__forceOauthFirst
- Renamed all
-
Moved
createThemeandsimpleto@clerk/ui/themes/experimentalexport path: (#7925) by @jacekradkoexperimental_createTheme/__experimental_createTheme→createTheme(now exported from@clerk/ui/themes/experimental)experimental__simple/__experimental_simple→simple(now exported from@clerk/ui/themes/experimental)
-
Updates both
colorRingandcolorModalBackdropto render at full opacity when modified via the appearance prop or CSS variables. Previously we'd render the provided color at 15% opacity, which made it difficult to dial in a specific ring or backdrop color. (#7333) by @alexcarpenter -
Remove deprecated
samlAccountin favor ofenterpriseAccount(#7258) by @LauraBeatris -
Hide "Create organization" action when user reaches organization membership limit (#7327) by @LauraBeatris
-
Introducing
@clerk/ui— the UI component package for Clerk. This package provides all prebuilt Clerk components (sign-in, sign-up, user profile, organization management, etc.) and is loaded automatically from the Clerk CDN by@clerk/clerk-js. (#7925) by @jacekradko -
Remove deprecated
hideSlugin favor oforganizationSettings.slug.disabledsetting (#7283) by @LauraBeatrisSlugs can now be enabled directly from the Organization Settings page in the Clerk Dashboard
-
Removes
simpletheme export from UI package in favor of using thesimpletheme via the appearance prop: (#7381) by @alexcarpenter<ClerkProvider appearance={{ theme: 'simple' }} />
-
Remove all previously deprecated UI props across the Next.js, React and clerk-js SDKs. The legacy
afterSign(In|Up)Url/redirectUrlprops,UserButtonsign-out overrides, organizationhideSlugflags,OrganizationSwitcher'safterSwitchOrganizationUrl,Client.activeSessions,setActive({ beforeEmit }), and theClerkMiddlewareAuthObjecttype alias are no longer exported. Components now rely solely on the new redirect options and server-side configuration. (#7243) by @jacekradko -
Renamed
appearance.layouttoappearance.optionsacross all appearance configurations. This is a breaking change - update all instances ofappearance.layouttoappearance.optionsin your codebase. (#7366) by @brkalow -
Remove deprecated
samlstrategy in favor ofenterprise_sso(#7326) by @LauraBeatris -
Changes provider icon rendering from
<Image>to<Span>elements to support customizable icon fills via CSS variables. (#7560) by @alexcarpenterProvider icons for Apple, GitHub, OKX Wallet, and Vercel now use CSS
mask-imagetechnique with a customizable--cl-icon-fillCSS variable, allowing themes to control icon colors. Other provider icons (like Google) continue to render as full-color images usingbackground-image.You can customize the icon fill color in your theme:
import { createTheme } from '@clerk/ui/themes'; const myTheme = createTheme({ name: 'myTheme', elements: { providerIcon__apple: { '--cl-icon-fill': '#000000', // Custom fill color }, providerIcon__github: { '--cl-icon-fill': 'light-dark(#000000, #ffffff)', // Theme-aware fill }, }, });
This change enables better theme customization for monochrome provider icons while maintaining full-color support for providers that require it.
Minor Changes
-
Surface organization creation defaults with prefilled form fields and advisory warnings (#7488) by @LauraBeatris
-
Improve RTL support by converting physical CSS properties (margins, padding, text alignment, borders) to logical equivalents and adding direction-aware arrow icons (#7718) by @alexcarpenter
The changes included:
- Positioning (left → insetInlineStart)
- Margins (marginLeft/Right → marginInlineStart/End)
- Padding (paddingLeft/Right → paddingInlineStart/End)
- Text alignment (left/right → start/end)
- Border radius (borderTopLeftRadius → borderStartStartRadius)
- Arrow icon flipping with scaleX(-1) in RTL
- Animation direction adjustments
-
Don't display impersonation overlay for agents (#7933) by @tmilewski
-
Hide the "Remove" action from the last available 2nd factor strategy when MFA is required (#7729) by @octoper
-
Adds
SignInClientTrustcomponent for discretely handling flows where client trust is required. (#7430) by @tmilewski -
Changed the default value of
appearance.layout.showOptionalFieldsfromtruetofalse. Optional fields are now hidden by default during sign up. Users can still explicitly setshowOptionalFields: trueto show optional fields. (#7365) by @brkalow -
Add legacy browser variant build support for older browsers (#7472) by @jacekradko
-
Disable role selection in
OrganizationProfileduring role set migration (#7534) by @LauraBeatris -
Display message in
TaskChooseOrganizationwhen user is not allowed to create organizations (#7486) by @LauraBeatris -
Add runtime version check in ClerkUi constructor to detect incompatible @clerk/clerk-js versions (#7667) by @bratsos
-
Add Safari ITP (Intelligent Tracking Prevention) cookie refresh support. (#7623) by @nikosdouvlis
Safari's ITP limits cookies set via JavaScript to 7 days. When a session cookie is close to expiring (within 8 days), Clerk now automatically routes navigations through a
/v1/client/touchendpoint to refresh the cookie via a full-page navigation, bypassing the 7-day cap.For developers using a custom
navigatecallback insetActive(), a newdecorateUrlfunction is passed to the callback. Use it to wrap your destination URL:await clerk.setActive({ session: newSession, navigate: ({ decorateUrl }) => { const url = decorateUrl('/dashboard'); window.location.href = url; }, });
The
decorateUrlfunction returns the original URL unchanged when the Safari ITP fix is not needed, so it's safe to always use it. -
Add shared React variant to reduce bundle size when using
@clerk/react. (#7601) by @brkalowIntroduces a new
ui.shared.browser.jsbuild variant that externalizes React dependencies, allowing the host application's React to be reused instead of bundling a separate copy. This can significantly reduce bundle size for applications using@clerk/react.New features:
@clerk/ui/registermodule: Import this to register React onglobalThis.__clerkSharedModulesfor sharing with@clerk/uiclerkUIVariantoption: Set to'shared'to use the shared variant (automatically detected and enabled for compatible React versions in@clerk/react)
For
@clerk/reactusers: No action required. The shared variant is automatically used when your React version is compatible.For custom integrations: Import
@clerk/ui/registerbefore loading the UI bundle, then setclerkUIVariant: 'shared'in your configuration. -
Add
uiprop toClerkProviderfor passing@clerk/ui(#7664) by @jacekradko -
Add
autocomplete="new-password"for password inputs during password creation. (#7948) by @dstaley -
Adds...
@clerk/testing@2.0.0
Major Changes
- Require Node.js 20.9.0 in all packages (#7262) by @jacekradko
Minor Changes
- Export
createAgentTestingTaskhelper for creating agent tasks via the Clerk Backend API from both@clerk/testing/playwrightand@clerk/testing/cypresssubpaths. (#7783) by @tmilewski
Patch Changes
-
Fix
toBeSignedOuttest-helper so it only resolves whenuser === null. It previously resolved for any falsy value, which could give false positives when Clerk had not loaded yet, or during auth-state changes. (#7823) by @Ephem -
Improved keyless selectors. (#7834) by @wobsoriano
-
Updated dependencies [
0a9cce3,e35960f,c9f0d77,1bd1747,6a2ff9e,d2cee35,44d0e5c,6ec5f08,0a9cce3,8c47111,00882e8,a374c18,466d642,5ef4a77,3abe9ed,af85739,10b5bea,a05d130,b193f79,e9d2f2f,6e90b7f,43fc7b7,0f1011a,cbc5618,38def4f,7772f45,a3e689f,583f7a9,965e7f1,84483c2,2b76081,f284c3d,ac34168,cf0d0dc,0aff70e,690280e,b971d0b,22d1689,e9a1d4d,c088dde,8902e21,972f6a0,a1aaff3,d85646a,ab3dd16,4a8cb10,fd195c1,8887fac,0b4b481,5f88dbb,dc886a9,428629b,8b95393,c438fa5,c438fa5,fd195c1,fd69edb,8d91225,1fc95e2,3dac245,a4c3b47,7c3c002,d8bbc66,3983cf8,f1f1d09,736314f,2cc7dbb,0af2e6f,86d2199,da415c8,97c9ab3,cc63aab,a7a38ab,cfa70ce,25d37b0,26254f0,c97e6af,5b24266,d98727e,79e2622,12b3070]:- @clerk/shared@4.0.0
- @clerk/backend@3.0.0
@clerk/tanstack-react-start@1.0.0
Major Changes
-
Require Node.js 20.9.0 in all packages (#7262) by @jacekradko
-
Remove
clerkJSUrl,clerkJSVersion,clerkUIUrl, andclerkUIVersionprops from all SDKs. To pin a specific version of@clerk/clerk-js, import theClerkconstructor from@clerk/clerk-jsand pass it toClerkProvidervia theClerkprop. To pin a specific version of@clerk/ui, importuifrom@clerk/uiand pass it via theuiprop. This bundles the modules directly with your application instead of loading them from the CDN. (#7879) by @jacekradko -
Introduce
<Show when={...}>as the cross-framework authorization control component and remove<Protect>,<SignedIn>, and<SignedOut>in favor of<Show>. (#7373) by @jacekradko -
getToken()now throwsClerkOfflineErrorinstead of returningnullwhen the client is offline. (#7598) by @bratsosThis makes it explicit that a token fetch failure was due to network conditions, not authentication state. Previously, returning
nullcould be misinterpreted as "user is signed out," potentially causing the cached token to be cleared.To handle this change, catch
ClerkOfflineErrorfromgetToken()calls:import { ClerkOfflineError } from '@clerk/react/errors'; try { const token = await session.getToken(); } catch (error) { if (ClerkOfflineError.is(error)) { // Handle offline scenario - show offline UI, retry later, etc. } throw error; }
Minor Changes
-
useAuth().getTokenis no longerundefinedduring server-side rendering, it is a function and calling it will throw. (#7730) by @Ephem- If you are only using
getTokeninuseEffect, event handlers or with non-suspenseful data fetching libraries, no change is necessary as these only trigger on the client. - If you are using suspenseful data fetching libraries that do trigger during SSR, you likely have strategies in place to avoid calling
getTokenalready, since this has never been possible. - If you are using
getToken === undefinedchecks to avoid calling it, know that it will now throw instead and you should catch and handle the error.
async function doThingWithToken(getToken: GetToken) { try { const token = await getToken(); // Use token } catch (error) { if (isClerkRuntimeError(error) && error.code === 'clerk_runtime_not_browser') { // Handle error } } }
To access auth data server-side, see the
Authobject reference doc. - If you are only using
-
Refactor React SDK hooks to subscribe to auth state via
useSyncExternalStore. This is a mostly internal refactor to unlock future improvements, but includes a few breaking changes and fixes. (#7411) by @EphemBreaking changes:
- Removes ability to pass in
initialAuthStatetouseAuth- This was added for internal use and is no longer needed
- Instead pass in
initialStateto the<ClerkProvider>, ordynamicif using the Next package - See your specific SDK documentation for more information on Server Rendering
Fixes:
- A bug where
useAuthwould sometimes briefly return theinitialStaterather thanundefined- This could in certain situations incorrectly lead to a brief
user: nullon the first page after signing in, indicating a signed out state
- This could in certain situations incorrectly lead to a brief
- Hydration mismatches in certain rare scenarios where subtrees would suspend and hydrate only after
clerk-jshad loaded fully
- Removes ability to pass in
-
Remove
clerkJSVariantoption and headless bundle. UseprefetchUI={false}instead. (#7629) by @jacekradko -
Remove all previously deprecated UI props across the Next.js, React and clerk-js SDKs. The legacy
afterSign(In|Up)Url/redirectUrlprops,UserButtonsign-out overrides, organizationhideSlugflags,OrganizationSwitcher'safterSwitchOrganizationUrl,Client.activeSessions,setActive({ beforeEmit }), and theClerkMiddlewareAuthObjecttype alias are no longer exported. Components now rely solely on the new redirect options and server-side configuration. (#7243) by @jacekradko -
Add
satelliteAutoSyncoption to optimize satellite app handshake behavior (#7597) by @nikosdouvlisSatellite apps currently trigger a handshake redirect on every first page load, even when no cookies exist. This creates unnecessary redirects to the primary domain for apps where most users aren't authenticated.
New option:
satelliteAutoSync(default:false)- When
false(default): Skip automatic handshake if no session cookies exist, only trigger after explicit sign-in action - When
true: Satellite apps automatically trigger handshake on first load (previous behavior)
New query parameter:
__clerk_sync__clerk_sync=1(NeedsSync): Triggers handshake after returning from primary sign-in__clerk_sync=2(Completed): Prevents re-sync loop after handshake completes
Backwards compatible: Still reads legacy
__clerk_synced=trueparameter.SSR redirect fix: Server-side redirects (e.g.,
redirectToSignIn()from middleware) now correctly add__clerk_sync=1to the return URL for satellite apps. This ensures the handshake is triggered when the user returns from sign-in on the primary domain.CSR redirect fix: Client-side redirects now add
__clerk_sync=1to all redirect URL variants (forceRedirectUrl,fallbackRedirectUrl) for satellite apps, not just the defaultredirectUrl.Usage
SSR (Next.js Middleware)
import { clerkMiddleware } from '@clerk/nextjs/server'; export default clerkMiddleware({ isSatellite: true, domain: 'satellite.example.com', signInUrl: 'https://primary.example.com/sign-in', // Set to true to automatically sync auth state on first load satelliteAutoSync: true, });
SSR (TanStack Start)
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'; export default clerkMiddleware({ isSatellite: true, domain: 'satellite.example.com', signInUrl: 'https://primary.example.com/sign-in', // Set to true to automatically sync auth state on first load satelliteAutoSync: true, });
CSR (ClerkProvider)
<ClerkProvider publishableKey='pk_...' isSatellite={true} domain='satellite.example.com' signInUrl='https://primary.example.com/sign-in' // Set to true to automatically sync auth state on first load satelliteAutoSync={true} > {children} </ClerkProvider>
SSR (TanStack Start with callback)
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'; // Options callback - receives context object, returns options export default clerkMiddleware(({ url }) => ({ isSatellite: true, domain: 'satellite.example.com', signInUrl: 'https://primary.example.com/sign-in', satelliteAutoSync: url.pathname.startsWith('/dashboard'), }));
Migration Guide
Behavior change:
satelliteAutoSyncdefaults tofalsePreviously, satellite apps would automatically trigger a handshake redirect on every first page load to sync authentication state with the primary domain—even when no session cookies existed. This caused unnecessary redirects to the primary domain for users who weren't authenticated.
The new default (
satelliteAutoSync: false) provides a better experience for end users. Performance-wise, the satellite app can be shown immediately without attempting to sync state first, which is the right behavior for most use cases.To preserve the previous behavior where visiting a satellite while already signed in on the primary domain automatically syncs your session, set
satelliteAutoSync: true:export default clerkMiddleware({ isSatellite: true, domain: 'satellite.example.com', signInUrl: 'https://primary.example.com/sign-in', satelliteAutoSync: true, // Opt-in to automatic sync on first load });
TanStack Start: Function props to options callback
The
clerkMiddlewarefunction no longer accepts individual props as functions. If you were using the function form for props likedomain,proxyUrl, orisSatellite, migrate to the options callback pattern.Before (prop function form - no longer supported):
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'; export default clerkMiddleware({ isSatellite: true, // ❌ Function form for individual props no longer works domain: url => url.hostname, });
After (options callback form):
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'; // ✅ Wrap entire options in a callback function export default cl...
- When
@clerk/react@6.0.0
Major Changes
-
Align experimental/unstable prefixes to use consistent naming: (#7361) by @brkalow
- Renamed all
__unstable_*methods to__internal_*(for internal APIs) - Renamed all
experimental__*andexperimental_*methods to__experimental_*(for beta features) - Removed deprecated billing-related props (
__unstable_manageBillingUrl,__unstable_manageBillingLabel,__unstable_manageBillingMembersLimit) andexperimental__forceOauthFirst
- Renamed all
-
useAuth().getTokenis no longerundefinedduring server-side rendering, it is a function and calling it will throw. (#7730) by @Ephem- If you are only using
getTokeninuseEffect, event handlers or with non-suspenseful data fetching libraries, no change is necessary as these only trigger on the client. - If you are using suspenseful data fetching libraries that do trigger during SSR, you likely have strategies in place to avoid calling
getTokenalready, since this has never been possible. - If you are using
getToken === undefinedchecks to avoid calling it, know that it will now throw instead and you should catch and handle the error.
async function doThingWithToken(getToken: GetToken) { try { const token = await getToken(); // Use token } catch (error) { if (isClerkRuntimeError(error) && error.code === 'clerk_runtime_not_browser') { // Handle error } } }
To access auth data server-side, see the
Authobject reference doc. - If you are only using
-
Updated returned values of
Clerk.checkout()anduseCheckout. (#7232) by @panteliselefVanilla JS
// Before const { getState, subscribe, confirm, start, clear, finalize } = Clerk.checkout({ planId: 'xxx', planPeriod: 'annual', }); getState().isStarting; getState().isConfirming; getState().error; getState().checkout; getState().fetchStatus; getState().status; // After const { checkout, errors, fetchStatus } = Clerk.checkout({ planId: 'xxx', planPeriod: 'annual' }); checkout.plan; // null or defined based on `checkout.status` checkout.status; checkout.start; checkout.confirm;
React
// Before const { id, plan, status, start, confirm, paymentSource } = useCheckout({ planId: 'xxx', planPeriod: 'annual' }); // After const { checkout, errors, fetchStatus } = usecCheckout({ planId: 'xxx', planPeriod: 'annual' }); checkout.plan; // null or defined based on `checkout.status` checkout.status; checkout.start; checkout.confirm;
-
Refactor React SDK hooks to subscribe to auth state via
useSyncExternalStore. This is a mostly internal refactor to unlock future improvements, but includes a few breaking changes and fixes. (#7411) by @EphemBreaking changes:
- Removes ability to pass in
initialAuthStatetouseAuth- This was added for internal use and is no longer needed
- Instead pass in
initialStateto the<ClerkProvider>, ordynamicif using the Next package - See your specific SDK documentation for more information on Server Rendering
Fixes:
- A bug where
useAuthwould sometimes briefly return theinitialStaterather thanundefined- This could in certain situations incorrectly lead to a brief
user: nullon the first page after signing in, indicating a signed out state
- This could in certain situations incorrectly lead to a brief
- Hydration mismatches in certain rare scenarios where subtrees would suspend and hydrate only after
clerk-jshad loaded fully
- Removes ability to pass in
-
Updating minimum version of Node to v20.9.0 (#6936) by @jacekradko
-
Remove all previously deprecated UI props across the Next.js, React and clerk-js SDKs. The legacy
afterSign(In|Up)Url/redirectUrlprops,UserButtonsign-out overrides, organizationhideSlugflags,OrganizationSwitcher'safterSwitchOrganizationUrl,Client.activeSessions,setActive({ beforeEmit }), and theClerkMiddlewareAuthObjecttype alias are no longer exported. Components now rely solely on the new redirect options and server-side configuration. (#7243) by @jacekradko -
Removed legacy subpath export mappings in favor of modern package.json
exportsfield configuration. Previously, these packages used a workaround to support subpath imports (e.g.,@clerk/shared/react,@clerk/expo/web). All public APIs remain available through the main package entry points. (#7925) by @jacekradko -
Introduce
<Show when={...}>as the cross-framework authorization control component and remove<Protect>,<SignedIn>, and<SignedOut>in favor of<Show>. (#7373) by @jacekradko -
getToken()now throwsClerkOfflineErrorinstead of returningnullwhen the client is offline. (#7598) by @bratsosThis makes it explicit that a token fetch failure was due to network conditions, not authentication state. Previously, returning
nullcould be misinterpreted as "user is signed out," potentially causing the cached token to be cleared.To handle this change, catch
ClerkOfflineErrorfromgetToken()calls:import { ClerkOfflineError } from '@clerk/react/errors'; try { const token = await session.getToken(); } catch (error) { if (ClerkOfflineError.is(error)) { // Handle offline scenario - show offline UI, retry later, etc. } throw error; }
Minor Changes
-
Add support for email link based verification to SignUpFuture (#7745) by @dstaley
-
Renames
mountTaskSetupMfaandunmountTaskSetupMfatomountTaskSetupMFAandunmountTaskSetupMFArespectively (#7859) by @octoper -
Add support for email code MFA to SignInFuture (#7594) by @dstaley
-
Add support for resetting a password via phone code. (#7824) by @dstaley
-
Remove
clerkJSVariantoption and headless bundle. UseprefetchUI={false}instead. (#7629) by @jacekradko -
Get transferable state in sign in proxy. (#7941) by @dmoerner
-
Add shared React variant to reduce bundle size when using
@clerk/react. (#7601) by @brkalowIntroduces a new
ui.shared.browser.jsbuild variant that externalizes React dependencies, allowing the host application's React to be reused instead of bundling a separate copy. This can significantly reduce bundle size for applications using@clerk/react.New features:
@clerk/ui/registermodule: Import this to register React onglobalThis.__clerkSharedModulesfor sharing with@clerk/uiclerkUIVariantoption: Set to'shared'to use the shared variant (automatically detected and enabled for compatible React versions in@clerk/react)
For
@clerk/reactusers: No action required. The shared variant is automatically used when your React version is compatible.For custom integrations: Import
@clerk/ui/registerbefore loading the UI bundle, then setclerkUIVariant: 'shared'in your configuration. -
Add
uiprop toClerkProviderfor passing@clerk/ui(#7664) by @jacekradko -
Add standalone
getToken()function for retrieving session tokens outside of framework component trees. (#7325) by @bratsosThis function is safe to call from anywhere in the browser, such as API interceptors, data fetching layers (e.g., React Query, SWR), or vanilla JavaScript code. It automatically waits for Clerk to initialize before returning the token.
import { getToken } from '@clerk/nextjs'; // or any framework package
// Example: Axios interceptor
axios.interceptors.request.use(async (config) => {
const token = await getToken();
if (token) {
config.headers.Authorization =Bearer ${token};
}
return config;
}); -
Export
useOrganizationCreationDefaultshook to fetch suggested organization name and logo from default naming rules (#7694) by @LauraBeatris -
Add
/typessubpath export to re-export types from@clerk/shared/typesalong with SDK-specific types. This allows importing Clerk types directly from the SDK package (e.g., `import type...
@clerk/react-router@3.0.0
Major Changes
-
useAuth().getTokenis no longerundefinedduring server-side rendering, it is a function and calling it will throw. (#7730) by @Ephem- If you are only using
getTokeninuseEffect, event handlers or with non-suspenseful data fetching libraries, no change is necessary as these only trigger on the client. - If you are using suspenseful data fetching libraries that do trigger during SSR, you likely have strategies in place to avoid calling
getTokenalready, since this has never been possible. - If you are using
getToken === undefinedchecks to avoid calling it, know that it will now throw instead and you should catch and handle the error.
async function doThingWithToken(getToken: GetToken) { try { const token = await getToken(); // Use token } catch (error) { if (isClerkRuntimeError(error) && error.code === 'clerk_runtime_not_browser') { // Handle error } } }
To access auth data server-side, see the
Authobject reference doc. - If you are only using
-
Refactor React SDK hooks to subscribe to auth state via
useSyncExternalStore. This is a mostly internal refactor to unlock future improvements, but includes a few breaking changes and fixes. (#7411) by @EphemBreaking changes:
- Removes ability to pass in
initialAuthStatetouseAuth- This was added for internal use and is no longer needed
- Instead pass in
initialStateto the<ClerkProvider>, ordynamicif using the Next package - See your specific SDK documentation for more information on Server Rendering
Fixes:
- A bug where
useAuthwould sometimes briefly return theinitialStaterather thanundefined- This could in certain situations incorrectly lead to a brief
user: nullon the first page after signing in, indicating a signed out state
- This could in certain situations incorrectly lead to a brief
- Hydration mismatches in certain rare scenarios where subtrees would suspend and hydrate only after
clerk-jshad loaded fully
- Removes ability to pass in
-
Usage of
rootAuthLoaderwithout theclerkMiddleware()installed will not throw a runtime error. (#7796) by @wobsorianoBefore (Removed):
import { rootAuthLoader } from '@clerk/react-router/ssr.server'; export const loader = (args: Route.LoaderArgs) => rootAuthLoader(args);
After:
- Enable the
v8_middlewarefuture flag:
// react-router.config.ts export default { future: { v8_middleware: true, }, } satisfies Config;
- Use the middleware in your app:
import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server'; export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()]; export const loader = (args: Route.LoaderArgs) => rootAuthLoader(args);
- Enable the
-
Remove
clerkJSUrl,clerkJSVersion,clerkUIUrl, andclerkUIVersionprops from all SDKs. To pin a specific version of@clerk/clerk-js, import theClerkconstructor from@clerk/clerk-jsand pass it toClerkProvidervia theClerkprop. To pin a specific version of@clerk/ui, importuifrom@clerk/uiand pass it via theuiprop. This bundles the modules directly with your application instead of loading them from the CDN. (#7879) by @jacekradko -
Remove all previously deprecated UI props across the Next.js, React and clerk-js SDKs. The legacy
afterSign(In|Up)Url/redirectUrlprops,UserButtonsign-out overrides, organizationhideSlugflags,OrganizationSwitcher'safterSwitchOrganizationUrl,Client.activeSessions,setActive({ beforeEmit }), and theClerkMiddlewareAuthObjecttype alias are no longer exported. Components now rely solely on the new redirect options and server-side configuration. (#7243) by @jacekradko -
Remove
@clerk/react-router/api.serverexport (use@clerk/react-router/serverinstead). Added codemod to automatically migrate. (#7643) by @jacekradko -
Introduce
<Show when={...}>as the cross-framework authorization control component and remove<Protect>,<SignedIn>, and<SignedOut>in favor of<Show>. (#7373) by @jacekradko -
getToken()now throwsClerkOfflineErrorinstead of returningnullwhen the client is offline. (#7598) by @bratsosThis makes it explicit that a token fetch failure was due to network conditions, not authentication state. Previously, returning
nullcould be misinterpreted as "user is signed out," potentially causing the cached token to be cleared.To handle this change, catch
ClerkOfflineErrorfromgetToken()calls:import { ClerkOfflineError } from '@clerk/react/errors'; try { const token = await session.getToken(); } catch (error) { if (ClerkOfflineError.is(error)) { // Handle offline scenario - show offline UI, retry later, etc. } throw error; }
Minor Changes
-
Introduce Keyless quickstart for React Router. This allows the Clerk SDK to be used without having to sign up and paste your keys manually. (#7794) by @wobsoriano
-
Remove
clerkJSVariantoption and headless bundle. UseprefetchUI={false}instead. (#7629) by @jacekradko -
Add standalone
getToken()function for retrieving session tokens outside of framework component trees. (#7325) by @bratsosThis function is safe to call from anywhere in the browser, such as API interceptors, data fetching layers (e.g., React Query, SWR), or vanilla JavaScript code. It automatically waits for Clerk to initialize before returning the token.
import { getToken } from '@clerk/nextjs'; // or any framework package
// Example: Axios interceptor
axios.interceptors.request.use(async (config) => {
const token = await getToken();
if (token) {
config.headers.Authorization =Bearer ${token};
}
return config;
}); -
Export
useOrganizationCreationDefaultshook to fetch suggested organization name and logo from default naming rules (#7694) by @LauraBeatris -
Add
/typessubpath export to re-export types from@clerk/shared/typesalong with SDK-specific types. This allows importing Clerk types directly from the SDK package (e.g.,import type { UserResource } from '@clerk/react/types') without needing to install@clerk/typesas a separate dependency. (#7644) by @nikosdouvlis -
Introduce
<UNSAFE_PortalProvider>component which allows you to specify a custom container for Clerk floating UI elements (popovers, modals, tooltips, etc.) that use portals. Only Clerk components within the provider will be affected, components outside the provider will continue to use the default document.body for portals. (#7310) by @alexcarpenterThis is particularly useful when using Clerk components inside external UI libraries like Radix Dialog or React Aria Components, where portaled elements need to render within the dialog's container to remain interact-able.
'use client'; import { useRef } from 'react'; import * as Dialog from '@radix-ui/react-dialog'; import { UNSAFE_PortalProvider, UserButton } from '@clerk/nextjs'; export function UserDialog() { const containerRef = useRef<HTMLDivElement>(null); return ( <Dialog.Root> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog.Portal> <Dialog.Overlay /> <Dialog.Content ref={containerRef}> <UNSAFE_PortalProvider getContainer={() => containerRef.current}> <UserButton /> </UNSAFE_PortalProvider> </Dialog.Content> </Dialog.Portal> </Dialog.Root> ); }
Patch Changes
@clerk/nuxt@2.0.0
Major Changes
-
Require Node.js 20.9.0 in all packages (#7262) by @jacekradko
-
Remove
clerkJSUrl,clerkJSVersion,clerkUIUrl, andclerkUIVersionprops from all SDKs. To pin a specific version of@clerk/clerk-js, import theClerkconstructor from@clerk/clerk-jsand pass it toClerkProvidervia theClerkprop. To pin a specific version of@clerk/ui, importuifrom@clerk/uiand pass it via theuiprop. This bundles the modules directly with your application instead of loading them from the CDN. (#7879) by @jacekradko -
Introduce
<Show when={...}>as the cross-framework authorization control component and remove<Protect>,<SignedIn>, and<SignedOut>in favor of<Show>. (#7373) by @jacekradko -
Removed deprecated
getAuth()helper. Useevent.context.auth()in your server routes instead. (#7284) by @wobsorianoexport default defineEventHandler(event => { const { userId } = event.context.auth(); return { userId, }; });
-
getToken()now throwsClerkOfflineErrorinstead of returningnullwhen the client is offline. (#7598) by @bratsosThis makes it explicit that a token fetch failure was due to network conditions, not authentication state. Previously, returning
nullcould be misinterpreted as "user is signed out," potentially causing the cached token to be cleared.To handle this change, catch
ClerkOfflineErrorfromgetToken()calls:import { ClerkOfflineError } from '@clerk/react/errors'; try { const token = await session.getToken(); } catch (error) { if (ClerkOfflineError.is(error)) { // Handle offline scenario - show offline UI, retry later, etc. } throw error; }
-
Routing strategy for the ff. components now default to
path: (#7260) by @wobsoriano<SignIn /><SignUp /><UserProfile /><OrganizationProfile /><CreateOrganization /><OrganizationList />
Minor Changes
-
Remove
clerkJSVariantoption and headless bundle. UseprefetchUI={false}instead. (#7629) by @jacekradko -
Add standalone
getToken()function for retrieving session tokens outside of framework component trees. (#7325) by @bratsosThis function is safe to call from anywhere in the browser, such as API interceptors, data fetching layers (e.g., React Query, SWR), or vanilla JavaScript code. It automatically waits for Clerk to initialize before returning the token.
import { getToken } from '@clerk/nextjs'; // or any framework package
// Example: Axios interceptor
axios.interceptors.request.use(async (config) => {
const token = await getToken();
if (token) {
config.headers.Authorization =Bearer ${token};
}
return config;
}); -
Add
/typessubpath export to re-export types from@clerk/shared/typesalong with SDK-specific types. This allows importing Clerk types directly from the SDK package (e.g.,import type { UserResource } from '@clerk/react/types') without needing to install@clerk/typesas a separate dependency. (#7644) by @nikosdouvlis -
Introduce
<UNSAFE_PortalProvider>component which allows you to specify a custom container for Clerk floating UI elements (popovers, modals, tooltips, etc.) that use portals. Only Clerk components within the provider will be affected, components outside the provider will continue to use the default document.body for portals. (#7310) by @alexcarpenterThis is particularly useful when using Clerk components inside external UI libraries like Radix Dialog or React Aria Components, where portaled elements need to render within the dialog's container to remain interact-able.
'use client'; import { useRef } from 'react'; import * as Dialog from '@radix-ui/react-dialog'; import { UNSAFE_PortalProvider, UserButton } from '@clerk/nextjs'; export function UserDialog() { const containerRef = useRef<HTMLDivElement>(null); return ( <Dialog.Root> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog.Portal> <Dialog.Overlay /> <Dialog.Content ref={containerRef}> <UNSAFE_PortalProvider getContainer={() => containerRef.current}> <UserButton /> </UNSAFE_PortalProvider> </Dialog.Content> </Dialog.Portal> </Dialog.Root> ); }
Patch Changes
-
Wire
clerkUIVersionoption through all framework packages (#7740) by @nikosdouvlis -
Updated dependencies [
0a9cce3,e35960f,c9f0d77,1bd1747,6a2ff9e,d2cee35,44d0e5c,6ec5f08,0a9cce3,8c47111,00882e8,a374c18,466d642,5ef4a77,3abe9ed,af85739,10b5bea,a05d130,b193f79,e9d2f2f,6e90b7f,43fc7b7,0f1011a,cbc5618,38def4f,7772f45,a3e689f,583f7a9,965e7f1,84483c2,2b76081,f284c3d,ac34168,cf0d0dc,0aff70e,690280e,b971d0b,22d1689,e9a1d4d,c088dde,cc3b220,8902e21,972f6a0,a1aaff3, ...