Storefront configuration
In this section, you’ll learn how Commerce blocks in your storefront connect to a Commerce backend using values from either the public config for your site or a config.json file in your code repo.
The configuration is organized into several key sections:
- Endpoints - GraphQL endpoints for Commerce and Catalog Services
- Headers - HTTP headers required for API authentication and store context
- Analytics - Store and environment metadata for tracking and reporting
- Plugins - Configuration for various Edge Delivery Services plugins and features
- Multistore - Settings for multiple store views and internationalization
When implementing your own project, you must update the configuration values with:
- The Adobe Commerce and Catalog Service GraphQL endpoint that you configured as part of the content delivery network (CDN) setup.
- The header values specific to your Adobe Commerce Catalog Services environment.
If you set up your storefront using the boilerplate code, refer to the config generator tool to generate a config.json file for your Commerce backend. This file will contain the environment values for a Commerce backend including GraphQl endpoints and headers.
If you set up your site using the Site Creator Tool , the config.json file is created and added to the GitHub repository created for the boilerplate code. You can review and update the default values in the config.json file after the process completes.
Vocabulary
Storefront configuration
A JSON object that maps properties and values used by the Commerce boilerplate.
The storefront configuration is a JSON object which lives in the config-service and contains the connection settings for your Commerce blocks. You can use the live demo configuration for the boilerplate as a starting point: https://main--aem-boilerplate-commerce--hlxsites.aem.live/config.json , or generate a config with your own values using the config generator tool .
At the root, there is a public property which should not be changed, and a nested default object. This default object is the root level configuration that is used for your storefront. The config object contains properties and values which correspond to a specific setting or usage in your Commerce backend.
If you use aem.live’s config service, your config will live at https://admin.hlx.page/config/{{ORG}}/sites/{{SITE}}/public.json but can be overwritten with a local /config.json file in your code repo.
default values
The demo configuration for the boilerplate uses values from a sample Commerce backend to ensure everything works out of the box. When it comes time to connect your own backend, you need to know what each key means so you can update it with the correct value from your own Commerce instance.
getConfigValue function
The getConfigValue function is a helper function that retrieves the value from the configs file using the dot-notation path as an argument. For example, getConfigValue('headers.cs.x-api-key') returns the value of [root config].headers.cs.x-api-key.
getHeaders function
The getHeaders function is a helper function which takes a storefront scope (like cs, cart, etc) and reads values from the configs file with the corresponding header keys and returns an object map of those rows. For example, if you have properties in config like headers.cs.Magento-Environment-Id": "abc-123", then getHeaders('cs') will return an object like { "Magento-Environment-Id": "abc-123"}.
Configuration Caching
The storefront configuration is cached at multiple levels to optimize performance:
-
CDN Caching: The configuration file is cached by the EDS CDN with a
max-age=7200(2 hours) cache control header. This means configuration changes can take up to 2 hours to be reflected on the CDN after deployment. -
Browser Caching: When the configuration is loaded in the browser, it is stored in session storage , which persists until the browser session is cleared.
For developers: After making configuration changes, it can take up to two hours for the CDN cache to expire. Clear your browser’s session storage to see updates. Verify the current cache configuration by accessing <site.com>/config.json directly and checking the last-modified header.
Configuration Sections
The following sections detail each part of your configuration for Adobe Commerce. Each section includes placeholders (marked with {{PLACEHOLDER}}) that you must replace with your specific Commerce environment details.
You can find your configuration in your code repo at /config.json, or in the config service for your site. If you do not have a configuration yet, you can:
- Copy and customize the demo config for the boilerplate: https://main--aem-boilerplate-commerce--hlxsites.aem.live/config.json .
- Or use the Config Generator tool to generate a configuration with your backend values (may contain placeholders to fill in).
Be sure to update all values to match your Commerce backend before deploying.
Endpoints
The endpoints properties define the GraphQL API endpoints for your Commerce backend.
{ "commerce-core-endpoint": "{{COMMERCE_CORE_ENDPOINT}}", "commerce-endpoint": "{{COMMERCE_ENDPOINT}}"}Configuration Properties:
-
commerce-core-endpoint(read/write) - Core GraphQL endpoint for queries and mutations. This endpoint handles all write operations and some read operations. See Adobe Commerce GraphQL API for details. -
commerce-endpoint(read-only) - Services GraphQL endpoint optimized for read-only operations with Catalog Service, Live Search, and Product Recommendations. It is also optimized for performance for product data retrieval. For details, see the following documentation:- For Adobe Commerce as a Cloud Service, see the Catalog Service Guide .
- For Adobe Commerce Optimizer, see the Merchandising Services Developer Guide .
Headers
The headers section defines HTTP headers required for API authentication and store context. Headers are organized by scope to apply different authentication and context settings for different request types. The specific headers required depend on your Commerce environment type.
Adobe Commerce PaaS environments use standard Adobe Commerce header naming conventions and require API keys for SaaS services.
{ "headers": { "all": { "Store": "{{STORE_VIEW_CODE}}" }, "cs": { "Magento-Store-Code": "{{STORE_CODE}}", "Magento-Store-View-Code": "{{STORE_VIEW_CODE}}", "Magento-Website-Code": "{{WEBSITE_CODE}}", "x-api-key": "{{API_KEY}}", "Magento-Environment-Id": "{{ENVIRONMENT_ID}}" } }}Header Scopes:
-
all- Headers applied to all GraphQL requestsStore- Store view code for Core GraphQL requests. See GraphQL Headers for details.
-
cs- Headers for Catalog Service requestsMagento-Store-Code- Store to connect to. See Create stores for details.Magento-Store-View-Code- Store view for Catalog Service requests. See Store views for details.Magento-Website-Code- Website to connect to. See Create websites for details.x-api-key- API key for SaaS services (Catalog Service, Live Search, Product Recommendations). See Commerce Services Connector for details.Magento-Environment-Id- Connects the storefront to the cloud instance serving it. See Cloud Environment overview for details.
Adobe Commerce as a Cloud Service uses standard Adobe Commerce header naming conventions but does not require API keys or environment IDs in the default configuration.
{ "headers": { "all": { "Store": "{{STORE_VIEW_CODE}}" }, "cs": { "Magento-Store-Code": "{{STORE_CODE}}", "Magento-Store-View-Code": "{{STORE_VIEW_CODE}}", "Magento-Website-Code": "{{WEBSITE_CODE}}" } }}Header Scopes:
-
all- Headers applied to all GraphQL requestsStore- Store view code for Core GraphQL requests. See GraphQL Headers for details.
-
cs- Headers for Catalog Service requestsMagento-Store-Code- Store to connect to. See Create stores for details.Magento-Store-View-Code- Store view for Catalog Service requests. See Store views for details.Magento-Website-Code- Website to connect to. See Create websites for details.
Adobe Commerce Optimizer uses different header naming conventions and requires Commerce Optimizer-specific headers as defined in the Merchandising Services API documentation .
{ "headers": { "cs": { "AC-View-ID": "{{CATALOG_VIEW_ID}}", "AC-Source-Locale": "{{LOCALE}}", "AC-Price-Book-ID": "{{PRICE_BOOK_ID}}", "AC-Policy-{{*}}": "{{ATTRIBUTE_VALUE}}" } }}Header Scopes:
cs- Headers applied to all GraphQL requestsAC-View-ID- (Required) The unique ID assigned to the catalog view that products will be sold through. You can find this in the Adobe Commerce Optimizer UI .AC-Source-Locale- (Required) Catalog source locale (language or geography) to filter products for display, for exampleen_US. See the catalog view configuration to determine the correct value.AC-Price-Book-ID- (Optional) Specifies the Price Book ID to use for pricing. Each catalog view defines a default Price Book. If a customer has an assigned Price Book, it is used when it falls within the allowed Price Books for the catalog view. Otherwise, the default Price Book for the catalog view is used. See Price Book ID setup for implementation details.AC-Policy-{{*}}- (Optional) Policy trigger for filtering products by attribute. The header should match the “name” of the trigger. For example,AC-Policy-Brand:Cruzfor brand filtering using “Cruz”. You can specify multiple policy headers per request.
Analytics
The analytics section contains store and environment metadata for tracking and reporting. The specific values depend on your Commerce environment type.
For Adobe Commerce PaaS and Adobe Commerce as a Cloud Service environments, use standard Commerce store and website identifiers from your Commerce Environment. You can obtain these values using a storeConfig query.
{ "analytics": { "aep-ims-org-id": "{{IMS_ORG_ID}}", "aep-datastream-id": "{{DATASTREAM_ID}}", "base-currency-code": "{{CURRENCY_CODE}}", "environment": "{{ENVIRONMENT_TYPE}}", "environment-id": "{{ENVIRONMENT_ID}}", "store-code": "{{STORE_CODE}}", "store-id": {{STORE_ID}}, "store-name": "{{STORE_NAME}}", "store-url": "{{STORE_URL}}", "store-view-code": "{{STORE_VIEW_CODE}}", "store-view-id": {{STORE_VIEW_ID}}, "store-view-name": "{{STORE_VIEW_NAME}}", "website-code": "{{WEBSITE_CODE}}", "website-id": {{WEBSITE_ID}}, "website-name": "{{WEBSITE_NAME}}" }}Configuration Properties:
aep-ims-org-id- (Optional) Adobe IMS Organization ID for Experience Platform integration (for example,"1234567890ABCDEF7F000101@AdobeOrg")aep-datastream-id- (Optional) Datastream ID for routing data to Adobe Experience Platform (for example,"12345678-1234-1234-1234-123456789012")base-currency-code- The base currency code for the store (for example, “USD”, “EUR”)environment- Environment type (“Production”, “Testing”)environment-id- Unique identifier for the Commerce environmentstore-url- Base URL for the storestore-code- Code identifier for the store from your Commerce environmentstore-id- Numeric ID for the storestore-name- Display name for the storestore-view-code- Code identifier for the store viewstore-view-id- Numeric ID for the store viewstore-view-name- Display name for the store viewwebsite-code- Code identifier for the website from your Commerce environmentwebsite-id- Numeric ID for the websitewebsite-name- Display name for the website
For Adobe Commerce Optimizer environments, use a simplified analytics configuration structure:
{ "analytics": { "aep-ims-org-id": "{{IMS_ORG_ID}}", "aep-datastream-id": "{{DATASTREAM_ID}}", "base-currency-code": "{{CURRENCY_CODE}}", "environment": "{{ENVIRONMENT_TYPE}}", "environment-id": "{{YOUR_TENANT_ID}}", "locale": "{{LOCALE}}", "store-url": "{{STORE_URL}}", "store-view-currency-code": "{{CURRENCY_CODE}}", "storefront-template": "{{TEMPLATE_TYPE}}", "view-id": "{{CATALOG_VIEW_ID}}" }}Configuration Properties:
aep-ims-org-id- (Optional) Adobe IMS Organization ID for Experience Platform integration (for example,"1234567890ABCDEF7F000101@AdobeOrg")aep-datastream-id- (Optional) Datastream ID for routing data to Adobe Experience Platform (for example,"12345678-1234-1234-1234-123456789012")base-currency-code- The base currency code for the store (for example, “USD”, “EUR”)environment- Environment type (“Production”, “Testing”)environment-id- The tenant ID for the Adobe Commerce Optimizer instancelocale- Catalog source locale (language or geography) for the store view, for exampleen-USstore-url- Base URL for the storestore-view-currency-code- Currency code for the store view (for example, “USD”, “EUR”)storefront-template- (Optional) Storefront template type (for example, “Other”)view-id- The unique ID assigned to the catalog view from the Adobe Commerce Optimizer UI
Plugins
The plugins section configures various Commerce plugins and features.
{ "plugins": { "picker": { "rootCategory": "{{ROOT_CATEGORY_ID}}" } }}Configuration Properties:
picker.rootCategory- Root category ID for the product picker. This determines which category serves as the starting point when browsing products in the Commerce interface.
Multistore
The multistore section manages configurations for multiple store views and internationalization. This allows different configurations for different locales or store views. Each non-”default” configuration will be merged with the default at runtime and used for the corresponding locale or store view. For example, the below would serve as a basis for configuration for the site at aemshop.net/fr.
{ "/fr/": { "headers": { "all": { "Store": "{{FRENCH_STORE_VIEW_CODE}}" }, "cs": { "Magento-Store-Code": "{{FRENCH_STORE_CODE}}", "Magento-Website-Code": "{{FRENCH_WEBSITE_CODE}}", "Magento-Store-View-Code": "{{FRENCH_STORE_VIEW_CODE}}" } } }}Configuration Properties:
- Path-based configuration - Use URL paths (like
/fr/,/de/, etc.) to define locale-specific or store-specific overrides - Header overrides - Override default headers for specific store views
- Store context - Define different store, website, and store view codes for each locale
Additional Configuration Options
Some configuration options can be set to enable or disable certain boilerplate features.
{ "commerce-assets-enabled": boolean, "commerce-companies-enabled": boolean,}commerce-assets-enabled- Boolean flag to enable or disable AEM Assets within the storefrontcommerce-companies-enabled- Boolean flag to enable or disable Commerce B2B features within the storefront
Configuration Examples
The following examples show real config.json files from different Adobe Commerce environments. These examples demonstrate the actual structure and values used in production environments.
This example shows the configuration for an Adobe Commerce PaaS environment, which includes additional features like multistore support and asset management. This configuration is used on this site: https://www.aemshop.net/
{ "public": { "default": { "commerce-core-endpoint": "https://www.aemshop.net/graphql", "commerce-endpoint": "https://www.aemshop.net/cs-graphql", "headers": { "all": { "Store": "default" }, "cs": { "Magento-Store-Code": "main_website_store", "Magento-Store-View-Code": "default", "Magento-Website-Code": "base", "x-api-key": "4dfa19c9fe6f4cccade55cc5b3da94f7", "Magento-Environment-Id": "f38a0de0-764b-41fa-bd2c-5bc2f3c7b39a" } }, "analytics": { "aep-ims-org-id": null, "aep-datastream-id": null, "base-currency-code": "USD", "environment": "Production", "environment-id": "f38a0de0-764b-41fa-bd2c-5bc2f3c7b39a", "store-code": "main_website_store", "store-id": 1, "store-name": "Main Website Store", "store-url": "https://www.aemshop.net", "store-view-code": "default", "store-view-id": 1, "store-view-name": "Default Store View", "website-code": "base", "website-id": 1, "website-name": "Main Website" }, "plugins": { "picker": { "rootCategory": "2" } }, "commerce-assets-enabled": false }, "/fr/": { "headers": { "all": { "Store": "fr" }, "cs": { "Magento-Store-Code": "fr_store", "Magento-Website-Code": "fr_website", "Magento-Store-View-Code": "fr" } } } }}This example shows the configuration for Adobe Commerce as a Cloud Service, which uses standard Adobe Commerce header naming conventions. This configuration is used on this site: https://main—boilerplate-accs—adobe-commerce.aem.live/
{ "public": { "default": { "commerce-core-endpoint": "https://na1-sandbox.api.commerce.adobe.com/LwndYQs37CvkUQk9WEmNkz/graphql", "commerce-endpoint": "https://na1-sandbox.api.commerce.adobe.com/LwndYQs37CvkUQk9WEmNkz/graphql", "headers": { "all": { "Store": "default" }, "cs": { "Magento-Store-Code": "main_website_store", "Magento-Store-View-Code": "default", "Magento-Website-Code": "base" } }, "analytics": { "base-currency-code": "USD", "environment": "Testing", "environment-id": "LwndYQs37CvkUQk9WEmNkz", "store-code": "main_website_store", "store-id": 1, "store-name": "ACCS Store", "store-url": "https://main--boilerplate-accs--adobe-commerce.aem.live", "store-view-code": "default", "store-view-id": 1, "store-view-name": "Default Store View", "website-code": "base", "website-id": 1, "website-name": "Main Website" }, "plugins": { "picker": { "rootCategory": "2" } } } }}This example shows the configuration for Adobe Commerce Optimizer, which uses different header naming conventions and includes Optimizer-specific settings. This configuration is used on this site: https://main—boilerplate-aco—adobe-commerce.aem.live/
{ "public": { "default": { "commerce-core-endpoint": "https://na1-sandbox.api.commerce.adobe.com/8idEEDDiVwjCEJAyB5kjfi/graphql", "commerce-endpoint": "https://na1-sandbox.api.commerce.adobe.com/8idEEDDiVwjCEJAyB5kjfi/graphql", "headers": { "cs": { "ac-view-id": "0d3eebf7-b5fb-4904-9ccf-f35fcc61862b", "ac-price-book-id": "west_coast_inc", "ac-scope-locale": "en-US" } }, "analytics": { "base-currency-code": "USD", "environment": "Testing", "environment-id": "8idEEDDiVwjCEJAyB5kjfi", "locale": "en-US", "store-url": "https://main--boilerplate-aco--adobe-commerce.aem.live/", "store-view-currency-code": "USD", "storefront-template": "Other", "view-id": "0d3eebf7-b5fb-4904-9ccf-f35fcc61862b" }, "plugins": { "picker": { "rootCategory": "2" } } } }}Local Development
Understanding how storefront configuration resolution works is essential for effective local development and branch-based testing. This section explains how the browser retrieves configuration and how to manage it across different environments.
How Configuration Resolution Works
When your storefront loads in the browser, the following sequence occurs:
- Browser requests
https://[site]/config.json - EDS CDN checks if a
config.jsonfile exists in the code repository root - If found - The
config.jsonfile from the repository is served - If not found - The CDN falls back to the
publicconfig from the EDS site config
Important: A committed config.json file in your repository will always take precedence over the public config from EDS site config.
Getting a starter configuration
To get a configuration for your Commerce storefront, you have two options:
-
Copy the demo configuration: Download and customize the live configuration for the boilerplate from https://main--aem-boilerplate-commerce--hlxsites.aem.live/config.json . This provides a working example with all required fields.
-
Generate with your values: Use the config generator tool to automatically generate a configuration for your Commerce backend. Note that the generated config may contain placeholders that you’ll need to replace with actual values.
Important: Always update the configuration values to match your specific Commerce backend before deploying to production.
Local Development Configuration
To work with your own Commerce backend locally:
-
Get your configuration from the config generator tool:
- Visit the config generator tool and enter your API url.
- Copy the configuration to your clipboard and paste it into your
config.jsonfile in your code repo.
-
Edit config.json with your Commerce backend values:
- Update
commerce-endpointandcommerce-core-endpoint(if needed) - Update
headersfor authentication - Update
analyticsvalues for your store - Update any other values as needed, such as
commerce-assets-enabled, etc.
- Update
-
Add config.json to .gitignore (optional):
echo "config.json" >> .gitignoreThis prevents you from accidentally committing your local configuration.
-
Clear session storage and reload:
- Open browser DevTools (F12)
- Go to Application > Session Storage
- Delete the
configentry - Reload the page
-
Verify the configuration loaded:
- Check
http://localhost:3000/config.jsonin your browser - Or check Application > Session Storage >
configentry in DevTools
- Check
Branch-Based Configuration
You can commit config.json to any branch to provide branch-specific configuration. Understanding the behavior based on which branch you commit to is crucial:
Committing to a feature/test branch:
- Commit
config.jsonto your branch (for example,feature/new-backend). - When deployed,
https://[branch]--[site]--[org].aem.page/config.jsonwill serve the configuration for your branch. - The
mainbranch and other branches are unaffected. - Public config is NOT used for this branch.
Committing to main branch:
- If you commit
config.jsontomain, it will ALWAYS be served. - Public config from EDS site config will NEVER be used (unless you delete
config.jsonfrom main). - All branches without their own
config.jsonwill inherit the configuration from main. - Use this approach only if you want repository-based configuration for production.
Using public config (Recommended for production):
- Do NOT commit
config.jsontomain. - Configure the
publicproperty in your EDS site config via the Configuration Service . - Access at
https://admin.hlx.page/config/{ORG}/sites/{SITE}/public.json. - Update configuration without code deployments.
- Any branch with a committed
config.jsonwill be used (on that branch) instead of this public config.
Testing Configuration Changes
After creating or updating your configuration (either in public config or config.json), follow these steps to verify the changes:
-
Deploy or save your changes:
- For repository-based: Commit and push
config.json - For public config: Update via the Configuration Service API
- For repository-based: Commit and push
-
Clear session storage:
- Open browser DevTools (F12)
- Navigate to Application tab > Session Storage
- Find and delete the
configentry for your domain
-
Reload the page:
- Hard refresh (Ctrl+Shift+R or Cmd+Shift+R)
- Or simply reload after clearing session storage
-
Verify the configuration:
- In DevTools, go to Application > Session Storage
- Check the
configentry contains your updated values - Or access
https://[your-site]/config.jsondirectly in the browser
Step-by-step
We’ll use a mock PDP / Catalog Service block to demonstrate how to utilize the config utilities and values. This example shows how to access the configuration sections detailed above.
Import the configuration functions.
First, import the getConfigValue and getHeaders functions from the scripts/configs.js file in your boilerplate.
import { getConfigValue, getHeaders } from '../../scripts/configs.js';Access endpoint configuration.
Use the getConfigValue function to retrieve endpoint URLs from the configuration. This function takes a dot-notation path that matches the keys in your config.json.
export default async function decorate(block) { // Get the catalog service endpoint from the endpoints section const catalogEndpoint = await getConfigValue('commerce-endpoint'); const coreEndpoint = await getConfigValue('commerce-core-endpoint');
console.log('Catalog Service endpoint:', catalogEndpoint); console.log('Core Commerce endpoint:', coreEndpoint);}Access header configuration.
Use the getHeaders function to retrieve headers for specific scopes. This function automatically formats the headers for use in HTTP requests.
export default async function decorate(block) { // Get headers for Catalog Service requests const csHeaders = await getHeaders('cs');
// Get headers for all requests const allHeaders = await getHeaders('all');
console.log('CS headers:', csHeaders); console.log('All headers:', allHeaders);}Access analytics and other configuration.
Use getConfigValue to access any configuration value using dot notation, including analytics data and plugin settings.
export default async function decorate(block) { // Get analytics configuration const storeUrl = await getConfigValue('analytics.store-url'); const currency = await getConfigValue('analytics.base-currency-code'); const environment = await getConfigValue('analytics.environment');
// Get plugin configuration const rootCategory = await getConfigValue('plugins.picker.rootCategory');
console.log('Store URL:', storeUrl, 'Currency:', currency, 'Environment:', environment); console.log('Root category:', rootCategory);}Make API requests with configuration.
Combine the endpoint and header configuration to make authenticated API requests to your Commerce backend.
export default async function decorate(block) { // Get the catalog service endpoint const endpoint = await getConfigValue('commerce-endpoint');
// Get the catalog service required headers const headers = await getHeaders('cs');
// Make the API request const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', ...headers }, body: JSON.stringify({ query: `query { products { items { name } } }` }) });
const data = await response.json(); // Process the response data}Summary
The Commerce configuration provides a structured approach to connecting your storefront to Adobe Commerce backends. By organizing settings into clear sections for endpoints, headers, analytics, plugins, and multistore configurations, you can easily customize your storefront for different Commerce environments. The configuration system supports Adobe Commerce (PaaS), Adobe Commerce as a Cloud Service (SaaS), and Adobe Commerce Optimizer, each with specific header requirements and authentication methods. For local development and testing, you can use a config.json file in your repository or the public config from the Configuration Service, with repository files taking precedence. Use the getConfigValue and getHeaders helper functions to access these settings in your Commerce blocks, ensuring consistent and maintainable integration with your Commerce backend.