Generating secure URLs to transfer sessions from your headless frontend to WordPress.
Session dropoff URLs allow you to securely redirect users from your headless frontend to WordPress pages while maintaining their session (cart, authentication, etc.).
When users need to access WordPress-rendered pages (checkout, account, payment methods), you generate a special URL that includes a cryptographic nonce. WordPress validates this nonce and "picks up" the user's session.
The library supports these dropoff URL types:
| Type | Constant | Description |
|---|---|---|
| Cart Page | URLTypes.CartPage | WordPress cart page |
| Checkout Page | URLTypes.CheckoutPage | WordPress checkout |
| Account Page | URLTypes.AccountPage | My Account dashboard |
| Add Payment Method | URLTypes.AddNewPaymentMethodPage | Add new payment method |
| Change Subscription | URLTypes.ChangeSubscriptionPage | Modify subscription |
| Renew Subscription | URLTypes.RenewSubscriptionPage | Renew subscription |
import { generateDropoffURL, URLTypes } from '@woographql/session-utils'; // Generate a checkout URL const checkoutUrl = generateDropoffURL( clientSessionId, // From tokenManager.getClientSessionId() userId, // User/session identifier URLTypes.CheckoutPage ); // Redirect the user window.location.href = checkoutUrl;
import { TokenManager, URLTypes, generateDropoffURL, getUid } from '@woographql/session-utils'; async function redirectToCheckout(tokenManager: TokenManager) { // Ensure session is ready if (!tokenManager.isReady()) { await tokenManager.renewTokens(); } // Get client session ID const clientSessionId = tokenManager.getClientSessionId(); if (!clientSessionId) { throw new Error('Client session ID not available'); } // Get user ID from session token const { sessionToken } = tokenManager.getTokens(); const uId = getUid(sessionToken); // Generate and redirect const url = generateDropoffURL(clientSessionId, uId, URLTypes.CheckoutPage); window.location.href = url; }
Generated URLs follow this pattern:
https://your-wordpress-site.com/transfer-session?session_id={userId}&{nonceParam}={nonce}
Example:
https://shop.example.com/transfer-session?session_id=abc123&_wc_checkout=a1b2c3d4e5
| Component | Description |
|---|---|
| Base URL | Your WordPress site URL (from BACKEND_URL env var) |
| Path | transfer-session (configurable) |
session_id | User/session identifier |
| Nonce param | Action-specific parameter (e.g., _wc_checkout) |
| Nonce value | Cryptographic nonce for verification |
| URL Type | Nonce Parameter |
|---|---|
| Cart Page | _wc_cart |
| Checkout Page | _wc_checkout |
| Account Page | _wc_account |
| Add Payment Method | _wc_payment |
| Change Subscription | _wc_change_sub |
| Renew Subscription | _wc_renew_sub |
For more control, create a custom URL generator:
import { createUrlGenerator, URLTypes } from '@woographql/session-utils'; // Create a custom generator with different base URL or path const generateUrl = createUrlGenerator( 'https://my-wordpress-site.com', // WordPress URL 'session-handoff', // Custom path customNonceParams, // Optional: custom nonce params customNonceKeys // Optional: custom nonce keys ); // Use the custom generator const url = generateUrl(clientSessionId, userId, URLTypes.CheckoutPage);
For subscription-related URLs, the generated URL includes a placeholder:
const changeSubUrl = generateDropoffURL( clientSessionId, userId, URLTypes.ChangeSubscriptionPage ); // Result: https://site.com/transfer-session?session_id=abc&_wc_change_sub=xyz&sub=%SUBSCRIPTION_ID% // Replace the placeholder with the actual subscription ID const finalUrl = changeSubUrl.replace('%SUBSCRIPTION_ID%', subscriptionId);
The dropoff functionality requires the WooGraphQL Pro plugin or a custom WordPress endpoint that:
transfer-session route# Your WordPress backend URL BACKEND_URL=https://your-wordpress-site.com
Nonces are generated using a WordPress-compatible algorithm:
┌─────────────────────────────────────────────────────────────┐
│ Verification Flow │
├─────────────────────────────────────────────────────────────┤
│ 1. User clicks dropoff URL │
│ │
│ 2. WordPress receives request at /transfer-session │
│ │
│ 3. WordPress extracts: │
│ - session_id from URL │
│ - Nonce from URL parameter │
│ - Client Session ID from WooCommerce session meta │
│ │
│ 4. WordPress regenerates expected nonce using: │
│ - session_id │
│ - Stored Client Session ID │
│ - Action type (from nonce param name) │
│ │
│ 5. If nonces match: │
│ - Load user's WooCommerce session │
│ - Redirect to destination page │
│ │
│ 6. If nonces don't match: │
│ - Return error or redirect to login │
└─────────────────────────────────────────────────────────────┘
'use client'; import { useSession } from '@/client/SessionProvider'; import { generateDropoffURL, URLTypes } from '@woographql/session-utils'; export function CheckoutButton() { const { tokenManager, cart, customer } = useSession(); const handleCheckout = async () => { // Ensure we have a valid session if (!tokenManager.isReady()) { await tokenManager.renewTokens(); } const clientSessionId = tokenManager.getClientSessionId(); if (!clientSessionId) { // Handle error - client session ID required console.error('Client session ID not available'); return; } // Get user ID (from customer or session token) const userId = customer?.databaseId?.toString() || cart?.sessionToken?.split('||')[0] || 'guest'; // Generate checkout URL const checkoutUrl = generateDropoffURL( clientSessionId, userId, URLTypes.CheckoutPage ); // Redirect to WordPress checkout window.location.href = checkoutUrl; }; return ( <button onClick={handleCheckout}> Proceed to Checkout </button> ); }
withClientSession behavior