Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

The Boilerplate

Blocks configuration

The AEM Commerce boilerplate requires configuration to connect to your Adobe Commerce instance and customize the storefront behavior.

Boilerplate version: 4.0.1

The boilerplate uses multiple configuration files depending on your deployment stage:

  • Local development - Copy of the demo configuration for Commerce backend connection
  • Production deployment - Configuration Service with template files for site setup
  • Drop-in initialization - Initializer files in scripts/initializers/

Which endpoints you set depends on your Commerce backend:

  • Adobe Commerce as a Cloud Service (ACCS) — Set only commerce-endpoint to your ACCS GraphQL endpoint URL.
  • Adobe Commerce Optimizer (ACO) — Set commerce-endpoint to your ACO GraphQL URL (catalog) and commerce-core-endpoint to your Commerce core endpoint URL (PaaS or your own Adobe Commerce hosted environment).

For full details and examples, see Storefront configuration.

For local development, you can use the demo configuration for the boilerplate as a starting point. The live demo configuration is available at https://main--aem-boilerplate-commerce--hlxsites.aem.live/config.json and connects to the sample Commerce backend for the boilerplate:

{
"public": {
"default": {
"commerce-core-endpoint": "https://www.aemshop.net/graphql",
"commerce-endpoint": "https://www.aemshop.net/cs-graphql",
"commerce-assets-enabled": false,
"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": {
"base-currency-code": "USD",
"environment": "Testing",
"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": "YOUR_ROOT_CATEGORY_ID"
}
}
}
}
}

For local development:

For production deployment, choose one of these options:

  1. Configuration Service (Recommended) - Use the Configuration Service, which stores configuration at https://admin.hlx.page/config/{ORG}/sites/{SITE}/public.json. This approach stores configuration in the same format as the public section in default-site.json and allows configuration updates without code deployments. Note that a local config.json in your repository will override the Configuration Service.

  2. Repository-based config (Simple) - Create a config.json file in your repository root with your production Commerce backend details and commit the file. Edge Delivery Services will serve this file at /config.json in production. Start with either the demo config or use the config generator tool, then update all values to match your backend.

The boilerplate includes template configuration files with placeholders for your site setup:

Comprehensive site configuration template for production deployment:

{
"version": 1,
"code": {
"owner": "{ORG}",
"repo": "{REPO}",
"source": {
"type": "github",
"url": "https://github.com/{ORG}/{REPO}"
}
},
"content": {
"source": {
"url": "{CONTENT_SOURCE}",
"type": "onedrive"
}
},
"folders": {
"/products/": "/products/default"
},
"cdn": {
"live": {
"host": "main--{SITE}--{ORG}.aem.live"
},
"preview": {
"host": "main--{SITE}--{ORG}.aem.page"
}
},
"headers": {},
"public": {
"default": {
"commerce-core-endpoint": "{ENDPOINT}",
"commerce-endpoint": "{CATALOG_ENDPOINT}",
"headers": {
"all": {
"Store": "default"
},
"cs": {
"Magento-Store-Code": "{STORE_CODE}",
"Magento-Store-View-Code": "{STORE_VIEW_CODE}",
"Magento-Website-Code": "{WEBSITE_CODE}",
"x-api-key": "{COMMERCE_API_KEY}",
"Magento-Environment-Id": "{COMMERCE_ENVIRONMENT_ID}"
}
},
"analytics": {
"aep-ims-org-id": "{IMS_ORG_ID}",
"aep-datastream-id": "{DATASTREAM_ID}",
"base-currency-code": "USD",
"environment": "Production",
"store-id": "{STORE_ID}",
"store-name": "Main Website Store",
"store-url": "{DOMAIN}",
"store-view-id": "{STORE_VIEW_ID}",
"store-view-name": "Default Store View",
"website-id": "{WEBSITE_ID}",
"website-name": "Main Website"
},
"plugins": {
"picker": {
"rootCategory": "{YOUR_ROOT_CATEGORY_ID}"
}
}
}
},
"robots": {
"txt": "User-agent: *\nAllow: /\nDisallow: /drafts/\nDisallow: /enrichment/\nDisallow: /tools/\nDisallow: /plugins/experimentation/\n\nSitemap: https://{DOMAIN}/sitemap-index.xml"
},
"access": {
"admin": {
"role": {
"config_admin": ["{ADMIN_USER_EMAIL}"]
},
"requireAuth": "auto"
}
}
}

Replace the {PLACEHOLDER} values with your actual configuration.

Content indexing configuration for generating sitemap and enrichment data:

version: 1
indices:
sitemap:
target: /sitemap.json
exclude:
- 'drafts/**'
- 'enrichment/**'
- 'fragments/**'
- 'products/**'
properties:
title:
select: head > meta[property="og:title"]
value: |
attribute(el, 'content')
image:
select: head > meta[property="og:image"]
value: |
attribute(el, 'content')
description:
select: head > meta[name="description"]
value: |
attribute(el, 'content')
template:
select: head > meta[name="template"]
value: |
attribute(el, 'content')
robots:
select: head > meta[name="robots"]
value: |
attribute(el, 'content')
lastModified:
select: none
value: parseTimestamp(headers["last-modified"], "ddd, DD MMM YYYY hh:mm:ss GMT")
enrichment:
target: /enrichment/enrichment.json
include:
- '**/enrichment/**'
properties:
title:
select: head > meta[property="og:title"]
value: |
attribute(el, 'content')
products:
select: head > meta[name="enrichment-products"]
values: |
match(attribute(el, 'content'), '([^,]+)')
categories:
select: head > meta[name="enrichment-categories"]
values: |
match(attribute(el, 'content'), '([^,]+)')
positions:
select: head > meta[name="enrichment-positions"]
values: |
match(attribute(el, 'content'), '([^,]+)')

Sitemap generation configuration:

sitemaps:
default:
source: /sitemap.json
destination: /sitemap-content.xml
lastmod: YYYY-MM-DD

The sitemap reads from the generated sitemap.json (created by default-query.yaml) and outputs an XML sitemap.

Configure individual drop-ins in scripts/initializers/:

import { initializers } from '@dropins/tools/initializer.js';
import { initialize, setEndpoint } from '@dropins/storefront-cart/api.js';
import { initializeDropin } from './index.js';
import { CORE_FETCH_GRAPHQL, fetchPlaceholders } from '../commerce.js';
await initializeDropin(async () => {
// Set Fetch GraphQL (Core)
setEndpoint(CORE_FETCH_GRAPHQL);
// Fetch placeholders
const labels = await fetchPlaceholders('placeholders/cart.json');
const langDefinitions = {
default: {
...labels,
},
};
// Initialize cart
return initializers.mountImmediately(initialize, { langDefinitions });
})();