Skip to content
The Boilerplate

Configuration

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

Boilerplate version: 4.0.1

Configuration Overview

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

  • Local development - demo-config.json file for Commerce backend connection
  • Production deployment - Configuration Service with template files for site setup
  • Drop-in initialization - Initializer files in scripts/initializers/

Demo Configuration (Local Development)

The demo-config.json file provides configuration for local development. It connects to the boilerplate’s sample Commerce backend:

{
"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"
}
}
}
}
}

Local vs Production Configuration

For local development:

  • The AEM CLI automatically serves demo-config.json as /config.json at runtime
  • No renaming required - the file works out of the box with the demo Commerce backend
  • To connect your own backend locally, edit the values in demo-config.json directly

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) - Rename demo-config.json to config.json in your repository root, update the values with your production Commerce backend details, and commit the file. Edge Delivery Services will serve this file at /config.json in production.

Production Configuration Templates

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

default-site.json

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": "{CS_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": {
"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"
},
"sidekick": {
"project": "Boilerplate",
"plugins": [
{
"id": "cif",
"title": "Commerce",
"environments": ["edit"],
"url": "https://main--{SITE}--{ORG}.aem.live/tools/picker/dist/index.html",
"isPalette": true,
"paletteRect": "top: 54px; left: 5px; bottom: 5px; width: 300px; height: calc(100% - 59px); border-radius: var(--hlx-sk-button-border-radius); overflow: hidden; resize: horizontal."
},
{
"id": "personalisation",
"title": "Personalisation",
"environments": ["edit"],
"url": "https://main--{SITE}--{ORG}.aem.live/tools/segments/dist/index.html",
"isPalette": true,
"paletteRect": "top: 54px; left: 5px; bottom: 5px; width: 300px; height: calc(100% - 59px); border-radius: var(--hlx-sk-button-border-radius); overflow: hidden; resize: horizontal."
}
]
},
"access": {
"admin": {
"role": {
"config_admin": ["{ADMIN_USER_EMAIL}"]
},
"requireAuth": "auto"
}
}
}

Replace the {PLACEHOLDER} values with your actual configuration.

default-fstab.yaml

Content source and folder mapping configuration:

mountpoints:
/:
url: https://content.da.live/{org}/{site}/
type: markup
folders:
/products/: /products/default

The mountpoints define where content is authored, and folders map URL paths to content directories.

default-query.yaml

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'), '([^,]+)')

default-sitemap.yaml

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.

Drop-in Initializers

Configure individual drop-ins in scripts/initializers/:

Example: cart.js

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 });
})();

Environment-Specific Configuration