{"id":22478,"date":"2026-01-23T11:10:04","date_gmt":"2026-01-23T11:10:04","guid":{"rendered":"https:\/\/ecommerce.folio3.com\/blog\/?p=22478"},"modified":"2026-01-23T18:56:06","modified_gmt":"2026-01-23T18:56:06","slug":"using-bigcommerce-storefront-apis-to-create-custom-product-display-page-experiences","status":"publish","type":"post","link":"https:\/\/ecommerce.folio3.com\/blog\/using-bigcommerce-storefront-apis-to-create-custom-product-display-page-experiences\/","title":{"rendered":"BigCommerce Storefront API Guide: GraphQL Setup, Documentation, and Multi-Storefront Implementation"},"content":{"rendered":"<p>Building custom shopping experiences demands direct control over your store&#8217;s data and presentation layer. The BigCommerce storefront API delivers this capability through a modern GraphQL interface that gives developers precise control over data retrieval and storefront customization.<\/p>\n<p><span style=\"font-weight: 400;\">Unlike traditional REST APIs that return fixed data structures, the storefront API lets you request exactly the information you need in a single query. This efficiency becomes critical when building high-performance storefronts, headless commerce architectures, or implementing advanced features like multi storefront SSO configurations. The API provides access to products, categories, customers, carts, and checkout functionality while maintaining security and scalability.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Summary<\/span><\/h2>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>GraphQL Architecture<\/b><span style=\"font-weight: 400;\">: The BigCommerce storefront API uses GraphQL for efficient, precise data retrieval with single-query capabilities replacing multiple REST endpoint calls<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Authentication Setup<\/b><span style=\"font-weight: 400;\">: Learn to generate storefront tokens, configure API credentials, and implement secure multi storefront API SSO for seamless channel integration<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Query Optimization<\/b><span style=\"font-weight: 400;\">: Master field selection, caching strategies, and cursor-based pagination to maximize performance across large product catalogs<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Headless Implementation<\/b><span style=\"font-weight: 400;\">: Build custom storefronts with any frontend framework while leveraging BigCommerce GraphQL storefront API documentation for backend operations<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Multi-Channel Management<\/b><span style=\"font-weight: 400;\">: Configure channel-specific API access, synchronize customer data, and maintain shared carts across multiple storefronts<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Security Best Practices<\/b><span style=\"font-weight: 400;\">: Implement token rotation, CORS validation, and rate limiting to protect customer data and maintain API reliability<\/span><\/li>\n<\/ul>\n<h2><span style=\"font-weight: 400;\">Understanding the BigCommerce Storefront API Architecture<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The BigCommerce storefront API operates as a GraphQL endpoint that separates data retrieval from presentation logic, enabling flexible frontend implementations.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Core API Components and Capabilities<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">The storefront API architecture consists of three primary layers that work together to deliver seamless data access. The GraphQL query layer handles all read operations, allowing you to fetch product details, category structures, customer information, and inventory status with precision. The mutation layer manages write operations including cart modifications, checkout processes, and <a href=\"https:\/\/ecommerce.folio3.com\/blog\/merge-guest-orders-to-customer-accounts\/\">customer account<\/a> updates. The authentication layer secures these operations through JWT tokens and storefront-specific credentials.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This architecture supports both traditional <a href=\"https:\/\/ecommerce.folio3.com\/blog\/switch-from-blueprint-to-stencil-bigcommerce\/\">Stencil themes<\/a> and headless implementations. When working with Stencil, the API integrates directly with Handlebars templates through JavaScript. For headless setups, the API serves as the backend data source while your chosen frontend framework handles presentation.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><b>API Component<\/b><\/td>\n<td><b>Primary Function<\/b><\/td>\n<td><b>Common Use Cases<\/b><\/td>\n<td><b>Performance Impact<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">GraphQL Queries<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Data retrieval operations<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Product listings, category browsing, search results<\/span><\/td>\n<td><span style=\"font-weight: 400;\">High efficiency with selective field fetching<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">GraphQL Mutations<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Data modification operations<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Cart management, checkout flow, wishlist updates<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Optimized for transactional operations<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Storefront Tokens<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Request authentication<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Secure API access, customer sessions, checkout security<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Minimal overhead with proper caching<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Webhooks Integration<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Real-time event handling<\/span><\/td>\n<td><span style=\"font-weight: 400;\"><a href=\"https:\/\/ecommerce.folio3.com\/blog\/how-to-update-inventory-in-bigcommerce\/\">Inventory updates<\/a>, order notifications, price changes<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Reduces polling requirements<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3><span style=\"font-weight: 400;\">GraphQL Advantages Over REST Implementations<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">The shift from REST to GraphQL in the BigCommerce storefront API documentation brings measurable performance improvements. Traditional REST endpoints often require multiple requests to gather related data. With GraphQL, you consolidate these into a single query that returns precisely what your frontend needs.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Consider fetching a product with its variants, images, and pricing. A REST approach might require three separate requests to different endpoints. The BigCommerce GraphQL storefront API documentation shows how a single query can retrieve all this data efficiently. This reduces network overhead, decreases latency, and improves the user experience, particularly on mobile devices with limited bandwidth.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The strongly-typed schema also provides built-in documentation and validation. Your development tools can autocomplete available fields and catch errors before runtime. This accelerates development while reducing bugs in production.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Setting Up Your BigCommerce Storefront API Environment<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Proper environment configuration ensures secure and efficient API access across development, staging, and production environments.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Creating API Credentials and Tokens<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Navigate to your BigCommerce control panel and access the Advanced Settings section. Within API Accounts, create a new Storefront API token that grants appropriate permissions for your use case. The token generation process creates credentials tied to a specific store and channel, enabling secure multi storefront API configurations.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Store these credentials securely using environment variables rather than hardcoding them in your application. For local development, use a <\/span><span style=\"font-weight: 400;\">.env<\/span><span style=\"font-weight: 400;\"> file that remains excluded from version control. Production deployments should leverage your hosting platform&#8217;s secret management system to protect sensitive credentials.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Environment configuration for storefront API access<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">STOREFRONT_CONFIG<\/span> <span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">storeHash<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_STORE_HASH<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">storefrontToken<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_STOREFRONT_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">graphqlEndpoint<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">`https:\/\/store-<\/span><span style=\"font-weight: 400;\">${process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_STORE_HASH<\/span><span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\">.mybigcommerce.com\/graphql`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">};<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Initialize GraphQL client with authentication<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">createStorefrontClient<\/span> <span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> () <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">GraphQLClient<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">STOREFRONT_CONFIG<\/span><span style=\"font-weight: 400;\">.graphqlEndpoint, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">headers<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Authorization'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">`Bearer <\/span><span style=\"font-weight: 400;\">${<\/span><span style=\"font-weight: 400;\">STOREFRONT_CONFIG<\/span><span style=\"font-weight: 400;\">.storefrontToken}<\/span><span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Content-Type'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'application\/json'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">};<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Configuring Multiple Storefronts with SSO<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">The <a href=\"https:\/\/ecommerce.folio3.com\/blog\/bigcommerce-multi-storefront-everything-you-need-to-know\/\">BigCommerce multi storefront<\/a> API SSO capability allows customers to authenticate once and access multiple storefronts within your ecosystem. This requires coordinating customer tokens across channels while maintaining security boundaries.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Start by configuring each storefront with its own API credentials. Then implement a central authentication service that generates customer impersonation tokens valid across your storefronts. When a customer logs in through one storefront, your authentication service creates tokens for all associated channels, enabling seamless transitions between stores.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Multi storefront SSO token generation<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">generateMultiStorefrontTokens<\/span> <span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">async<\/span><span style=\"font-weight: 400;\"> (customerId, customerEmail) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> storefronts <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> [<\/span><span style=\"font-weight: 400;\">'main-store'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'wholesale-store'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'retail-store'<\/span><span style=\"font-weight: 400;\">];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> tokens <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">Promise<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">all<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0storefronts.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">async<\/span><span style=\"font-weight: 400;\"> (storefront) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> response <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">fetch<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">`https:\/\/api.bigcommerce.com\/stores\/<\/span><span style=\"font-weight: 400;\">${storefront}<\/span><span style=\"font-weight: 400;\">\/v3\/storefront\/api-token`<\/span><span style=\"font-weight: 400;\">, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">method<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'POST'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">headers<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'X-Auth-Token'<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_API_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Content-Type'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'application\/json'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">body<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">JSON<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">stringify<\/span><span style=\"font-weight: 400;\">({<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">channel_id<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">getChannelId<\/span><span style=\"font-weight: 400;\">(storefront),<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">expires_at<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">+<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">3600<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">1000<\/span><span style=\"font-weight: 400;\">), <\/span><i><span style=\"font-weight: 400;\">\/\/ 1 hour expiration<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">allowed_cors_origins<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> [process.env.<\/span><span style=\"font-weight: 400;\">STOREFRONT_URL<\/span><span style=\"font-weight: 400;\">],<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">customer_id<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> customerId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> response.<\/span><span style=\"font-weight: 400;\">json<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0})<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> tokens;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">};<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">This implementation maintains separate customer sessions per storefront while sharing authentication state. Users experience seamless navigation between your stores without repeated login prompts.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Working With BigCommerce GraphQL Storefront API Documentation<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The BigCommerce GraphQL storefront API docs provide comprehensive schema definitions and example queries that accelerate development.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Essential Query Patterns for Product Data<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Product queries form the foundation of most storefront implementations. The API documentation reveals the full product schema, including fields for variants, options, custom fields, and metafields.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">graphql<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\"># Comprehensive product query with variants and pricing<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">query<\/span> <span style=\"font-weight: 400;\">GetProductDetails<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">$productId<\/span><span style=\"font-weight: 400;\">: Int<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0product(<\/span><span style=\"font-weight: 400;\">entityId<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$productId<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">sku<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">description<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0availabilityV2 {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">status<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">description<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0defaultImage {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url(<\/span><span style=\"font-weight: 400;\">width<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">800<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">height<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">800<\/span><span style=\"font-weight: 400;\">)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">altText<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0images {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url(<\/span><span style=\"font-weight: 400;\">width<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">1200<\/span><span style=\"font-weight: 400;\">)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">altText<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">isDefault<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0salePrice {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0retailPrice {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0productOptions {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">displayName<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">isRequired<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">...<\/span> <span style=\"font-weight: 400;\">on<\/span> <span style=\"font-weight: 400;\">MultipleChoiceOption<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0values {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">label<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0variants {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">sku<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">isPurchasable<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inventory {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">isInStock<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0aggregated {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">availableToSell<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">This query structure retrieves complete product information in a single request. The availability status, inventory levels, and variant details enable accurate product display and purchase options. Adjust the image dimensions based on your frontend requirements to optimize bandwidth usage.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Implementing Cart and Checkout Operations<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Cart management requires both queries and mutations to handle the full shopping flow. The BigCommerce storefront GraphQL API documentation details the cart schema and available operations.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">graphql<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\"># Create or retrieve a cart<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">mutation<\/span> <span style=\"font-weight: 400;\">CreateCart<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">$createCartInput<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">CreateCartInput<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0createCart(<\/span><span style=\"font-weight: 400;\">input<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$createCartInput<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lineItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0physicalItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">quantity<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0extendedListPrice {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0amount {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\"># Add line items to existing cart<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">mutation<\/span> <span style=\"font-weight: 400;\">AddCartLineItems<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">$addCartLineItemsInput<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">AddCartLineItemsInput<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0addCartLineItems(<\/span><span style=\"font-weight: 400;\">input<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$addCartLineItemsInput<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lineItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0physicalItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">quantity<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">productEntityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">variantEntityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\"># Update cart line item quantity<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">mutation<\/span> <span style=\"font-weight: 400;\">UpdateCartLineItem<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">$updateCartLineItemInput<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">UpdateCartLineItemInput<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0updateCartLineItem(<\/span><span style=\"font-weight: 400;\">input<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$updateCartLineItemInput<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lineItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0physicalItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">quantity<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0extendedListPrice {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">Cart persistence requires storing the cart ID in local storage or cookies. When customers return to your site, retrieve the cart using the stored ID rather than creating a new one. This maintains shopping continuity across sessions.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Category and Navigation Structure Queries<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Building dynamic navigation requires fetching the category tree with proper hierarchy relationships. The API provides efficient queries for retrieving category structures.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">graphql<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">query<\/span> <span style=\"font-weight: 400;\">GetCategoryTree<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">$rootEntityId<\/span><span style=\"font-weight: 400;\">: Int) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0categoryTree(<\/span><span style=\"font-weight: 400;\">rootEntityId<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$rootEntityId<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">description<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">productCount<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0children {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">productCount<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0children {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">productCount<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\"># Get products within a category with filtering<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">query<\/span> <span style=\"font-weight: 400;\">GetCategoryProducts<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">$categoryId<\/span><span style=\"font-weight: 400;\">: Int<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">$first<\/span><span style=\"font-weight: 400;\">: Int<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">$after<\/span><span style=\"font-weight: 400;\">: String,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">$sortBy<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">CategoryProductSort<\/span><span style=\"font-weight: 400;\">!<\/span>\r\n\r\n<span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0category(<\/span><span style=\"font-weight: 400;\">entityId<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$categoryId<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">description<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0products(<\/span><span style=\"font-weight: 400;\">first<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$first<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">after<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$after<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">sortBy<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">$sortBy<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pageInfo {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">hasNextPage<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">hasPreviousPage<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">startCursor<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">endCursor<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">cursor<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0defaultImage {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url(<\/span><span style=\"font-weight: 400;\">width<\/span><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">300<\/span><span style=\"font-weight: 400;\">)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">Now that we&#8217;ve covered category navigation, let&#8217;s examine how to optimize API performance through strategic query design.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Optimizing BigCommerce Storefront API Performance<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Strategic API usage patterns significantly improve application speed and reduce server load across your storefront.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Query Optimization and Field Selection<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">The BigCommerce GraphQL storefront API docs emphasize requesting only necessary fields to minimize response sizes. Each additional field increases payload size and processing time. Audit your queries regularly to remove unused data.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><b>Optimization Technique<\/b><\/td>\n<td><b>Performance Gain<\/b><\/td>\n<td><b>Implementation Complexity<\/b><\/td>\n<td><b>Best Use Cases<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Field selection pruning<\/span><\/td>\n<td><span style=\"font-weight: 400;\">40-60% smaller payloads<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Low<\/span><\/td>\n<td><span style=\"font-weight: 400;\">All queries<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Query result caching<\/span><\/td>\n<td><span style=\"font-weight: 400;\">80-95% faster responses<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Medium<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Product catalogs, categories<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Cursor-based pagination<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Consistent performance at scale<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Medium<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Large product lists, search results<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Fragment composition<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Improved code maintainability<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Low<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Repeated query patterns<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Example of optimized field selection<\/span><\/i>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ AVOID: Requesting all available fields<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> inefficientQuery <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0query {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0products(first: 20) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# Requesting everything increases payload unnecessarily<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ BETTER: Request only needed fields<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> optimizedQuery <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0query {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0products(first: 20) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0defaultImage {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url(width: 300)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">;<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Implementing Effective Caching Strategies<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Cache API responses at multiple layers to reduce redundant requests and improve user experience. Browser caching handles frequently accessed data, while server-side caching accelerates repeated queries across users.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Implement tiered caching for storefront API<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">import<\/span><span style=\"font-weight: 400;\"> { Redis } <\/span><span style=\"font-weight: 400;\">from<\/span> <span style=\"font-weight: 400;\">'ioredis'<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">StorefrontCache<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.redis <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Redis<\/span><span style=\"font-weight: 400;\">(process.env.<\/span><span style=\"font-weight: 400;\">REDIS_URL<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.browserCache <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Map<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">getCachedQuery<\/span><span style=\"font-weight: 400;\">(queryKey, fetchFunction, ttl <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">300<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Check browser cache first (for client-side)<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.browserCache.<\/span><span style=\"font-weight: 400;\">has<\/span><span style=\"font-weight: 400;\">(queryKey)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> cached <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.browserCache.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(queryKey);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\"> cached.expiry) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> cached.data;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Check Redis cache (for server-side)<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> cachedData <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.redis.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(queryKey);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (cachedData) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">JSON<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">parse<\/span><span style=\"font-weight: 400;\">(cachedData);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Fetch fresh data and cache it<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> freshData <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">fetchFunction<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.redis.<\/span><span style=\"font-weight: 400;\">setex<\/span><span style=\"font-weight: 400;\">(queryKey, ttl, <\/span><span style=\"font-weight: 400;\">JSON<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">stringify<\/span><span style=\"font-weight: 400;\">(freshData));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.browserCache.<\/span><span style=\"font-weight: 400;\">set<\/span><span style=\"font-weight: 400;\">(queryKey, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">data<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> freshData,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">expiry<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">+<\/span><span style=\"font-weight: 400;\"> (ttl <\/span><span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">1000<\/span><span style=\"font-weight: 400;\">)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> freshData;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">invalidateCache<\/span><span style=\"font-weight: 400;\">(pattern) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Invalidate Redis cache by pattern<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.redis.<\/span><span style=\"font-weight: 400;\">keys<\/span><span style=\"font-weight: 400;\">(pattern).<\/span><span style=\"font-weight: 400;\">then<\/span><span style=\"font-weight: 400;\">(keys <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (keys.length <\/span><span style=\"font-weight: 400;\">&gt;<\/span> <span style=\"font-weight: 400;\">0<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.redis.<\/span><span style=\"font-weight: 400;\">del<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">...<\/span><span style=\"font-weight: 400;\">keys);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Usage example<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> cache <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">StorefrontCache<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">getProductDetails<\/span><span style=\"font-weight: 400;\">(productId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> cache.<\/span><span style=\"font-weight: 400;\">getCachedQuery<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">`product:<\/span><span style=\"font-weight: 400;\">${productId}<\/span><span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0() <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">executeProductQuery<\/span><span style=\"font-weight: 400;\">(productId),<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">600<\/span> <i><span style=\"font-weight: 400;\">\/\/ 10 minutes cache<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">Set appropriate cache durations based on data volatility. Product descriptions might cache for hours, while inventory levels require shorter TTL values or real-time updates.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Pagination Best Practices for Large Data Sets<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Cursor-based pagination provided by the BigCommerce storefront API maintains consistent performance regardless of offset depth. This approach outperforms traditional offset pagination for large product catalogs.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Implement infinite scroll with cursor pagination<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">loadMoreProducts<\/span><span style=\"font-weight: 400;\">(categoryId, cursor <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">null<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">PRODUCTS_PER_PAGE<\/span> <span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">24<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> query <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0query GetProducts($categoryId: Int!, $first: Int!, $after: String) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0category(entityId: $categoryId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0products(first: $first, after: $after) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pageInfo {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0hasNextPage<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0endCursor<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0defaultImage {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url(width: 300)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> variables <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0categoryId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">first<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">PRODUCTS_PER_PAGE<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">after<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> cursor<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> response <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span><span style=\"font-weight: 400;\"> storefrontClient.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(query, variables);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> response.site.category.products;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Implement infinite scroll UI handler<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">let<\/span><span style=\"font-weight: 400;\"> currentCursor <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">null<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> productContainer <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">document<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">getElementById<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'product-grid'<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">handleScroll<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">isNearBottom<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">&amp;&amp;<\/span> <span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">isLoading) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0isLoading <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">true<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> products <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">loadMoreProducts<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">CATEGORY_ID<\/span><span style=\"font-weight: 400;\">, currentCursor);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">appendProducts<\/span><span style=\"font-weight: 400;\">(products.edges);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0currentCursor <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> products.pageInfo.hasNextPage <\/span><span style=\"font-weight: 400;\">?<\/span><span style=\"font-weight: 400;\"> products.pageInfo.endCursor <\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">null<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0isLoading <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">false<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h2><span style=\"font-weight: 400;\">Building Custom Storefront Experiences<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Custom implementations leverage the storefront API to create unique shopping experiences beyond standard theme capabilities.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Headless Commerce Architecture Implementation<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Headless architecture separates your frontend from BigCommerce&#8217;s backend, enabling complete design freedom and framework flexibility. The storefront API serves as the data layer while your chosen frontend framework handles presentation.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Select a frontend framework based on your team&#8217;s expertise and project requirements. Next.js offers excellent SEO capabilities through server-side rendering, making it ideal for content-heavy stores. React provides maximum flexibility for complex interactive experiences. Vue.js delivers a gentler learning curve while maintaining robust features.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Next.js implementation example for headless storefront<\/span><\/i>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ pages\/products\/[slug].js<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">import<\/span><span style=\"font-weight: 400;\"> { GraphQLClient } <\/span><span style=\"font-weight: 400;\">from<\/span> <span style=\"font-weight: 400;\">'graphql-request'<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> client <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">GraphQLClient<\/span><span style=\"font-weight: 400;\">(process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_GRAPHQL_ENDPOINT<\/span><span style=\"font-weight: 400;\">, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">headers<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Authorization'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">`Bearer <\/span><span style=\"font-weight: 400;\">${process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_STOREFRONT_TOKEN<\/span><span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">export<\/span> <span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">getStaticPaths<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> query <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0query {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0products(first: 250) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0path<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> data <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span><span style=\"font-weight: 400;\"> client.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(query);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> paths <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> data.site.products.edges.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(({ node }) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> ({<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">params<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> { <\/span><span style=\"font-weight: 400;\">slug<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> node.path.<\/span><span style=\"font-weight: 400;\">replace<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'\/products\/'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">''<\/span><span style=\"font-weight: 400;\">) }<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> { paths, <\/span><span style=\"font-weight: 400;\">fallback<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'blocking'<\/span><span style=\"font-weight: 400;\"> };<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">export<\/span> <span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">getStaticProps<\/span><span style=\"font-weight: 400;\">({ params }) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> query <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0query GetProduct($path: String!) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0route(path: $path) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... on Product {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0currencyCode<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0images {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0url(width: 1200)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0altText<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> data <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span><span style=\"font-weight: 400;\"> client.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(query, { <\/span><span style=\"font-weight: 400;\">path<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">`\/products\/<\/span><span style=\"font-weight: 400;\">${params.slug}<\/span><span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\"> });<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">props<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">product<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> data.site.route.node<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">revalidate<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">3600<\/span> <i><span style=\"font-weight: 400;\">\/\/ Regenerate page every hour<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">export<\/span> <span style=\"font-weight: 400;\">default<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">ProductPage<\/span><span style=\"font-weight: 400;\">({ product }) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> (<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"product-page\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">h1<\/span><span style=\"font-weight: 400;\">&gt;<\/span><span style=\"font-weight: 400;\">{product.name}<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">h1<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"product-images\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{product.images.edges.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(({ node }) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> (<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">img key<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{node.url} src<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{node.url} alt<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{node.altText} <\/span><span style=\"font-weight: 400;\">\/&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0))}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"product-price\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{product.prices.price.currencyCode} {product.prices.price.value}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"product-description\"<\/span><span style=\"font-weight: 400;\"> dangerouslySetInnerHTML<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{{ <\/span><span style=\"font-weight: 400;\">__html<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> product.description }} <\/span><span style=\"font-weight: 400;\">\/&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">This approach generates static pages for all products at build time, then revalidates them hourly. Users receive instant page loads while seeing current product information.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Product Configurator Development<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Interactive product configurators enhance the shopping experience for customizable items. The storefront API provides all necessary data for building sophisticated configuration tools.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ React component for product configuration<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">import<\/span><span style=\"font-weight: 400;\"> { useState, useEffect } <\/span><span style=\"font-weight: 400;\">from<\/span> <span style=\"font-weight: 400;\">'react'<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">ProductConfigurator<\/span><span style=\"font-weight: 400;\">({ product }) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> [selectedOptions, setSelectedOptions] <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">useState<\/span><span style=\"font-weight: 400;\">({});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> [currentVariant, setCurrentVariant] <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">useState<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">null<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> [price, setPrice] <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">useState<\/span><span style=\"font-weight: 400;\">(product.prices.price);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">useEffect<\/span><span style=\"font-weight: 400;\">(() <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Find matching variant based on selected options<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> variant <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">findMatchingVariant<\/span><span style=\"font-weight: 400;\">(product.variants, selectedOptions);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (variant) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">setCurrentVariant<\/span><span style=\"font-weight: 400;\">(variant);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">setPrice<\/span><span style=\"font-weight: 400;\">(variant.prices.price);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}, [selectedOptions, product]);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">handleOptionChange<\/span> <span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> (optionId, valueId) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">setSelectedOptions<\/span><span style=\"font-weight: 400;\">(prev <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> ({<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">...<\/span><span style=\"font-weight: 400;\">prev,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0[optionId]<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> valueId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> (<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"product-configurator\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"product-visualization\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">ProductImage\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0images<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{product.images.edges}\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectedVariant<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{currentVariant}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">\/&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"configuration-options\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{product.productOptions.edges.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(({ <\/span><span style=\"font-weight: 400;\">node<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> option }) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> (<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div key<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{option.entityId} className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"option-group\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">label<\/span><span style=\"font-weight: 400;\">&gt;<\/span><span style=\"font-weight: 400;\">{option.displayName}<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">label<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{option.isRequired <\/span><span style=\"font-weight: 400;\">&amp;&amp;<\/span> <span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">span className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"required\"<\/span><span style=\"font-weight: 400;\">&gt;*&lt;\/<\/span><span style=\"font-weight: 400;\">span<\/span><span style=\"font-weight: 400;\">&gt;<\/span><span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">OptionSelector<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0option<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{option}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectedValue<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{selectedOptions[option.entityId]}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{(valueId) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">handleOptionChange<\/span><span style=\"font-weight: 400;\">(option.entityId, valueId)}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">\/&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0))}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"configuration-summary\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">div className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"price-display\"<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{price.currencyCode} {price.value}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\">button\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">\"add-to-cart\"<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0disabled<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">currentVariant <\/span><span style=\"font-weight: 400;\">||<\/span> <span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">currentVariant.isPurchasable}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick<\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\">{() <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">addToCart<\/span><span style=\"font-weight: 400;\">(currentVariant)}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Add to Cart<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">button<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">&lt;\/<\/span><span style=\"font-weight: 400;\">div<\/span><span style=\"font-weight: 400;\">&gt;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">findMatchingVariant<\/span><span style=\"font-weight: 400;\">(variants, selectedOptions) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> variants.edges.<\/span><span style=\"font-weight: 400;\">find<\/span><span style=\"font-weight: 400;\">(({ <\/span><span style=\"font-weight: 400;\">node<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> variant }) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> variant.options.<\/span><span style=\"font-weight: 400;\">every<\/span><span style=\"font-weight: 400;\">(option <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectedOptions[option.entityId] <\/span><span style=\"font-weight: 400;\">===<\/span><span style=\"font-weight: 400;\"> option.valueEntityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0})<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">node;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Real-Time Inventory and Availability Display<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Accurate inventory information prevents overselling and improves customer trust. Query inventory status alongside product data to display current availability.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Real-time inventory checker with automatic updates<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">InventoryTracker<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">(productIds) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.productIds <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> productIds;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.updateInterval <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">30000<\/span><span style=\"font-weight: 400;\">; <\/span><i><span style=\"font-weight: 400;\">\/\/ 30 seconds<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.subscribers <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Map<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">checkInventory<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> query <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0query CheckInventory($productIds: [Int!]!) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0products(entityIds: $productIds) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0availabilityV2 {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0status<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inventory {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isInStock<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0aggregated {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0availableToSell<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0variants {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0edges {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0node {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inventory {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isInStock<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0aggregated {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0availableToSell<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n\r\n\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> data <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span><span style=\"font-weight: 400;\"> client.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(query, { <\/span><span style=\"font-weight: 400;\">productIds<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.productIds });<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> data.site.products.edges;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">subscribe<\/span><span style=\"font-weight: 400;\">(productId, callback) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.subscribers.<\/span><span style=\"font-weight: 400;\">has<\/span><span style=\"font-weight: 400;\">(productId)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.subscribers.<\/span><span style=\"font-weight: 400;\">set<\/span><span style=\"font-weight: 400;\">(productId, []);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.subscribers.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(productId).<\/span><span style=\"font-weight: 400;\">push<\/span><span style=\"font-weight: 400;\">(callback);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">startTracking<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">setInterval<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">async<\/span><span style=\"font-weight: 400;\"> () <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> inventoryData <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">checkInventory<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inventoryData.<\/span><span style=\"font-weight: 400;\">forEach<\/span><span style=\"font-weight: 400;\">(({ <\/span><span style=\"font-weight: 400;\">node<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> product }) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> callbacks <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.subscribers.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(product.entityId) <\/span><span style=\"font-weight: 400;\">||<\/span><span style=\"font-weight: 400;\"> [];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0callbacks.<\/span><span style=\"font-weight: 400;\">forEach<\/span><span style=\"font-weight: 400;\">(callback <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">callback<\/span><span style=\"font-weight: 400;\">(product));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}, <\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.updateInterval);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Usage example<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> tracker <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">InventoryTracker<\/span><span style=\"font-weight: 400;\">([<\/span><span style=\"font-weight: 400;\">123<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">456<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">789<\/span><span style=\"font-weight: 400;\">]);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">tracker.<\/span><span style=\"font-weight: 400;\">subscribe<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">123<\/span><span style=\"font-weight: 400;\">, (product) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">updateInventoryDisplay<\/span><span style=\"font-weight: 400;\">(product.entityId, product.inventory.aggregated.availableToSell);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">tracker.<\/span><span style=\"font-weight: 400;\">startTracking<\/span><span style=\"font-weight: 400;\">();<\/span><\/pre>\n<h2><span style=\"font-weight: 400;\">Advanced Multi Storefront API Configuration<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Managing multiple storefronts requires coordinated API access and shared authentication across channel boundaries.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Channel-Specific API Implementation<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Each BigCommerce channel requires separate API credentials while sharing the same product catalog. Configure channel-specific tokens and endpoints to isolate storefront operations.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Multi-channel API client manager<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">MultiChannelClient<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.channels <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'main-store'<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">storeHash<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">MAIN_STORE_HASH<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">token<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">MAIN_STORE_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">channelId<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">1<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'wholesale'<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">storeHash<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">WHOLESALE_STORE_HASH<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">token<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">WHOLESALE_STORE_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">channelId<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">2<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'b2b-portal'<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">storeHash<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">B2B_STORE_HASH<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">token<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">B2B_STORE_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">channelId<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">3<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">getClient<\/span><span style=\"font-weight: 400;\">(channelName) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> config <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.channels[channelName];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">GraphQLClient<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">`https:\/\/store-<\/span><span style=\"font-weight: 400;\">${config.storeHash}<\/span><span style=\"font-weight: 400;\">.mybigcommerce.com\/graphql`<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">headers<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Authorization'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">`Bearer <\/span><span style=\"font-weight: 400;\">${config.token}<\/span><span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Content-Type'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'application\/json'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">executeQuery<\/span><span style=\"font-weight: 400;\">(channelName, query, variables) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> client <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">getClient<\/span><span style=\"font-weight: 400;\">(channelName);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> client.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(query, variables);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Usage for channel-specific operations<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> channelManager <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">MultiChannelClient<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">getWholesalePricing<\/span><span style=\"font-weight: 400;\">(productId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> query <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0query GetProduct($productId: Int!) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0site {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0product(entityId: $productId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0prices {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0price {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> channelManager.<\/span><span style=\"font-weight: 400;\">executeQuery<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'wholesale'<\/span><span style=\"font-weight: 400;\">, query, { productId });<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Shared Cart Across Multiple Storefronts<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Implement cart synchronization when customers navigate between your storefronts, maintaining their shopping session across channels.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Cross-storefront cart synchronization<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">SharedCartManager<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">(customerId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.customerId <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> customerId;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.cartMapping <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Map<\/span><span style=\"font-weight: 400;\">(); <\/span><i><span style=\"font-weight: 400;\">\/\/ Maps channel to cart ID<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">initializeCarts<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> channels <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> [<\/span><span style=\"font-weight: 400;\">'main-store'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'wholesale'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'b2b-portal'<\/span><span style=\"font-weight: 400;\">];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">Promise<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">all<\/span><span style=\"font-weight: 400;\">(channels.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">async<\/span><span style=\"font-weight: 400;\"> (channel) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> cart <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">getOrCreateCart<\/span><span style=\"font-weight: 400;\">(channel);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.cartMapping.<\/span><span style=\"font-weight: 400;\">set<\/span><span style=\"font-weight: 400;\">(channel, cart.entityId);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">getOrCreateCart<\/span><span style=\"font-weight: 400;\">(channel) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Try to retrieve existing cart<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> existingCartId <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">localStorage<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">getItem<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">`cart_<\/span><span style=\"font-weight: 400;\">${channel}<\/span><span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (existingCartId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> cart <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">getCart<\/span><span style=\"font-weight: 400;\">(channel, existingCartId);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (cart) <\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> cart;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Create new cart if none exists<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">createCart<\/span><span style=\"font-weight: 400;\">(channel);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">syncCartItem<\/span><span style=\"font-weight: 400;\">(item, sourceChannel) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> sourceCartId <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.cartMapping.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(sourceChannel);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Add item to all other channel carts<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> otherChannels <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">Array<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">from<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.cartMapping.<\/span><span style=\"font-weight: 400;\">keys<\/span><span style=\"font-weight: 400;\">())<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.<\/span><span style=\"font-weight: 400;\">filter<\/span><span style=\"font-weight: 400;\">(channel <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> channel <\/span><span style=\"font-weight: 400;\">!==<\/span><span style=\"font-weight: 400;\"> sourceChannel);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">Promise<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">all<\/span><span style=\"font-weight: 400;\">(otherChannels.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(channel <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">addItemToCart<\/span><span style=\"font-weight: 400;\">(channel, <\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.cartMapping.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(channel), item)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">addItemToCart<\/span><span style=\"font-weight: 400;\">(channel, cartId, item) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> client <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> channelManager.<\/span><span style=\"font-weight: 400;\">getClient<\/span><span style=\"font-weight: 400;\">(channel);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> mutation <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">`<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mutation AddItem($input: AddCartLineItemsInput!) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0addCartLineItems(input: $input) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cart {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lineItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0physicalItems {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0entityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0quantity<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0`<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> client.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(mutation, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">input<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">cartEntityId<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> cartId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">data<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">lineItems<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> [{<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">productEntityId<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> item.productId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">variantEntityId<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> item.variantId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">quantity<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> item.quantity<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}]<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Customer Data Synchronization Between Storefronts<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Maintain consistent customer profiles across channels while respecting privacy boundaries and data isolation requirements.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Customer profile synchronization service<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">CustomerSyncService<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">syncCustomerData<\/span><span style=\"font-weight: 400;\">(customerId, sourceChannel, updateData) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Update customer in BigCommerce<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">updateBigCommerceCustomer<\/span><span style=\"font-weight: 400;\">(customerId, updateData);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Propagate changes to all active sessions<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">broadcastCustomerUpdate<\/span><span style=\"font-weight: 400;\">(customerId, updateData);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Update cached customer data<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">updateCustomerCache<\/span><span style=\"font-weight: 400;\">(customerId, updateData);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">updateBigCommerceCustomer<\/span><span style=\"font-weight: 400;\">(customerId, data) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> response <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">fetch<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">`https:\/\/api.bigcommerce.com\/stores\/<\/span><span style=\"font-weight: 400;\">${process.env.<\/span><span style=\"font-weight: 400;\">STORE_HASH<\/span><span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\">\/v3\/customers\/<\/span><span style=\"font-weight: 400;\">${customerId}<\/span><span style=\"font-weight: 400;\">`<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">method<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'PUT'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">headers<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'X-Auth-Token'<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_API_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Content-Type'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'application\/json'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">body<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">JSON<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">stringify<\/span><span style=\"font-weight: 400;\">(data)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> response.<\/span><span style=\"font-weight: 400;\">json<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">broadcastCustomerUpdate<\/span><span style=\"font-weight: 400;\">(customerId, data) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Notify all active storefront sessions<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> channels <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">getActiveChannels<\/span><span style=\"font-weight: 400;\">(customerId);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">Promise<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">all<\/span><span style=\"font-weight: 400;\">(channels.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(channel <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">notifyChannel<\/span><span style=\"font-weight: 400;\">(channel, customerId, data)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h2><span style=\"font-weight: 400;\">Security and Authentication Best Practices<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Proper security implementation protects customer data and prevents unauthorized access to your storefront API.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Token Management and Rotation<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Implement automatic token rotation to minimize security risks from compromised credentials. The BigCommerce storefront API documentation recommends regular token refresh for long-running applications.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Secure token management with automatic rotation<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">TokenManager<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.tokens <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Map<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.rotationInterval <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">24<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">60<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">60<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">1000<\/span><span style=\"font-weight: 400;\">; <\/span><i><span style=\"font-weight: 400;\">\/\/ 24 hours<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">getValidToken<\/span><span style=\"font-weight: 400;\">(channelId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> tokenData <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.tokens.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(channelId);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">tokenData <\/span><span style=\"font-weight: 400;\">||<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">isTokenExpiring<\/span><span style=\"font-weight: 400;\">(tokenData)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">rotateToken<\/span><span style=\"font-weight: 400;\">(channelId);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> tokenData.token;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">rotateToken<\/span><span style=\"font-weight: 400;\">(channelId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> response <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">fetch<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">`https:\/\/api.bigcommerce.com\/stores\/<\/span><span style=\"font-weight: 400;\">${process.env.<\/span><span style=\"font-weight: 400;\">STORE_HASH<\/span><span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\">\/v3\/storefront\/api-token`<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">method<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'POST'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">headers<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'X-Auth-Token'<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> process.env.<\/span><span style=\"font-weight: 400;\">BIGCOMMERCE_API_TOKEN<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'Content-Type'<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'application\/json'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">body<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">JSON<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">stringify<\/span><span style=\"font-weight: 400;\">({<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">channel_id<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> channelId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">expires_at<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">+<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.rotationInterval,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">allowed_cors_origins<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> [process.env.<\/span><span style=\"font-weight: 400;\">STOREFRONT_URL<\/span><span style=\"font-weight: 400;\">]<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> { data } <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">await<\/span><span style=\"font-weight: 400;\"> response.<\/span><span style=\"font-weight: 400;\">json<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.tokens.<\/span><span style=\"font-weight: 400;\">set<\/span><span style=\"font-weight: 400;\">(channelId, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">token<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> data.token,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">expiresAt<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> data.expires_at,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">createdAt<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">()<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> data.token;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">isTokenExpiring<\/span><span style=\"font-weight: 400;\">(tokenData) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> timeUntilExpiry <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> tokenData.expiresAt <\/span><span style=\"font-weight: 400;\">-<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> rotationThreshold <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">2<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">60<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">60<\/span> <span style=\"font-weight: 400;\">*<\/span> <span style=\"font-weight: 400;\">1000<\/span><span style=\"font-weight: 400;\">; <\/span><i><span style=\"font-weight: 400;\">\/\/ 2 hours<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> timeUntilExpiry <\/span><span style=\"font-weight: 400;\">&lt;<\/span><span style=\"font-weight: 400;\"> rotationThreshold;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">CORS Configuration for Secure API Access<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Configure Cross-Origin Resource Sharing properly to prevent unauthorized domains from accessing your storefront API while maintaining functionality for legitimate requests.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><b>CORS Setting<\/b><\/td>\n<td><b>Recommended Configuration<\/b><\/td>\n<td><b>Security Impact<\/b><\/td>\n<td><b>Use Case<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">allowed_cors_origins<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Specific domains only<\/span><\/td>\n<td><span style=\"font-weight: 400;\">High security<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Production storefronts<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Token expiration<\/span><\/td>\n<td><span style=\"font-weight: 400;\">1-24 hours<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Medium security<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Balance between security and UX<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Request validation<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Strict mode<\/span><\/td>\n<td><span style=\"font-weight: 400;\">High security<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Payment and checkout operations<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Rate limiting<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Per-token basis<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Prevents abuse<\/span><\/td>\n<td><span style=\"font-weight: 400;\">All API endpoints<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Server-side CORS validation<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">validateCorsOrigin<\/span> <span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> (origin) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> allowedOrigins <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> [<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'https:\/\/store.example.com'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'https:\/\/wholesale.example.com'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'https:\/\/b2b.example.com'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (process.env.<\/span><span style=\"font-weight: 400;\">NODE_ENV<\/span> <span style=\"font-weight: 400;\">===<\/span> <span style=\"font-weight: 400;\">'development'<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0allowedOrigins.<\/span><span style=\"font-weight: 400;\">push<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'http:\/\/localhost:3000'<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> allowedOrigins.<\/span><span style=\"font-weight: 400;\">includes<\/span><span style=\"font-weight: 400;\">(origin);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">};<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Express middleware for CORS handling<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">app.<\/span><span style=\"font-weight: 400;\">use<\/span><span style=\"font-weight: 400;\">((req, res, next) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> origin <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> req.headers.origin;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">validateCorsOrigin<\/span><span style=\"font-weight: 400;\">(origin)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0res.<\/span><span style=\"font-weight: 400;\">header<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'Access-Control-Allow-Origin'<\/span><span style=\"font-weight: 400;\">, origin);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0res.<\/span><span style=\"font-weight: 400;\">header<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'Access-Control-Allow-Methods'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'GET, POST, PUT, DELETE'<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0res.<\/span><span style=\"font-weight: 400;\">header<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'Access-Control-Allow-Headers'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'Content-Type, Authorization'<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0res.<\/span><span style=\"font-weight: 400;\">header<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'Access-Control-Allow-Credentials'<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">'true'<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">next<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">Rate Limiting and Request Throttling<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">Implement request throttling to stay within API rate limits while maintaining optimal performance. The storefront API enforces limits to ensure platform stability.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Client-side rate limiter<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">RateLimiter<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">(maxRequests, timeWindow) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.maxRequests <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> maxRequests; <\/span><i><span style=\"font-weight: 400;\">\/\/ e.g., 100 requests<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.timeWindow <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> timeWindow; <\/span><i><span style=\"font-weight: 400;\">\/\/ e.g., 60000 ms (1 minute)<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.requests <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> [];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">throttleRequest<\/span><span style=\"font-weight: 400;\">(requestFn) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">waitForSlot<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.requests.<\/span><span style=\"font-weight: 400;\">push<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">());<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">cleanOldRequests<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">requestFn<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">waitForSlot<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">while<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.requests.length <\/span><span style=\"font-weight: 400;\">&gt;=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.maxRequests) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> oldestRequest <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.requests[<\/span><span style=\"font-weight: 400;\">0<\/span><span style=\"font-weight: 400;\">];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> timeSinceOldest <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">-<\/span><span style=\"font-weight: 400;\"> oldestRequest;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (timeSinceOldest <\/span><span style=\"font-weight: 400;\">&lt;<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.timeWindow) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> waitTime <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.timeWindow <\/span><span style=\"font-weight: 400;\">-<\/span><span style=\"font-weight: 400;\"> timeSinceOldest;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Promise<\/span><span style=\"font-weight: 400;\">(resolve <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">setTimeout<\/span><span style=\"font-weight: 400;\">(resolve, waitTime));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">cleanOldRequests<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">cleanOldRequests<\/span><span style=\"font-weight: 400;\">() {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> cutoffTime <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">now<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">-<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.timeWindow;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.requests <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.requests.<\/span><span style=\"font-weight: 400;\">filter<\/span><span style=\"font-weight: 400;\">(time <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> time <\/span><span style=\"font-weight: 400;\">&gt;<\/span><span style=\"font-weight: 400;\"> cutoffTime);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Usage with storefront API<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> rateLimiter <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">RateLimiter<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">100<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">60000<\/span><span style=\"font-weight: 400;\">);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">fetchProductData<\/span><span style=\"font-weight: 400;\">(productId) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> rateLimiter.<\/span><span style=\"font-weight: 400;\">throttleRequest<\/span><span style=\"font-weight: 400;\">(() <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0storefrontClient.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">GET_PRODUCT_QUERY<\/span><span style=\"font-weight: 400;\">, { productId })<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h2><span style=\"font-weight: 400;\">Troubleshooting Common API Issues<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Effective troubleshooting accelerates development and maintains storefront reliability when issues arise.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Debugging GraphQL Query Errors<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">GraphQL errors provide detailed information about query problems. Understanding error structures helps quickly identify and resolve issues.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><b>Error Type<\/b><\/td>\n<td><b>Common Causes<\/b><\/td>\n<td><b>Resolution Steps<\/b><\/td>\n<td><b>Prevention Strategy<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Syntax errors<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Malformed queries<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Validate query structure<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Use GraphQL IDE for testing<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Authentication errors<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Invalid tokens<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Regenerate credentials<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Implement token refresh<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Permission errors<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Insufficient scope<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Update token permissions<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Request minimum required scopes<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Rate limit errors<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Too many requests<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Implement throttling<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Use caching and batching<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Comprehensive error handler for storefront API<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">class<\/span> <span style=\"font-weight: 400;\">StorefrontAPIError<\/span> <span style=\"font-weight: 400;\">extends<\/span> <span style=\"font-weight: 400;\">Error<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">constructor<\/span><span style=\"font-weight: 400;\">(message, query, variables, response) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">super<\/span><span style=\"font-weight: 400;\">(message);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.name <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">'StorefrontAPIError'<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.query <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> query;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.variables <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> variables;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">this<\/span><span style=\"font-weight: 400;\">.response <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> response;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">executeQueryWithErrorHandling<\/span><span style=\"font-weight: 400;\">(query, variables) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">await<\/span><span style=\"font-weight: 400;\"> storefrontClient.<\/span><span style=\"font-weight: 400;\">request<\/span><span style=\"font-weight: 400;\">(query, variables);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0} <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> (error) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Parse GraphQL errors<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (error.response<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">errors) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> errorDetails <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> error.response.errors.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(err <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> ({<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">message<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> err.message,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">path<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> err.path,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">extensions<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> err.extensions<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">console<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">error<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'GraphQL Query Errors:'<\/span><span style=\"font-weight: 400;\">, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">errors<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> errorDetails,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">query<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> query,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">variables<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> variables<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Handle specific error types<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> firstError <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> error.response.errors[<\/span><span style=\"font-weight: 400;\">0<\/span><span style=\"font-weight: 400;\">];<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (firstError.extensions<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">code <\/span><span style=\"font-weight: 400;\">===<\/span> <span style=\"font-weight: 400;\">'UNAUTHENTICATED'<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Token expired or invalid - regenerate<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">refreshStorefrontToken<\/span><span style=\"font-weight: 400;\">();<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">executeQueryWithErrorHandling<\/span><span style=\"font-weight: 400;\">(query, variables);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (firstError.extensions<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">code <\/span><span style=\"font-weight: 400;\">===<\/span> <span style=\"font-weight: 400;\">'RATE_LIMITED'<\/span><span style=\"font-weight: 400;\">) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Wait and retry<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Promise<\/span><span style=\"font-weight: 400;\">(resolve <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">setTimeout<\/span><span style=\"font-weight: 400;\">(resolve, <\/span><span style=\"font-weight: 400;\">5000<\/span><span style=\"font-weight: 400;\">));<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">executeQueryWithErrorHandling<\/span><span style=\"font-weight: 400;\">(query, variables);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">throw<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">StorefrontAPIError<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">'GraphQL query failed'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0query,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0variables,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0error.response<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Network or other errors<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">console<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">error<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'API Request Failed:'<\/span><span style=\"font-weight: 400;\">, error);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">throw<\/span><span style=\"font-weight: 400;\"> error;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Handling Product Variant Complexity<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Complex variant structures with multiple options require careful handling to match customer selections with available inventory.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Variant matching algorithm for complex option sets<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">findMatchingVariant<\/span><span style=\"font-weight: 400;\">(product, selectedOptions) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">product.variants<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">edges<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">length) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span> <span style=\"font-weight: 400;\">null<\/span><span style=\"font-weight: 400;\">;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Build option map from selections<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> selectionMap <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Map<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">Object<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">entries<\/span><span style=\"font-weight: 400;\">(selectedOptions).<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(([optionId, valueId]) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0[<\/span><span style=\"font-weight: 400;\">parseInt<\/span><span style=\"font-weight: 400;\">(optionId), <\/span><span style=\"font-weight: 400;\">parseInt<\/span><span style=\"font-weight: 400;\">(valueId)]<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Find variant that matches all selected options<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> matchingVariant <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> product.variants.edges.<\/span><span style=\"font-weight: 400;\">find<\/span><span style=\"font-weight: 400;\">(({ <\/span><span style=\"font-weight: 400;\">node<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> variant }) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> variant.options.<\/span><span style=\"font-weight: 400;\">every<\/span><span style=\"font-weight: 400;\">(option <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectionMap.<\/span><span style=\"font-weight: 400;\">get<\/span><span style=\"font-weight: 400;\">(option.entityId) <\/span><span style=\"font-weight: 400;\">===<\/span><span style=\"font-weight: 400;\"> option.valueEntityId<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">matchingVariant) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Log mismatch for debugging<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">console<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">warn<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'No matching variant found for selections:'<\/span><span style=\"font-weight: 400;\">, {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">productId<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> product.entityId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">selectedOptions<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> selectedOptions,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">availableVariants<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> product.variants.edges.<\/span><span style=\"font-weight: 400;\">map<\/span><span style=\"font-weight: 400;\">(e <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> e.node.entityId)<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> matchingVariant<\/span><span style=\"font-weight: 400;\">?.<\/span><span style=\"font-weight: 400;\">node;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<i><span style=\"font-weight: 400;\">\/\/ Validate option compatibility<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">validateOptionSelection<\/span><span style=\"font-weight: 400;\">(product, optionId, valueId, currentSelections) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> newSelections <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> { <\/span><span style=\"font-weight: 400;\">...<\/span><span style=\"font-weight: 400;\">currentSelections, [optionId]<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> valueId };<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> variant <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">findMatchingVariant<\/span><span style=\"font-weight: 400;\">(product, newSelections);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">!<\/span><span style=\"font-weight: 400;\">variant) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Find compatible values for this option<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> compatibleValues <\/span><span style=\"font-weight: 400;\">=<\/span> <span style=\"font-weight: 400;\">getCompatibleValues<\/span><span style=\"font-weight: 400;\">(<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0product,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0optionId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0currentSelections<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">valid<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">false<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">message<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'This combination is not available'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">compatibleValues<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> compatibleValues<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">valid<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">true<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">variant<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> variant,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">inventory<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> variant.inventory<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h3><span style=\"font-weight: 400;\">Resolving Checkout Integration Issues<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Checkout flow errors require systematic debugging to identify whether issues originate from API configuration, cart state, or payment processing.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">javascript<\/span><\/p>\n<pre><i><span style=\"font-weight: 400;\">\/\/ Comprehensive checkout error handler<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">async<\/span> <span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">handleCheckoutError<\/span><span style=\"font-weight: 400;\">(error, cartId, checkoutData) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> errorLog <\/span><span style=\"font-weight: 400;\">=<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">timestamp<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">new<\/span> <span style=\"font-weight: 400;\">Date<\/span><span style=\"font-weight: 400;\">().<\/span><span style=\"font-weight: 400;\">toISOString<\/span><span style=\"font-weight: 400;\">(),<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">cartId<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> cartId,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">checkoutData<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> checkoutData,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">error<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> error.message,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">stack<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> error.stack<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Log to monitoring service<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">await<\/span> <span style=\"font-weight: 400;\">logError<\/span><span style=\"font-weight: 400;\">(errorLog);<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Determine error category<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (error.message.<\/span><span style=\"font-weight: 400;\">includes<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'inventory'<\/span><span style=\"font-weight: 400;\">)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">type<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'INVENTORY_ERROR'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">message<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'Some items in your cart are no longer available'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">action<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'REFRESH_CART'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">recoverable<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">true<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (error.message.<\/span><span style=\"font-weight: 400;\">includes<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'payment'<\/span><span style=\"font-weight: 400;\">)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">type<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'PAYMENT_ERROR'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">message<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'Payment processing failed. Please try again'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">action<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'RETRY_PAYMENT'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">recoverable<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">true<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (error.message.<\/span><span style=\"font-weight: 400;\">includes<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'shipping'<\/span><span style=\"font-weight: 400;\">)) {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">type<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'SHIPPING_ERROR'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">message<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'Unable to calculate shipping for your address'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">action<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'UPDATE_ADDRESS'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">recoverable<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">true<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Unrecoverable error<\/span><\/i>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">return<\/span><span style=\"font-weight: 400;\"> {<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">type<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'CHECKOUT_ERROR'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">message<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'An error occurred during checkout. Please contact support'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">action<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">'CONTACT_SUPPORT'<\/span><span style=\"font-weight: 400;\">,<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">recoverable<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">false<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0};<\/span>\r\n\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n<span style=\"font-weight: 400;\">Key Takeaways<\/span><\/pre>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The BigCommerce storefront API transforms how developers build and customize online shopping experiences through flexible GraphQL queries and modern architecture patterns<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Implement proper authentication and token management to secure API access across all storefronts<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Optimize query performance through strategic field selection, effective caching layers, and cursor-based pagination for large data sets<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Leverage the comprehensive <a href=\"https:\/\/ecommerce.folio3.com\/blog\/bigcommerce-api-documentation\/\">BigCommerce GraphQL storefront API documentation when building custom<\/a> implementations and troubleshooting integration challenges<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Configure multi storefront API SSO capabilities carefully to enable seamless customer experiences across multiple channels while maintaining security boundaries<\/span><\/li>\n<\/ul>\n<h2><span style=\"font-weight: 400;\">Conclusion<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The BigCommerce storefront API delivers the flexibility and power needed to create exceptional shopping experiences through GraphQL-based queries, headless commerce capabilities, and multi storefront management. Whether you&#8217;re implementing advanced product configurators or managing multiple channels with unified authentication, the API provides robust capabilities for modern ecommerce development.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Ready to transform your BigCommerce storefront with custom API implementations?<\/span><a href=\"https:\/\/ecommerce.folio3.com\/contact-us\/\"> <span style=\"font-weight: 400;\">Contact our expert development team<\/span><\/a><span style=\"font-weight: 400;\"> to discuss your project requirements and leverage the full potential of the BigCommerce storefront API.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Frequently Asked Questions<\/span><\/h2>\n<h3><span style=\"font-weight: 400;\">How Does the BigCommerce Storefront API Differ From the Management API?<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">The storefront API handles customer-facing operations like product browsing, cart management, and checkout. The management API manages backend tasks, including inventory updates, order processing, and catalog administration. Use the storefront API for shopping experiences, management API for administrative tasks requiring elevated permissions.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Can I Use the BigCommerce GraphQL Storefront API With Any Frontend Framework?<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Yes. The API works with any framework capable of HTTP requests and JSON handling. Popular choices include React, Vue, Next.js, Angular, and Gatsby. Select based on team expertise, SEO requirements, and performance needs.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">What Are the Rate Limits for BigCommerce Storefront API Requests?<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">BigCommerce applies rate limiting per storefront token. Limits vary by store plan and usage. Implement caching, request batching, and throttling to stay within limits. Check API response headers for rate limit details.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">How Do I Implement Customer Authentication With the Storefront API?<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Generate customer impersonation tokens through the Customer Login API endpoint. Include tokens in storefront API request headers to authenticate customers. This enables personalized features like order history and account management. Tokens expire and require regeneration.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Can the Storefront API Handle Complex Product Variants and Options?<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Yes. Query the product Options field for available choices and the variants collection for inventory data. Match customer selections to variants using option entity IDs and value entity IDs for accurate pricing and availability.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building custom shopping experiences demands direct control over your store&#8217;s data and presentation layer. The BigCommerce storefront API delivers this capability through a modern GraphQL interface that gives developers precise control over data retrieval and storefront customization. Unlike traditional REST APIs that return fixed data structures, the storefront API lets you request exactly the information<\/p>\n","protected":false},"author":50,"featured_media":22483,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[28],"tags":[195],"class_list":{"0":"post-22478","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-bigcommerce","8":"tag-bigcommerce-storefront-api"},"acf":[],"featured_image_data":{"src":"https:\/\/ecommerce.folio3.com\/blog\/wp-content\/uploads\/2023\/12\/5596321_55872_750x394.webp","alt":"BigCommerce Storefront API Guide: GraphQL Setup, Documentation, and Multi-Storefront Implementation","caption":""},"_links":{"self":[{"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/posts\/22478"}],"collection":[{"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/users\/50"}],"replies":[{"embeddable":true,"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/comments?post=22478"}],"version-history":[{"count":0,"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/posts\/22478\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/media\/22483"}],"wp:attachment":[{"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/media?parent=22478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/categories?post=22478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ecommerce.folio3.com\/blog\/wp-json\/wp\/v2\/tags?post=22478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}