The getAccessToken function retrieves an access token for the currently authenticated user from client components. It automatically handles token refresh if the token has expired.
Import
import { getAccessToken } from '@auth0/nextjs-auth0';
This function can only be called from client components or browser environments.
Signature
function getAccessToken(options?: AccessTokenOptions): Promise<string>;
function getAccessToken(
options: AccessTokenOptions & { includeFullResponse: true }
): Promise<AccessTokenResponse>;
Parameters
Configuration options for fetching the access token.The unique identifier of the target API. Required when calling multiple APIs with different audiences.When using audience or scope, ensure Multi-Resource Refresh Tokens (MRRT) is configured in your Auth0 Application settings.
Additional scopes to request beyond those granted during login.Example: 'read:profile write:profile'
options.includeFullResponse
When true, returns the full response object instead of just the access token string.
Return Value
Default Return (string)
By default, returns the access token as a string:
const token: string = await getAccessToken();
Full Response Return
When includeFullResponse: true, returns an object with:
The scopes granted for this token.
Unix timestamp (in seconds) when the token expires.
Number of seconds until the token expires.
Token type (typically "Bearer").
Basic Usage
app/components/api-caller.tsx
"use client";
import { getAccessToken } from '@auth0/nextjs-auth0';
export default function ApiCaller() {
async function fetchData() {
try {
const token = await getAccessToken();
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${token}`
}
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Failed to fetch data:', error);
}
}
return <button onClick={fetchData}>Fetch Data</button>;
}
Full Response Usage
"use client";
import { getAccessToken } from '@auth0/nextjs-auth0';
export default function TokenInfo() {
async function showTokenInfo() {
try {
const tokenSet = await getAccessToken({
includeFullResponse: true
});
console.log('Token:', tokenSet.token);
console.log('Expires in:', tokenSet.expires_in, 'seconds');
console.log('Expires at:', new Date(tokenSet.expires_at! * 1000));
console.log('Scopes:', tokenSet.scope);
} catch (error) {
console.error('Failed to get token:', error);
}
}
return <button onClick={showTokenInfo}>Show Token Info</button>;
}
Multi-Resource Refresh Tokens (MRRT)
When your application calls multiple APIs with different audiences, you must specify the audience parameter:
"use client";
import { getAccessToken } from '@auth0/nextjs-auth0';
export default function MultiApiCaller() {
async function fetchFromMultipleApis() {
try {
// Get token for profile API
const profileToken = await getAccessToken({
audience: 'https://profile-api.example.com'
});
// Get token for orders API
const ordersToken = await getAccessToken({
audience: 'https://orders-api.example.com'
});
// Call both APIs with their respective tokens
const [profileData, ordersData] = await Promise.all([
fetch('https://profile-api.example.com/me', {
headers: { Authorization: `Bearer ${profileToken}` }
}).then(r => r.json()),
fetch('https://orders-api.example.com/orders', {
headers: { Authorization: `Bearer ${ordersToken}` }
}).then(r => r.json())
]);
console.log({ profileData, ordersData });
} catch (error) {
console.error('Failed to fetch:', error);
}
}
return <button onClick={fetchFromMultipleApis}>Fetch All Data</button>;
}
When using MRRT, ensure the audiences and scopes are configured in your Auth0 Application’s Refresh Token Policies. See the Auth0 MRRT documentation for setup instructions.
Custom Scopes
"use client";
import { getAccessToken } from '@auth0/nextjs-auth0';
export default function AdminActions() {
async function performAdminAction() {
try {
const token = await getAccessToken({
audience: 'https://api.example.com',
scope: 'read:users write:users delete:users'
});
const response = await fetch('https://api.example.com/admin/users', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'create_user' })
});
const result = await response.json();
console.log(result);
} catch (error) {
console.error('Admin action failed:', error);
}
}
return <button onClick={performAdminAction}>Create User</button>;
}
Error Handling
"use client";
import { getAccessToken } from '@auth0/nextjs-auth0';
import { AccessTokenError } from '@auth0/nextjs-auth0/errors';
export default function SecureDataFetcher() {
async function fetchSecureData() {
try {
const token = await getAccessToken();
const response = await fetch('https://api.example.com/secure', {
headers: { Authorization: `Bearer ${token}` }
});
if (!response.ok) {
throw new Error('API request failed');
}
const data = await response.json();
console.log(data);
} catch (error) {
if (error instanceof AccessTokenError) {
console.error('Token error:', error.code, error.message);
// Redirect to login
window.location.href = '/auth/login';
} else {
console.error('Fetch error:', error);
}
}
}
return <button onClick={fetchSecureData}>Fetch Secure Data</button>;
}
Token Caching
For client-side token caching to avoid redundant requests:
"use client";
import { getAccessToken } from '@auth0/nextjs-auth0';
import { useState, useEffect } from 'react';
export default function CachedTokenFetcher() {
const [tokenCache, setTokenCache] = useState<{
token: string;
expiresAt: number;
} | null>(null);
async function getToken() {
// Check if cached token is still valid
if (tokenCache && tokenCache.expiresAt > Date.now() / 1000 + 60) {
return tokenCache.token;
}
// Fetch new token
const tokenSet = await getAccessToken({ includeFullResponse: true });
// Cache the token
setTokenCache({
token: tokenSet.token,
expiresAt: tokenSet.expires_at!
});
return tokenSet.token;
}
async function fetchData() {
const token = await getToken();
const response = await fetch('https://api.example.com/data', {
headers: { Authorization: `Bearer ${token}` }
});
const data = await response.json();
console.log(data);
}
return <button onClick={fetchData}>Fetch Data</button>;
}
API Route
The client-side getAccessToken function makes a request to /auth/access-token (configurable via NEXT_PUBLIC_ACCESS_TOKEN_ROUTE).
The SDK automatically provides this route handler, but you can customize it:
app/api/auth/access-token/route.ts
import { auth0 } from '@/lib/auth0';
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
const session = await auth0.getSession();
if (!session) {
return NextResponse.json(
{ error: { code: 'unauthorized', message: 'Not authenticated' } },
{ status: 401 }
);
}
const searchParams = req.nextUrl.searchParams;
const audience = searchParams.get('audience') || undefined;
const scope = searchParams.get('scope') || undefined;
try {
const { token, expiresAt, scope: grantedScope } = await auth0.getAccessToken({
audience,
scope
});
return NextResponse.json({
token,
expires_at: expiresAt,
scope: grantedScope,
token_type: 'Bearer'
});
} catch (error) {
return NextResponse.json(
{ error: { code: 'access_token_error', message: error.message } },
{ status: 500 }
);
}
}
TypeScript
import { getAccessToken } from '@auth0/nextjs-auth0';
import type { AccessTokenOptions } from '@auth0/nextjs-auth0';
const options: AccessTokenOptions = {
audience: 'https://api.example.com',
scope: 'read:data'
};
// String return type
const token: string = await getAccessToken(options);
// Full response return type
const tokenSet = await getAccessToken({
...options,
includeFullResponse: true
});
console.log(tokenSet.token); // string
console.log(tokenSet.expires_in); // number | undefined
Custom Environment Variables
# Default: /auth/access-token
NEXT_PUBLIC_ACCESS_TOKEN_ROUTE=/api/auth/access-token
See Also