Storefront Language Selector

A language selector enables shoppers to switch between the storefront languages you have configured. Stencil automatically provides the necessary data through the language_selector object; your theme is responsible for rendering the UI and wiring up interactivity.

language_selector object

Stencil exposes a language_selector object on every page. It contains the following properties:

PropertyTypeDescription
active_language_codestringLocale code for the current language (for example, en, es, fr)
languagesarrayList of all available languages
languages[].codestringLocale code for the language
languages[].switch_urlstringURL that switches the storefront to this language
languages[].is_activebooleantrue if this language is currently active

Implementation

The language selector is already built into Cornerstone 6.19.0 and later. If your theme includes this feature, no additional implementation is needed — the steps below apply to third-party themes or custom themes based on earlier Cornerstone versions.

1

Create a Handlebars partial

Create a new partial file, for example templates/components/common/language-selector.html. Use data-locale-code attributes so JavaScript can resolve human-readable language names.

This markup is a simplified reference, not a copy of Cornerstone’s production dropdown. Cornerstone’s own language-selector.html toggles visibility with Foundation’s data-dropdown behavior, which only works in themes that bundle Foundation. Stencil has no shared dropdown primitive, so toggle behavior is theme-specific — several partner themes use a native <select> element instead, since keyboard navigation and accessibility come for free from the browser. If you build a custom dropdown like the one below, you’re responsible for wiring up the JavaScript that opens and closes it (toggling aria-expanded and showing or hiding the list).

templates/components/common/language-selector.html
<div class="languageSelector navUser-item" data-language-selector>
<button
class="languageSelector-toggle"
aria-labelledby="languageSelector-active"
aria-haspopup="listbox"
aria-expanded="false"
>
<span
id="languageSelector-active"
class="languageSelector-active"
data-locale-code="{{language_selector.active_language_code}}"
>
{{language_selector.active_language_code}}
</span>
</button>
<ul class="languageSelector-dropdown" role="listbox">
{{#each language_selector.languages}}
<li class="languageSelector-item{{#if is_active}} is-active{{/if}}" role="option">
<a
href="{{switch_url}}"
class="languageSelector-link"
data-locale-code="{{code}}"
{{#if is_active}}aria-selected="true"{{/if}}
>
{{code}}
</a>
</li>
{{/each}}
</ul>
</div>

Include the partial in your header template, gating the include with {{#and}} so the selector only renders when the store has more than one active language:

{{#and language_selector language_selector.languages.length '>' 1}}
{{> components/common/language-selector}}
{{/and}}

Cornerstone also ships a separate mobile partial at templates/components/common/language-selector-mobile.html, included from navigation-menu.html. If your theme has a distinct mobile navigation, create an equivalent mobile partial and gate its include the same way.

2

Resolve locale codes to display names

The code values returned by Stencil (such as es or fr-CA) are machine-readable locale identifiers. Use the browser’s Intl.DisplayNames API to display native language names instead.

assets/js/theme/global/language-selector.js
function resolveLanguageName(localeCode) {
try {
const displayNames = new Intl.DisplayNames([localeCode], { type: 'language' });
return displayNames.of(localeCode);
} catch {
return localeCode;
}
}
export default function initLanguageSelector() {
document.querySelectorAll('[data-locale-code]').forEach(el => {
const resolved = resolveLanguageName(el.dataset.localeCode);
if (resolved) el.textContent = resolved;
});
}

Import and call initLanguageSelector() from your global theme entry point.

3

Add styles

Cornerstone’s assets/scss/components/stencil/navUser/_navUser.scss is a good reference for production-quality styles that integrate with the existing navigation design. Scope your styles under .languageSelector and follow the same BEM naming pattern used in the rest of the theme.

Resources