Detailed explanation of the two session token types in WPGraphQL for WooCommerce: Legacy and Store-API tokens.
WPGraphQL for WooCommerce supports two different session token systems. Understanding when to use each is critical for building reliable headless WooCommerce applications.
| Token Type | Source | GraphQL Field | HTTP Header | WooCommerce Blocks Support |
|---|---|---|---|---|
| Legacy | QL_Session_Handler | Customer.sessionToken | woocommerce-session | Partial |
| Store-API | CartTokenUtils | Customer.cartToken | Cart-Token | Full |
The Store-API cart token is created by WooCommerce's native CartTokenUtils class, originally designed for the WooCommerce Store API. This is the recommended token type for all new projects.
CartTokenUtilsCustomer.cartToken fieldCart-Token header (no prefix needed)Retrieving the token:
query GetSession { customer { cartToken } }
Sending the token:
const response = await fetch(graphqlEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Cart-Token': cartToken, }, body: JSON.stringify({ query, variables }), });
The original session token created by WooGraphQL's QL_Session_Handler class.
Customer.sessionToken fieldSession in the woocommerce-session headerRetrieving the token:
query GetSession { customer { sessionToken } }
Sending the token:
const response = await fetch(graphqlEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'woocommerce-session': `Session ${sessionToken}`, }, body: JSON.stringify({ query, variables }), });
Recommended for all projects. Use the Store-API cart token if:
Only recommended if you already have an existing application using the legacy token without NextPress, and you don't have the time or resources to migrate.
For all other cases, use the Store-API cart token.
The TokenManager class in this library is agnostic to which token type you use. Configure your startSession callback to return whichever token type is appropriate:
const tokenManager = new TokenManagerWithBrowserStorage({ ID: 'my-store', behavior: [SessionBehavior.withAuth], startSession: async (tokens) => { const response = await graphqlClient.query({ query: gql` query GetSession { customer { cartToken # Use cartToken for Store-API } } `, context: { headers: tokens.authToken ? { Authorization: `Bearer ${tokens.authToken}` } : {}, }, }); return response.data.customer.cartToken; }, // ... other options });
const tokenManager = new TokenManagerWithBrowserStorage({ ID: 'my-store', behavior: [SessionBehavior.withAuth], startSession: async (tokens) => { const response = await graphqlClient.query({ query: gql` query GetSession { customer { sessionToken # Use sessionToken for legacy } } `, context: { headers: tokens.authToken ? { Authorization: `Bearer ${tokens.authToken}` } : {}, }, }); return response.data.customer.sessionToken; }, // ... other options });
When making GraphQL requests, the header format differs:
| Token Type | Header Name | Header Format |
|---|---|---|
| Store-API | Cart-Token | {token} |
| Legacy | woocommerce-session | Session {token} |
Example request with both auth and session:
// Using Store-API token (recommended) const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}`, 'Cart-Token': cartToken, }; // Using Legacy token const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}`, 'woocommerce-session': `Session ${sessionToken}`, };
If you're migrating from legacy tokens to Store-API tokens:
cartToken instead of sessionTokenwoocommerce-session: Session {token} to Cart-Token: {token}The token format and lifecycle are similar, so the TokenManager configuration remains largely the same - only the GraphQL field and HTTP header change.