BigCommerce Stencil Theme Development
Before writing code
Fetch live docs:
- Fetch
https://developer.bigcommerce.com/docs/storefront/stencil for Stencil overview
- Fetch
https://developer.bigcommerce.com/docs/storefront/stencil/themes/context/object-reference for theme object reference
- Web-search
site:developer.bigcommerce.com stencil handlebars helpers for Handlebars helper reference
Architecture
How Stencil Works
Stencil is BigCommerce's server-rendered theme engine:
- Template files (Handlebars
.html) define page structure
- Front matter (YAML) at the top of each template declares what data to fetch
- BigCommerce injects theme objects (product, category, cart, settings, etc.) into the template context
- Handlebars helpers and partials render the data
- SCSS compiles to CSS, JS bundles with webpack
- Stencil CLI provides local development with hot reload
Template Hierarchy
templates/
├── layout/
│ ├── base.html # Master layout — header, footer, body
│ └── empty.html # Minimal layout (checkout, etc.)
├── pages/
│ ├── home.html # Homepage
│ ├── product.html # Product detail page
│ ├── category.html # Category listing
│ ├── cart.html # Cart page
│ ├── checkout.html # Checkout page
│ ├── account/ # Customer account pages
│ └── ...
├── components/
│ ├── common/ # Header, footer, navigation
│ ├── products/ # Product cards, options, gallery
│ ├── cart/ # Cart items, totals
│ └── ...
└── ...
Front Matter
What It Does
YAML block at the top of template files that declares data requirements:
---
product:
videos:
limit: {{theme_settings.product_videos_count}}
reviews:
limit: {{theme_settings.product_reviews_count}}
related_products:
limit: {{theme_settings.related_products_count}}
similar_by_views:
limit: {{theme_settings.similar_by_views_count}}
---
How It Works
- BigCommerce reads the front matter before rendering
- Fetches the specified data from its APIs
- Injects results into the Handlebars template context
- Controls what data is available on each page
Common Front Matter Resources
product — product details, images, videos, reviews, related products
category — category info, products in category
cart — cart items, totals
customer — logged-in customer data
shop_by_brand — brand listing
new_products, featured_products, top_products — product collections
Theme Objects
Key Objects
| Object |
Available On |
Contains |
product |
Product page |
name, price, images, options, variants, description, reviews |
category |
Category page |
name, description, products, subcategories |
cart |
Cart page |
items, subtotal, taxes, grand_total |
customer |
When logged in |
name, email, addresses, orders |
settings |
All pages |
store name, currency, logo, URLs |
theme_settings |
All pages |
config.json setting values |
breadcrumbs |
Most pages |
navigation breadcrumbs |
page |
CMS pages |
title, content, URL |
Accessing Data
{{product.title}}
{{product.price.without_tax.formatted}}
{{#each product.images}}
<img src="{{getImage this 'product_size'}}" alt="{{this.alt}}">
{{/each}}
Handlebars Helpers
Control Flow
{{#if condition}}...{{else}}...{{/if}} — conditional
{{#unless condition}}...{{/unless}} — inverse conditional
{{#each collection}}...{{/each}} — iteration
{{#with object}}...{{/with}} — context shifting
BigCommerce Custom Helpers
{{getImage image 'size_name'}} — generate image URL at specific size
{{cdn 'path/to/asset'}} — CDN-prefixed asset URL
{{stylesheet 'path/to/css'}} — include stylesheet
{{inject 'variable' value}} — pass data to JavaScript context
{{jsContext}} — output injected variables as JSON for JS consumption
{{lang 'translation_key'}} — internationalization
{{money price}} — format currency
{{truncate text length}} — truncate string
{{any collection}} — check if collection has items
{{all condition1 condition2}} — logical AND
{{compare a '===' b}} — comparison
Partials
Include reusable template fragments:
{{> components/products/card product}} — render a partial with context
{{> components/common/header}} — include a component
- Partials live in
templates/components/
Styling (SCSS)
Structure
assets/scss/
├── settings/ # Variables, mixins
│ ├── foundation/
│ └── citadel/
├── components/ # Component styles
├── layouts/ # Layout styles
├── tools/ # Utility mixins
└── theme.scss # Main entry point
Theme Settings in SCSS
Access config.json values: stencilColor("primary"), stencilNumber("font-size"), stencilString("font-family")
JavaScript
Module System
Stencil uses webpack for JS bundling:
- ES6 module imports
- Entry point in
assets/js/app.js
- Page-specific modules loaded conditionally
- jQuery available globally (Cornerstone ships with it)
Accessing Theme Data in JS
Use {{inject}} in templates and {{jsContext}} to pass server data to client JS:
{{inject 'productId' product.id}}
<script>{{jsContext}}</script>
Access in JS via this.context in PageManager subclasses.
PageManager
Cornerstone's page lifecycle manager:
- Extend
PageManager for page-specific JS
onReady() — DOM ready, initialize functionality
- Registered per page type in
assets/js/app.js
Configuration
config.json
Theme configuration with settings and variations:
settings — default values for all theme settings
variations — named presets (Light, Bold, Warm, etc.)
read_only_files — files that cannot be edited in Theme Editor
schema.json
Defines the Theme Editor UI:
- Sections, groups, and fields that appear in the visual editor
- Field types:
color, font, select, checkbox, text, range, imageDimension
- Maps to
config.json settings keys
Best Practices
- Fork Cornerstone as your starting point — don't start from scratch
- Use front matter to control data loading — don't over-fetch
- Use
{{inject}} to pass data to JS — don't scrape the DOM
- Use
{{cdn}} for all asset URLs — ensures CDN delivery
- Define schema.json entries for all customizable settings
- Use SCSS variables linked to config.json for consistent theming
- Escape user content:
{{{sanitize html}}} for HTML, {{variable}} auto-escapes
- Test across theme variations
- Keep bundle size small — conditionally load JS per page
Fetch the Stencil documentation and theme object reference for exact helper syntax, front matter keys, and object structure before implementing.
1---2name: bc-stencil3description: Build BigCommerce Stencil themes — Handlebars templates, front matter, theme objects, SCSS, JavaScript modules, config.json, schema.json, and Stencil CLI. Use when creating or customizing BigCommerce storefront themes.4---5
6# BigCommerce Stencil Theme Development
7
8## Before writing code
9
10**Fetch live docs**:
111. Fetch `https://developer.bigcommerce.com/docs/storefront/stencil` for Stencil overview
122. Fetch `https://developer.bigcommerce.com/docs/storefront/stencil/themes/context/object-reference` for theme object reference
133. Web-search `site:developer.bigcommerce.com stencil handlebars helpers` for Handlebars helper reference
14
15## Architecture
16
17### How Stencil Works
18
19Stencil is BigCommerce's server-rendered theme engine:
201. Template files (Handlebars `.html`) define page structure
212. **Front matter** (YAML) at the top of each template declares what data to fetch
223. BigCommerce injects **theme objects** (product, category, cart, settings, etc.) into the template context
234. Handlebars helpers and partials render the data
245. SCSS compiles to CSS, JS bundles with webpack
256. Stencil CLI provides local development with hot reload
26
27### Template Hierarchy
28
29```
30templates/
31├── layout/
32│ ├── base.html # Master layout — header, footer, body
33│ └── empty.html # Minimal layout (checkout, etc.)
34├── pages/
35│ ├── home.html # Homepage
36│ ├── product.html # Product detail page
37│ ├── category.html # Category listing
38│ ├── cart.html # Cart page
39│ ├── checkout.html # Checkout page
40│ ├── account/ # Customer account pages
41│ └── ...
42├── components/
43│ ├── common/ # Header, footer, navigation
44│ ├── products/ # Product cards, options, gallery
45│ ├── cart/ # Cart items, totals
46│ └── ...
47└── ...
48```
49
50## Front Matter
51
52### What It Does
53
54YAML block at the top of template files that declares data requirements:
55
56```yaml
57---
58product:
59 videos:
60 limit: {{theme_settings.product_videos_count}}
61 reviews:
62 limit: {{theme_settings.product_reviews_count}}
63 related_products:
64 limit: {{theme_settings.related_products_count}}
65 similar_by_views:
66 limit: {{theme_settings.similar_by_views_count}}
67---
68```
69
70### How It Works
71
72- BigCommerce reads the front matter before rendering
73- Fetches the specified data from its APIs
74- Injects results into the Handlebars template context
75- Controls what data is available on each page
76
77### Common Front Matter Resources
78
79- `product` — product details, images, videos, reviews, related products
80- `category` — category info, products in category
81- `cart` — cart items, totals
82- `customer` — logged-in customer data
83- `shop_by_brand` — brand listing
84- `new_products`, `featured_products`, `top_products` — product collections
85
86## Theme Objects
87
88### Key Objects
89
90| Object | Available On | Contains |
91|--------|-------------|----------|
92| `product` | Product page | name, price, images, options, variants, description, reviews |
93| `category` | Category page | name, description, products, subcategories |
94| `cart` | Cart page | items, subtotal, taxes, grand_total |
95| `customer` | When logged in | name, email, addresses, orders |
96| `settings` | All pages | store name, currency, logo, URLs |
97| `theme_settings` | All pages | config.json setting values |
98| `breadcrumbs` | Most pages | navigation breadcrumbs |
99| `page` | CMS pages | title, content, URL |
100
101### Accessing Data
102
103```handlebars
104{{product.title}}
105{{product.price.without_tax.formatted}}
106{{#each product.images}}
107 <img src="{{getImage this 'product_size'}}" alt="{{this.alt}}">
108{{/each}}
109```
110
111## Handlebars Helpers
112
113### Control Flow
114
115- `{{#if condition}}...{{else}}...{{/if}}` — conditional
116- `{{#unless condition}}...{{/unless}}` — inverse conditional
117- `{{#each collection}}...{{/each}}` — iteration
118- `{{#with object}}...{{/with}}` — context shifting
119
120### BigCommerce Custom Helpers
121
122- `{{getImage image 'size_name'}}` — generate image URL at specific size
123- `{{cdn 'path/to/asset'}}` — CDN-prefixed asset URL
124- `{{stylesheet 'path/to/css'}}` — include stylesheet
125- `{{inject 'variable' value}}` — pass data to JavaScript context
126- `{{jsContext}}` — output injected variables as JSON for JS consumption
127- `{{lang 'translation_key'}}` — internationalization
128- `{{money price}}` — format currency
129- `{{truncate text length}}` — truncate string
130- `{{any collection}}` — check if collection has items
131- `{{all condition1 condition2}}` — logical AND
132- `{{compare a '===' b}}` — comparison
133
134### Partials
135
136Include reusable template fragments:
137- `{{> components/products/card product}}` — render a partial with context
138- `{{> components/common/header}}` — include a component
139- Partials live in `templates/components/`
140
141## Styling (SCSS)
142
143### Structure
144
145```
146assets/scss/
147├── settings/ # Variables, mixins
148│ ├── foundation/
149│ └── citadel/
150├── components/ # Component styles
151├── layouts/ # Layout styles
152├── tools/ # Utility mixins
153└── theme.scss # Main entry point
154```
155
156### Theme Settings in SCSS
157
158Access `config.json` values: `stencilColor("primary")`, `stencilNumber("font-size")`, `stencilString("font-family")`
159
160## JavaScript
161
162### Module System
163
164Stencil uses webpack for JS bundling:
165- ES6 module imports
166- Entry point in `assets/js/app.js`
167- Page-specific modules loaded conditionally
168- jQuery available globally (Cornerstone ships with it)
169
170### Accessing Theme Data in JS
171
172Use `{{inject}}` in templates and `{{jsContext}}` to pass server data to client JS:
173```handlebars
174{{inject 'productId' product.id}}
175<script>{{jsContext}}</script>
176```
177Access in JS via `this.context` in PageManager subclasses.
178
179### PageManager
180
181Cornerstone's page lifecycle manager:
182- Extend `PageManager` for page-specific JS
183- `onReady()` — DOM ready, initialize functionality
184- Registered per page type in `assets/js/app.js`
185
186## Configuration
187
188### config.json
189
190Theme configuration with settings and variations:
191- `settings` — default values for all theme settings
192- `variations` — named presets (Light, Bold, Warm, etc.)
193- `read_only_files` — files that cannot be edited in Theme Editor
194
195### schema.json
196
197Defines the Theme Editor UI:
198- Sections, groups, and fields that appear in the visual editor
199- Field types: `color`, `font`, `select`, `checkbox`, `text`, `range`, `imageDimension`
200- Maps to `config.json` settings keys
201
202## Best Practices
203
204- Fork Cornerstone as your starting point — don't start from scratch
205- Use front matter to control data loading — don't over-fetch
206- Use `{{inject}}` to pass data to JS — don't scrape the DOM
207- Use `{{cdn}}` for all asset URLs — ensures CDN delivery
208- Define schema.json entries for all customizable settings
209- Use SCSS variables linked to config.json for consistent theming
210- Escape user content: `{{{sanitize html}}}` for HTML, `{{variable}}` auto-escapes
211- Test across theme variations
212- Keep bundle size small — conditionally load JS per page
213
214Fetch the Stencil documentation and theme object reference for exact helper syntax, front matter keys, and object structure before implementing.