From 946c915f01b4a76983927c5139534bcc0cff2791 Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Mon, 9 Mar 2026 18:52:29 +0530 Subject: [PATCH 01/10] feat: add client prop and createAuth0Client factory --- __tests__/auth-provider.test.tsx | 23 ++++++++- __tests__/helpers.tsx | 12 ++--- examples/cra-react-router/src/index.tsx | 4 +- src/auth0-provider.tsx | 67 ++++++++++++++++++++++--- src/index.tsx | 6 ++- 5 files changed, 94 insertions(+), 18 deletions(-) diff --git a/__tests__/auth-provider.test.tsx b/__tests__/auth-provider.test.tsx index ec6163c6..bd934195 100644 --- a/__tests__/auth-provider.test.tsx +++ b/__tests__/auth-provider.test.tsx @@ -7,7 +7,7 @@ import '@testing-library/jest-dom'; import { act, render, renderHook, screen, waitFor } from '@testing-library/react'; import React, { StrictMode, useContext } from 'react'; import pkg from '../package.json'; -import { Auth0Provider, useAuth0 } from '../src'; +import { Auth0Provider, createAuth0Client, useAuth0 } from '../src'; import Auth0Context, { Auth0ContextInterface, initialContext, @@ -134,6 +134,27 @@ describe('Auth0Provider', () => { }); }); + it('should use provided client instance without creating a new one', async () => { + const wrapper = createWrapper({ client: clientMock }); + renderHook(() => useContext(Auth0Context), { wrapper }); + await waitFor(() => { + expect(Auth0Client).not.toHaveBeenCalled(); + expect(clientMock.checkSession).toHaveBeenCalled(); + }); + }); + + it('should inject auth0-react telemetry when using createAuth0Client', async () => { + createAuth0Client({ clientId: 'foo', domain: 'bar' }); + expect(Auth0Client).toHaveBeenCalledWith( + expect.objectContaining({ + auth0Client: { + name: 'auth0-react', + version: pkg.version, + }, + }) + ); + }); + it('should check session when logged out', async () => { const wrapper = createWrapper(); const { result } = renderHook( diff --git a/__tests__/helpers.tsx b/__tests__/helpers.tsx index 821d8547..f081bdd8 100644 --- a/__tests__/helpers.tsx +++ b/__tests__/helpers.tsx @@ -1,16 +1,16 @@ import React, { PropsWithChildren } from 'react'; import Auth0Provider, { Auth0ProviderOptions } from '../src/auth0-provider'; -export const createWrapper = ({ - clientId = '__test_client_id__', - domain = '__test_domain__', - ...opts -}: Partial = {}) => { +export const createWrapper = (opts: Partial = {}) => { + const providerProps = + 'client' in opts && opts.client != null + ? (opts as Auth0ProviderOptions) + : ({ clientId: '__test_client_id__', domain: '__test_domain__', ...opts } as Auth0ProviderOptions); return function Wrapper({ children, }: PropsWithChildren>): React.JSX.Element { return ( - + {children} ); diff --git a/examples/cra-react-router/src/index.tsx b/examples/cra-react-router/src/index.tsx index 3af442b1..0cbe8e9d 100644 --- a/examples/cra-react-router/src/index.tsx +++ b/examples/cra-react-router/src/index.tsx @@ -3,13 +3,13 @@ import React, { PropsWithChildren } from 'react'; import App from './App'; import { Auth0Provider, AppState, Auth0ContextInterface, User } from '@auth0/auth0-react'; import { BrowserRouter, useNavigate } from 'react-router-dom'; -import { Auth0ProviderOptions } from '../../../src/index.js'; +import { Auth0ProviderWithConfigOptions } from '../../../src/index.js'; const Auth0ProviderWithRedirectCallback = ({ children, context, ...props -}: PropsWithChildren> & { +}: PropsWithChildren> & { context?: React.Context> }) => { const navigate = useNavigate(); diff --git a/src/auth0-provider.tsx b/src/auth0-provider.tsx index 7d49d317..49a3ca55 100644 --- a/src/auth0-provider.tsx +++ b/src/auth0-provider.tsx @@ -51,10 +51,7 @@ export type AppState = { [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any }; -/** - * The main configuration to instantiate the `Auth0Provider`. - */ -export interface Auth0ProviderOptions extends Auth0ClientOptions { +type Auth0ProviderBaseOptions = { /** * The child nodes your Provider has wrapped */ @@ -97,7 +94,31 @@ export interface Auth0ProviderOptions extends Auth0Cl * For a sample on using multiple Auth0Providers review the [React Account Linking Sample](https://github.com/auth0-samples/auth0-link-accounts-sample/tree/react-variant) */ context?: React.Context>; -} +}; + +/** + * Options for `Auth0Provider` when configuring Auth0 via `domain` and `clientId`. + * Use this type when building wrapper components around `Auth0Provider`. + */ +export type Auth0ProviderWithConfigOptions = + Auth0ProviderBaseOptions & Auth0ClientOptions & { client?: never }; + +/** + * Options for `Auth0Provider` when supplying a pre-configured `Auth0Client` instance. + * Use `createAuth0Client` to create the client so telemetry is set correctly. + */ +export type Auth0ProviderWithClientOptions = + Auth0ProviderBaseOptions & Partial & { client: Auth0Client }; + +/** + * The main configuration to instantiate the `Auth0Provider`. + * + * Either provide `domain` and `clientId` (`Auth0ProviderWithConfigOptions`) + * or a pre-configured `client` instance (`Auth0ProviderWithClientOptions`). + */ +export type Auth0ProviderOptions = + | Auth0ProviderWithConfigOptions + | Auth0ProviderWithClientOptions; /** * Replaced by the package version at build time. @@ -109,7 +130,7 @@ declare const __VERSION__: string; * @ignore */ const toAuth0ClientOptions = ( - opts: Auth0ProviderOptions + opts: Auth0ClientOptions ): Auth0ClientOptions => { deprecateRedirectUri(opts); @@ -122,6 +143,35 @@ const toAuth0ClientOptions = ( }; }; +/** + * Creates a new `Auth0Client` with the `auth0-react` SDK telemetry header set. + * + * Use this when you need to share a single client instance with `Auth0Provider` + * and also access Auth0 outside of React (e.g. in middleware or interceptors). + * + * @example + * ```tsx + * const client = createAuth0Client({ domain, clientId }); + * + * // Use outside React (e.g. in TanStack middleware, axios interceptors, Redux middleware) + * const token = await client.getTokenSilently(); + * + * // Use inside React + * function App() { + * return ; + * } + * ``` + */ +export const createAuth0Client = (options: Auth0ClientOptions): Auth0Client => { + return new Auth0Client({ + ...options, + auth0Client: { + name: 'auth0-react', + version: __VERSION__, + }, + }); +}; + /** * @ignore */ @@ -151,10 +201,11 @@ const Auth0Provider = (opts: Auth0ProviderOptions & Auth0ClientOptions & { client?: Auth0Client }; const [client] = useState( - () => new Auth0Client(toAuth0ClientOptions(clientOpts)) + () => providedClient ?? new Auth0Client(toAuth0ClientOptions(clientOpts)) ); const [state, dispatch] = useReducer(reducer, initialAuthState as AuthState); const didInitialise = useRef(false); diff --git a/src/index.tsx b/src/index.tsx index 4db5b72e..9e942255 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,8 +1,11 @@ export { default as Auth0Provider, Auth0ProviderOptions, + Auth0ProviderWithConfigOptions, + Auth0ProviderWithClientOptions, AppState, - ConnectedAccount + ConnectedAccount, + createAuth0Client, } from './auth0-provider'; export { default as useAuth0 } from './use-auth0'; export { default as withAuth0, WithAuth0Props } from './with-auth0'; @@ -18,6 +21,7 @@ export { RedirectLoginOptions, } from './auth0-context'; export { + Auth0Client, AuthorizationParams, PopupLoginOptions, PopupConfigOptions, From 4f96be5b9434f9d184dd459f48ac147d59a15161 Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Tue, 10 Mar 2026 08:19:37 +0530 Subject: [PATCH 02/10] fix: remove Partial from Auth0ProviderWithClientOptions --- src/auth0-provider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth0-provider.tsx b/src/auth0-provider.tsx index 49a3ca55..42351c12 100644 --- a/src/auth0-provider.tsx +++ b/src/auth0-provider.tsx @@ -108,7 +108,7 @@ export type Auth0ProviderWithConfigOptions = * Use `createAuth0Client` to create the client so telemetry is set correctly. */ export type Auth0ProviderWithClientOptions = - Auth0ProviderBaseOptions & Partial & { client: Auth0Client }; + Auth0ProviderBaseOptions & { client: Auth0Client }; /** * The main configuration to instantiate the `Auth0Provider`. From c6bc6a24056c5984c366e35162ba415482b8f698 Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Tue, 10 Mar 2026 14:41:06 +0530 Subject: [PATCH 03/10] docs: add example for using Auth0 outside of React --- EXAMPLES.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 3c407f9d..c20191d2 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -102,6 +102,64 @@ const Posts = () => { export default Posts; ``` +## Use Auth0 outside of React + +If you need to access the `Auth0Client` outside of the React tree — for example in middleware, axios interceptors, or TanStack Router loaders — use `createAuth0Client` to create a shared instance and pass it to `Auth0Provider` via the `client` prop. + +Using `createAuth0Client` ensures the `auth0-react` telemetry header is set correctly on the client. + +```jsx +// auth0-client.js +import { createAuth0Client } from '@auth0/auth0-react'; + +export const auth0Client = createAuth0Client({ + domain: 'YOUR_AUTH0_DOMAIN', + clientId: 'YOUR_AUTH0_CLIENT_ID', + authorizationParams: { + redirect_uri: window.location.origin, + }, +}); +``` + +Pass the client to `Auth0Provider`: + +```jsx +import { Auth0Provider } from '@auth0/auth0-react'; +import { auth0Client } from './auth0-client'; + +export default function App() { + return ( + + + + ); +} +``` + +Use the same client instance directly outside React, for example in an axios interceptor: + +```js +import axios from 'axios'; +import { auth0Client } from './auth0-client'; + +axios.interceptors.request.use(async (config) => { + const token = await auth0Client.getTokenSilently(); + config.headers.Authorization = `Bearer ${token}`; + return config; +}); +``` + +Or in a TanStack Router middleware: + +```js +import { auth0Client } from './auth0-client'; + +export const authMiddleware = createMiddleware().server(async ({ next }) => { + const token = await auth0Client.getTokenSilently(); + return next({ context: { token } }); +}); +``` + ## Custom token exchange Exchange an external subject token for Auth0 tokens using the token exchange flow (RFC 8693): From 82aa2a3be3b34cf224b7ca89e966b044d752aceb Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Fri, 13 Mar 2026 11:21:59 +0530 Subject: [PATCH 04/10] docs: update outside-React example to use Redux middleware --- EXAMPLES.md | 29 +++++++++++------------------ src/auth0-provider.tsx | 12 +++--------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index c20191d2..e55592c6 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3,6 +3,7 @@ - [Use with a Class Component](#use-with-a-class-component) - [Protect a Route](#protect-a-route) - [Call an API](#call-an-api) +- [Use Auth0 outside of React](#use-auth0-outside-of-react) - [Protecting a route in a `react-router-dom v6` app](#protecting-a-route-in-a-react-router-dom-v6-app) - [Protecting a route in a Gatsby app](#protecting-a-route-in-a-gatsby-app) - [Protecting a route in a Next.js app (in SPA mode)](#protecting-a-route-in-a-nextjs-app-in-spa-mode) @@ -104,7 +105,7 @@ export default Posts; ## Use Auth0 outside of React -If you need to access the `Auth0Client` outside of the React tree — for example in middleware, axios interceptors, or TanStack Router loaders — use `createAuth0Client` to create a shared instance and pass it to `Auth0Provider` via the `client` prop. +If you need to share an `Auth0Client` instance between the React tree and code that has no access to React's lifecycle — such as Redux middleware — use `createAuth0Client` to create a shared instance and pass it to `Auth0Provider` via the `client` prop. Using `createAuth0Client` ensures the `auth0-react` telemetry header is set correctly on the client. @@ -136,29 +137,21 @@ export default function App() { } ``` -Use the same client instance directly outside React, for example in an axios interceptor: +Use the same client instance in Redux middleware: ```js -import axios from 'axios'; import { auth0Client } from './auth0-client'; -axios.interceptors.request.use(async (config) => { - const token = await auth0Client.getTokenSilently(); - config.headers.Authorization = `Bearer ${token}`; - return config; -}); +export const authMiddleware = store => next => async action => { + if (action.requiresAuth) { + const token = await auth0Client.getTokenSilently(); + return next({ ...action, token }); + } + return next(action); +}; ``` -Or in a TanStack Router middleware: - -```js -import { auth0Client } from './auth0-client'; - -export const authMiddleware = createMiddleware().server(async ({ next }) => { - const token = await auth0Client.getTokenSilently(); - return next({ context: { token } }); -}); -``` +> **Note:** `getTokenSilently()` requires an active session. Ensure `Auth0Provider` has mounted and completed initialization before calling it outside React. ## Custom token exchange diff --git a/src/auth0-provider.tsx b/src/auth0-provider.tsx index 42351c12..96a6b33c 100644 --- a/src/auth0-provider.tsx +++ b/src/auth0-provider.tsx @@ -147,13 +147,13 @@ const toAuth0ClientOptions = ( * Creates a new `Auth0Client` with the `auth0-react` SDK telemetry header set. * * Use this when you need to share a single client instance with `Auth0Provider` - * and also access Auth0 outside of React (e.g. in middleware or interceptors). + * and also access Auth0 outside of React (e.g. in Redux middleware). * * @example * ```tsx * const client = createAuth0Client({ domain, clientId }); * - * // Use outside React (e.g. in TanStack middleware, axios interceptors, Redux middleware) + * // Use outside React (e.g. in Redux middleware) * const token = await client.getTokenSilently(); * * // Use inside React @@ -163,13 +163,7 @@ const toAuth0ClientOptions = ( * ``` */ export const createAuth0Client = (options: Auth0ClientOptions): Auth0Client => { - return new Auth0Client({ - ...options, - auth0Client: { - name: 'auth0-react', - version: __VERSION__, - }, - }); + return new Auth0Client(toAuth0ClientOptions(options)); }; /** From bef507a7a48ccf4bde0c16f7b4c5e3f7eb43712f Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Fri, 13 Mar 2026 11:39:25 +0530 Subject: [PATCH 05/10] docs: use TanStack Start client middleware as outside-React example --- EXAMPLES.md | 24 ++++++++++++++---------- src/auth0-provider.tsx | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index e55592c6..699b7471 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -105,7 +105,7 @@ export default Posts; ## Use Auth0 outside of React -If you need to share an `Auth0Client` instance between the React tree and code that has no access to React's lifecycle — such as Redux middleware — use `createAuth0Client` to create a shared instance and pass it to `Auth0Provider` via the `client` prop. +If you need to share an `Auth0Client` instance between the React tree and code that has no access to React's lifecycle — such as TanStack Start client function middleware — use `createAuth0Client` to create a shared instance and pass it to `Auth0Provider` via the `client` prop. Using `createAuth0Client` ensures the `auth0-react` telemetry header is set correctly on the client. @@ -137,22 +137,26 @@ export default function App() { } ``` -Use the same client instance in Redux middleware: +> **Note:** `getTokenSilently()` requires an active session. Ensure `Auth0Provider` has mounted and completed initialization before calling it outside React. + +Use the same client instance in a TanStack Start client function middleware: ```js +import { createMiddleware } from '@tanstack/react-start'; import { auth0Client } from './auth0-client'; -export const authMiddleware = store => next => async action => { - if (action.requiresAuth) { +export const authMiddleware = createMiddleware({ type: 'function' }).client( + async ({ next }) => { const token = await auth0Client.getTokenSilently(); - return next({ ...action, token }); - } - return next(action); -}; + return next({ + headers: { + Authorization: `Bearer ${token}`, + }, + }); + }, +); ``` -> **Note:** `getTokenSilently()` requires an active session. Ensure `Auth0Provider` has mounted and completed initialization before calling it outside React. - ## Custom token exchange Exchange an external subject token for Auth0 tokens using the token exchange flow (RFC 8693): diff --git a/src/auth0-provider.tsx b/src/auth0-provider.tsx index 96a6b33c..80272418 100644 --- a/src/auth0-provider.tsx +++ b/src/auth0-provider.tsx @@ -147,13 +147,13 @@ const toAuth0ClientOptions = ( * Creates a new `Auth0Client` with the `auth0-react` SDK telemetry header set. * * Use this when you need to share a single client instance with `Auth0Provider` - * and also access Auth0 outside of React (e.g. in Redux middleware). + * and also access Auth0 outside of React (e.g. in TanStack Start client function middleware). * * @example * ```tsx * const client = createAuth0Client({ domain, clientId }); * - * // Use outside React (e.g. in Redux middleware) + * // Use outside React (e.g. in TanStack Start client function middleware) * const token = await client.getTokenSilently(); * * // Use inside React From 615515a0413abd7911dbdb2f3ea4852b071aa843 Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Thu, 19 Mar 2026 09:03:52 +0530 Subject: [PATCH 06/10] fix: warn when client prop is used with domain/clientId --- __tests__/auth-provider.test.tsx | 25 +++++++++++++++++++++++++ src/auth0-provider.tsx | 7 +++++++ 2 files changed, 32 insertions(+) diff --git a/__tests__/auth-provider.test.tsx b/__tests__/auth-provider.test.tsx index bd934195..e6842b94 100644 --- a/__tests__/auth-provider.test.tsx +++ b/__tests__/auth-provider.test.tsx @@ -155,6 +155,31 @@ describe('Auth0Provider', () => { ); }); + it('should warn when client prop is used alongside domain or clientId', async () => { + const warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + const wrapper = createWrapper({ client: clientMock, domain: 'foo', clientId: 'bar' } as any); + renderHook(() => useContext(Auth0Context), { wrapper }); + await waitFor(() => { + expect(warn).toHaveBeenCalledWith( + expect.stringContaining('the `client` prop takes precedence') + ); + }); + warn.mockRestore(); + }); + + it('should not warn when only client prop is provided', async () => { + const warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + const wrapper = createWrapper({ client: clientMock }); + renderHook(() => useContext(Auth0Context), { wrapper }); + await waitFor(() => { + expect(clientMock.checkSession).toHaveBeenCalled(); + }); + expect(warn).not.toHaveBeenCalledWith( + expect.stringContaining('the `client` prop takes precedence') + ); + warn.mockRestore(); + }); + it('should check session when logged out', async () => { const wrapper = createWrapper(); const { result } = renderHook( diff --git a/src/auth0-provider.tsx b/src/auth0-provider.tsx index 80272418..8f45aa76 100644 --- a/src/auth0-provider.tsx +++ b/src/auth0-provider.tsx @@ -198,6 +198,13 @@ const Auth0Provider = (opts: Auth0ProviderOptions & Auth0ClientOptions & { client?: Auth0Client }; + if (providedClient && (clientOpts.domain || clientOpts.clientId)) { + console.warn( + 'Auth0Provider: the `client` prop takes precedence over `domain`/`clientId` and other ' + + 'configuration options. Remove `domain`, `clientId`, and any other Auth0Client configuration ' + + 'props when using the `client` prop.' + ); + } const [client] = useState( () => providedClient ?? new Auth0Client(toAuth0ClientOptions(clientOpts)) ); From 81f8108378b6fd8a8cd6e966b7084a68373920bd Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Thu, 19 Mar 2026 09:19:35 +0530 Subject: [PATCH 07/10] docs: clarify raw client API differences and state sync behaviour --- EXAMPLES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 699b7471..f5e23ce1 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -137,7 +137,9 @@ export default function App() { } ``` -> **Note:** `getTokenSilently()` requires an active session. Ensure `Auth0Provider` has mounted and completed initialization before calling it outside React. +> **Note:** +> - The raw `Auth0Client` method is `getTokenSilently()`, not `getAccessTokenSilently()`. They share the same token cache but the hook version also updates React state. +> - Calling methods on the raw client does not update React state. For token fetching this is fine since the cache is shared. Avoid calling `client.logout()` directly — use the `logout` method from `useAuth0` instead so React state stays in sync. Use the same client instance in a TanStack Start client function middleware: From 7d331914e787fca27961f98206e070f2a1b8f13d Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Thu, 19 Mar 2026 09:36:07 +0530 Subject: [PATCH 08/10] fix: replace as any with unknown cast to satisfy no-explicit-any lint rule --- __tests__/auth-provider.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__tests__/auth-provider.test.tsx b/__tests__/auth-provider.test.tsx index e6842b94..39b76426 100644 --- a/__tests__/auth-provider.test.tsx +++ b/__tests__/auth-provider.test.tsx @@ -7,7 +7,7 @@ import '@testing-library/jest-dom'; import { act, render, renderHook, screen, waitFor } from '@testing-library/react'; import React, { StrictMode, useContext } from 'react'; import pkg from '../package.json'; -import { Auth0Provider, createAuth0Client, useAuth0 } from '../src'; +import { Auth0Provider, Auth0ProviderOptions, createAuth0Client, useAuth0 } from '../src'; import Auth0Context, { Auth0ContextInterface, initialContext, @@ -157,7 +157,7 @@ describe('Auth0Provider', () => { it('should warn when client prop is used alongside domain or clientId', async () => { const warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined); - const wrapper = createWrapper({ client: clientMock, domain: 'foo', clientId: 'bar' } as any); + const wrapper = createWrapper({ client: clientMock, domain: 'foo', clientId: 'bar' } as unknown as Partial); renderHook(() => useContext(Auth0Context), { wrapper }); await waitFor(() => { expect(warn).toHaveBeenCalledWith( From 4889dcefc7f01aec32c6550dfb8047e257030b19 Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Fri, 20 Mar 2026 17:28:37 +0530 Subject: [PATCH 09/10] feat: remove createAuth0Client, keep client prop only --- EXAMPLES.md | 8 +++----- __tests__/auth-provider.test.tsx | 14 +------------- src/auth0-provider.tsx | 24 ------------------------ src/index.tsx | 1 - 4 files changed, 4 insertions(+), 43 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index f5e23ce1..a673045b 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -105,15 +105,13 @@ export default Posts; ## Use Auth0 outside of React -If you need to share an `Auth0Client` instance between the React tree and code that has no access to React's lifecycle — such as TanStack Start client function middleware — use `createAuth0Client` to create a shared instance and pass it to `Auth0Provider` via the `client` prop. - -Using `createAuth0Client` ensures the `auth0-react` telemetry header is set correctly on the client. +If you need to share an `Auth0Client` instance between the React tree and code that has no access to React's lifecycle — such as TanStack Start client function middleware — create an `Auth0Client` and pass it to `Auth0Provider` via the `client` prop. ```jsx // auth0-client.js -import { createAuth0Client } from '@auth0/auth0-react'; +import { Auth0Client } from '@auth0/auth0-react'; -export const auth0Client = createAuth0Client({ +export const auth0Client = new Auth0Client({ domain: 'YOUR_AUTH0_DOMAIN', clientId: 'YOUR_AUTH0_CLIENT_ID', authorizationParams: { diff --git a/__tests__/auth-provider.test.tsx b/__tests__/auth-provider.test.tsx index 39b76426..3453f858 100644 --- a/__tests__/auth-provider.test.tsx +++ b/__tests__/auth-provider.test.tsx @@ -7,7 +7,7 @@ import '@testing-library/jest-dom'; import { act, render, renderHook, screen, waitFor } from '@testing-library/react'; import React, { StrictMode, useContext } from 'react'; import pkg from '../package.json'; -import { Auth0Provider, Auth0ProviderOptions, createAuth0Client, useAuth0 } from '../src'; +import { Auth0Provider, Auth0ProviderOptions, useAuth0 } from '../src'; import Auth0Context, { Auth0ContextInterface, initialContext, @@ -143,18 +143,6 @@ describe('Auth0Provider', () => { }); }); - it('should inject auth0-react telemetry when using createAuth0Client', async () => { - createAuth0Client({ clientId: 'foo', domain: 'bar' }); - expect(Auth0Client).toHaveBeenCalledWith( - expect.objectContaining({ - auth0Client: { - name: 'auth0-react', - version: pkg.version, - }, - }) - ); - }); - it('should warn when client prop is used alongside domain or clientId', async () => { const warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined); const wrapper = createWrapper({ client: clientMock, domain: 'foo', clientId: 'bar' } as unknown as Partial); diff --git a/src/auth0-provider.tsx b/src/auth0-provider.tsx index 8f45aa76..c7077d55 100644 --- a/src/auth0-provider.tsx +++ b/src/auth0-provider.tsx @@ -105,7 +105,6 @@ export type Auth0ProviderWithConfigOptions = /** * Options for `Auth0Provider` when supplying a pre-configured `Auth0Client` instance. - * Use `createAuth0Client` to create the client so telemetry is set correctly. */ export type Auth0ProviderWithClientOptions = Auth0ProviderBaseOptions & { client: Auth0Client }; @@ -143,29 +142,6 @@ const toAuth0ClientOptions = ( }; }; -/** - * Creates a new `Auth0Client` with the `auth0-react` SDK telemetry header set. - * - * Use this when you need to share a single client instance with `Auth0Provider` - * and also access Auth0 outside of React (e.g. in TanStack Start client function middleware). - * - * @example - * ```tsx - * const client = createAuth0Client({ domain, clientId }); - * - * // Use outside React (e.g. in TanStack Start client function middleware) - * const token = await client.getTokenSilently(); - * - * // Use inside React - * function App() { - * return ; - * } - * ``` - */ -export const createAuth0Client = (options: Auth0ClientOptions): Auth0Client => { - return new Auth0Client(toAuth0ClientOptions(options)); -}; - /** * @ignore */ diff --git a/src/index.tsx b/src/index.tsx index 9e942255..37798f95 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,7 +5,6 @@ export { Auth0ProviderWithClientOptions, AppState, ConnectedAccount, - createAuth0Client, } from './auth0-provider'; export { default as useAuth0 } from './use-auth0'; export { default as withAuth0, WithAuth0Props } from './with-auth0'; From 720730668625543435bf37be7d7a215e986309bf Mon Sep 17 00:00:00 2001 From: Yogesh Chaudhary Date: Fri, 20 Mar 2026 17:51:22 +0530 Subject: [PATCH 10/10] fix: remove Auth0Client export from auth0-react --- EXAMPLES.md | 2 +- src/index.tsx | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index a673045b..38fbdb90 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -109,7 +109,7 @@ If you need to share an `Auth0Client` instance between the React tree and code t ```jsx // auth0-client.js -import { Auth0Client } from '@auth0/auth0-react'; +import { Auth0Client } from '@auth0/auth0-spa-js'; export const auth0Client = new Auth0Client({ domain: 'YOUR_AUTH0_DOMAIN', diff --git a/src/index.tsx b/src/index.tsx index 37798f95..2c635503 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ export { Auth0ProviderWithConfigOptions, Auth0ProviderWithClientOptions, AppState, - ConnectedAccount, + ConnectedAccount } from './auth0-provider'; export { default as useAuth0 } from './use-auth0'; export { default as withAuth0, WithAuth0Props } from './with-auth0'; @@ -20,7 +20,6 @@ export { RedirectLoginOptions, } from './auth0-context'; export { - Auth0Client, AuthorizationParams, PopupLoginOptions, PopupConfigOptions,