> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Handle Visitors Using the JS SDK ## Article: Handle Visitors ## Article Link: https://dev.wix.com/docs/go-headless/develop-your-project/self-managed-headless/authentication/visitors/handle-visitors-using-the-js-sdk.md ## Article Content: # Handle Visitors with the JavaScript SDK > **Note:** This article is only relevant for [self-managed headless projects](https://dev.wix.com/docs/go-headless/develop-your-project/self-managed-headless/about-self-managed-headless.md). For [Wix-managed headless projects](https://dev.wix.com/docs/wix-cli/guides/about-the-wix-cli.md), the CLI automatically generates and manages visitor tokens for you. Use visitor tokens to maintain anonymous visitor sessions in your self-managed headless project. The SDK uses these tokens when making requests to Wix APIs on behalf of a visitor, preserving their data such as cart items or event reservations.
## Step 1 | Create a client Create a Wix client with the [OAuth strategy](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md). Before creating the client, check your storage for tokens from a previous session: - **Returning visitor:** Tokens exist in storage. Pass them to the client to resume the previous session. - **New visitor:** No tokens found. Omit tokens when creating the client and generate new tokens as described in [Step 2](#step-2--generate-visitor-tokens). ```javascript import { createClient, OAuthStrategy } from "@wix/sdk"; // Retrieve tokens from storage (see Step 3 for storage options) const storedTokens = yourGetStoredTokensMethod(); const wixClient = createClient({ auth: OAuthStrategy({ clientId: "", // Pass tokens if they exist, otherwise omit to start a new session. tokens: storedTokens ?? undefined, }), }); ``` > **Note:** OAuth for Wix Headless only requires a client ID. It doesn't require a client secret. ## Step 2 | Generate visitor tokens Call [generateVisitorTokens()](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md) and store tokens to persist the session. - **Returning visitor:** Visitor tokens expire after 4 hours, so you must ensure the stored tokens are still valid. The method returns the same tokens if they're still valid, or renewed tokens if they've expired. - **New visitor:** The method creates tokens for a new session. Alternatively, the client creates them automatically on your first [API call](#step-4--make-api-calls). Calling `generateVisitorTokens()` initially lets you persist tokens if the app reloads before making your first API call. ```javascript //storedTokens are undefined for new visitors const tokens = await wixClient.auth.generateVisitorTokens(storedTokens); yourStoreTokensMethod(tokens); // See Step 3 for implementation options ``` ## Step 3 | Save tokens to persist the session To persist a visitor's session across page reloads or app restarts, save the tokens to local storage, a cookie, or a file. Retrieve the active tokens with [getTokens()](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md). ```javascript const tokens = wixClient.auth.getTokens(); ``` The method returns an object in this format: ```javascript { accessToken: { value: "OauthNG.JWS.eyJraWQiOi...3NbrhrauQ", expiresAt: 1677581109 }, refreshToken: { value: "JWS.eyJraWQiOiJZSEJzdUpwSCIsImFsZyI6IkhTMjU2In0.eyJkYXRhIjoiXCJkMDY4OTM4OS1kNTExLTRlYWMtYThjZC03MWQwMzA1NGIxM2NcIiIsImlhdCI6MTY3NzU2NjcwOSwiZXhwIjoxNzA5MTAyNzA5fQ.w2D7wECX_T-XfRzP4pXSoH8XSdHFBPnKx50FYzftRdc", role: "visitor" } } ``` Save the tokens to your preferred storage: ```javascript // Browser: Save to localStorage localStorage.setItem("wixSession", JSON.stringify(tokens)); // Browser: Save to a cookie document.cookie = `wixSession=${encodeURIComponent(JSON.stringify(tokens))}; path=/; max-age=31536000`; // Server-side: Save to your session store or database // The implementation depends on your stack (for example, Redis, a database, or your framework's session layer). await saveTokensToSession(userId, tokens); ``` ## Step 4 | Make API calls Call Wix API methods using your client. > **Note:** If you create the client without tokens or skip [Step 2](#step-2--generate-visitor-tokens), the client generates tokens automatically on your first API call. Make sure to retrieve and save the tokens as described in [Step 3](#step-3--save-tokens-to-persist-the-session). ```javascript // Make API calls const { products } = await wixClient.productsV3.searchProducts({ filter: { name: { $startsWith: "shoes" } }, cursorPaging: { limit: 4 }, }); // The visitor's cart is preserved across sessions const cart = await wixClient.currentCart.getCurrentCart(); ``` ## Example The following example shows the complete visitor session flow, from creating a client to making API calls: ```javascript import { createClient, OAuthStrategy } from "@wix/sdk"; import { currentCart } from "@wix/ecom"; import { productsV3 } from "@wix/stores"; // Retrieve tokens from a previous session, if they exist const storedTokens = localStorage.getItem("wixSession") ? JSON.parse(localStorage.getItem("wixSession")) : undefined; // Create a client - resume the previous session if tokens exist, or start a new one const wixClient = createClient({ modules: { currentCart, productsV3 }, auth: OAuthStrategy({ clientId: "", tokens: storedTokens ?? undefined, }), }); // Generate, validate, or renew visitor tokens const tokens = await wixClient.auth.generateVisitorTokens(storedTokens); //Store tokens to persist the current session localStorage.setItem("wixSession", JSON.stringify(tokens)); // Make API calls const { products } = await wixClient.productsV3.searchProducts({ filter: { name: { $startsWith: "shoes" } }, cursorPaging: { limit: 4 }, }); // The visitor's cart is preserved across sessions const cart = await wixClient.currentCart.getCurrentCart(); ``` ## Manage tokens manually In most cases, the client manages tokens automatically. Use these methods when you need manual control. ### Set tokens on an existing client If you already have a client instance and need to set tokens on it later, use [setTokens()](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md): ```javascript const savedTokens = JSON.parse(localStorage.getItem("wixSession")); wixClient.auth.setTokens(savedTokens); ``` Once tokens are set, the visitor's data is preserved. For example, items added to a cart or tickets reserved are reflected in future API calls. ### Generate tokens explicitly Call [generateVisitorTokens()](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md) to create tokens before making any API calls: ```javascript const tokens = await wixClient.auth.generateVisitorTokens(); ``` ### Validate or renew existing tokens Pass existing tokens to `generateVisitorTokens()` to confirm they're valid or renew them if expired: ```javascript const refreshedTokens = await wixClient.auth.generateVisitorTokens(existingTokens); ``` The method returns: - The same tokens if the access token is still valid. - A new access token if the access token expired but the refresh token is valid. - New access and refresh tokens if the refresh token is invalid. ### Force token renewal Use [renewToken()](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md) to generate a new access token without checking if the current one is valid: ```javascript const tokens = wixClient.auth.getTokens(); const newTokens = await wixClient.auth.renewToken(tokens.refreshToken); ``` ### Check login status Use [loggedIn()](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md) to check if the current visitor is a logged-in member: ```javascript const isLoggedIn = wixClient.auth.loggedIn(); // Returns false for anonymous visitors, true for logged-in members ``` ## See also - [About Handling Visitors](https://dev.wix.com/docs/go-headless/develop-your-project/self-managed-headless/authentication/visitors/about-handling-visitors.md) - [OAuthStrategy API Reference](https://dev.wix.com/docs/sdk/core-modules/sdk/oauth-strategy.md) - [Handle Members with a Custom Login Page](https://dev.wix.com/docs/go-headless/develop-your-project/self-managed-headless/authentication/members/custom-login-page/custom-login/custom-login-using-the-js-sdk.md)