useAccessToken is a client-side React hook that provides access to the user’s JWT access token with automatic refresh capabilities. It handles token expiration, background refreshes, and provides both synchronous and asynchronous access patterns.
Usage
'use client' ;
import { useAccessToken } from '@workos-inc/authkit-nextjs' ;
export function ApiExample () {
const { accessToken , loading , getAccessToken } = useAccessToken ();
const fetchData = async () => {
// Get fresh token for API call
const token = await getAccessToken ();
const response = await fetch ( '/api/data' , {
headers: {
'Authorization' : `Bearer ${ token } `
}
});
return response . json ();
};
return < button onClick = { fetchData } > Fetch Data </ button > ;
}
Return value
The current access token. May be stale when the tab is inactive. Use this for display purposes or where eventual consistency is acceptable. For API calls, prefer getAccessToken(). const { accessToken } = useAccessToken ();
console . log ( 'Current token:' , accessToken );
Indicates whether the initial token fetch is in progress. This is true when the hook first loads and is fetching the token. const { loading } = useAccessToken ();
if ( loading ) {
return < div > Loading authentication... </ div > ;
}
Error from the last token operation, or null if no error occurred. const { error } = useAccessToken ();
if ( error ) {
return < div > Authentication error: { error . message } </ div > ;
}
refresh
() => Promise<string | undefined>
Manually trigger a token refresh. Forces a new token to be fetched regardless of expiration status. const { refresh } = useAccessToken ();
const handleRefresh = async () => {
const newToken = await refresh ();
console . log ( 'Refreshed token:' , newToken );
};
getAccessToken
() => Promise<string | undefined>
Get a guaranteed fresh access token. Automatically refreshes if the current token is expired or about to expire. Use this for API calls where token freshness is critical. Returns a Promise resolving to a fresh token, or undefined if not authenticated. const { getAccessToken } = useAccessToken ();
const callApi = async () => {
try {
const token = await getAccessToken ();
if ( ! token ) {
throw new Error ( 'Not authenticated' );
}
await fetch ( '/api/protected' , {
headers: { 'Authorization' : `Bearer ${ token } ` }
});
} catch ( error ) {
console . error ( 'API call failed:' , error );
}
};
Token refresh behavior
The hook automatically refreshes tokens in the following scenarios:
When the component first mounts, the hook fetches a fresh token if none exists or if the current token is expiring.
When the user or session changes, the hook clears the old token and fetches a new one.
When the browser tab becomes visible or gains focus, the hook checks if the token needs refreshing.
When the browser comes back online after being offline.
When the page is restored from the browser’s back/forward cache.
Examples
Making authenticated API requests
'use client' ;
import { useAccessToken } from '@workos-inc/authkit-nextjs' ;
export function DataFetcher () {
const { getAccessToken , loading } = useAccessToken ();
const [ data , setData ] = useState ( null );
const fetchData = async () => {
const token = await getAccessToken ();
if ( ! token ) return ;
const response = await fetch ( '/api/user-data' , {
headers: {
'Authorization' : `Bearer ${ token } `
}
});
const result = await response . json ();
setData ( result );
};
return (
< div >
< button onClick = { fetchData } disabled = { loading } >
Fetch Data
</ button >
{ data && < pre > { JSON . stringify ( data , null , 2 ) } </ pre > }
</ div >
);
}
Handling token errors
'use client' ;
import { useAccessToken } from '@workos-inc/authkit-nextjs' ;
export function ProtectedContent () {
const { accessToken , loading , error } = useAccessToken ();
if ( loading ) {
return < div > Loading... </ div > ;
}
if ( error ) {
return (
< div >
< p > Failed to get access token: { error . message } </ p >
< button onClick = { () => window . location . reload () } >
Retry
</ button >
</ div >
);
}
if ( ! accessToken ) {
return < div > Please sign in to continue </ div > ;
}
return < div > Protected content </ div > ;
}
Manual token refresh
'use client' ;
import { useAccessToken } from '@workos-inc/authkit-nextjs' ;
export function TokenManager () {
const { accessToken , refresh , loading } = useAccessToken ();
const [ refreshing , setRefreshing ] = useState ( false );
const handleRefresh = async () => {
setRefreshing ( true );
try {
await refresh ();
console . log ( 'Token refreshed successfully' );
} catch ( error ) {
console . error ( 'Failed to refresh token:' , error );
} finally {
setRefreshing ( false );
}
};
return (
< div >
< p > Token: { accessToken ?. substring ( 0 , 20 ) } ... </ p >
< button onClick = { handleRefresh } disabled = { loading || refreshing } >
{ refreshing ? 'Refreshing...' : 'Refresh Token' }
</ button >
</ div >
);
}
Using with custom fetch wrapper
'use client' ;
import { useAccessToken } from '@workos-inc/authkit-nextjs' ;
export function useAuthenticatedFetch () {
const { getAccessToken } = useAccessToken ();
const authFetch = async ( url : string , options : RequestInit = {}) => {
const token = await getAccessToken ();
if ( ! token ) {
throw new Error ( 'Not authenticated' );
}
return fetch ( url , {
... options ,
headers: {
... options . headers ,
'Authorization' : `Bearer ${ token } ` ,
},
});
};
return authFetch ;
}
// Usage
export function MyComponent () {
const authFetch = useAuthenticatedFetch ();
const loadData = async () => {
const response = await authFetch ( '/api/protected' );
return response . json ();
};
return < button onClick = { loadData } > Load Data </ button > ;
}
When to use accessToken vs getAccessToken
Use accessToken For display purposes, logging, or non-critical operations where eventual consistency is acceptable. The token is kept in sync but may be slightly stale during background operations.
Use getAccessToken For API calls, authentication headers, or any operation requiring a guaranteed fresh token. This method ensures the token is valid before returning it.
Important notes
This hook must be used within a component that is a child of AuthKitProvider. It will throw an error if used outside the provider.
The hook automatically clears tokens when the user signs out or the session changes, preventing stale token usage.
For server-side access token needs, use the withAuth function which returns the access token directly.
useAuth Access full authentication context
useTokenClaims Decode and access token claims
withAuth Server-side authentication