How-to: Translate widgets on store to other languages
This guide shows you how to override the text in Disco’s countdown, announcement bar, hero banner, landing pages and sale badges for translating the text to other languages used by the store. If you’re comfortable editing a Shopify theme and pasting JSON, you’re good to go.
1) Where to paste the JSON
- In Shopify Admin, go to Online Store → Customize.
- In the theme editor, open the App embeds panel (left sidebar).
- Turn on Disco App Embed and click it.
- Find the Translation overrides textarea.
- Paste your JSON there and Save.
You can paste just the parts you need. Missing keys fall back to Disco’s defaults.
2) How Disco decides which language to use
Disco checks languages in this order:
document.documentElement.lang(the HTML<html lang="…">on your storefront)- The default text set inside the app
Tip: If you have region-specific text (like Canadian French), add entries for both fr-CA and fr . The region-specific one will win if present.
3) The overall JSON shape
Paste this (and then fill in only what you need):
{
"countdown": {
"xx": {},
"sales": {
"SALE_ID": {
"xx": {}
}
}
},
"announcement": {
"xx": {},
"sales": {
"SALE_ID": {
"xx": {}
}
}
},
"announcement_timer": {
"xx": {}
}
}
xx= language code (e.g.fr,fr-CA). Region entries (e.g.,fr-CA) beat their base language (fr).sales(optional) = lets you scope overrides to a specific sale using its SALE_ID. Structure inside mirrors the global one (locale → key/value pairs).
4) What can I override?
A) Countdown (product/collection widget)
Use these keys inside "countdown" → "<locale>" :
| Key | What it controls | Default example |
|---|---|---|
ContentHeading |
Headline above the timer | Hurry up! Sale ends in |
ContentDays |
Label under days | Days |
ContentHours |
Label under hours | Hours |
ContentMinutes |
Label under minutes | Minutes |
ContentSeconds |
Label under seconds | Seconds |
B) Announcement bar text
Use these keys inside "announcement" → "<locale>" :
| Key | Where it shows | Notes / Defaults |
|---|---|---|
TextLeft |
Main left-aligned message (active sale) | From Sale → Announcement → Text (left) |
TextRight |
Right-aligned text (desktop) | From Text (right) |
TextButton |
CTA button label (active sale) | From Button text |
TextLeftBeforeStart |
Left message before sale starts | From Pre-start left text |
TextRightBeforeStart |
Right message before sale starts | From Pre-start right text |
TextButtonBeforeStart |
CTA label before start | Defaults to “Get notified!” if empty |
EmailPlaceholder |
Placeholder in subscribe field | Defaults to “Email address” if empty |
SubscribedLabel |
Text after successful subscribe | Defaults to “Subscribed” |
SubscribedHtml |
Optional: replaces entire subscribed message | Accepts HTML. If omitted, uses label + icon |
C) Hero banner text
"hero_banner" → "<locale>" :
| Key | What it controls | Default example |
|---|---|---|
| title | Main heading text | "Collection Sale" |
| subtitle | Subheading text | "Entire collection on sale" |
| buttonText | CTA button label | "Shop Collection" |
| timerHeading | Text above countdown (active sale) | "Sale ends in" |
| timerHeadingSubscribe | Text above countdown (before start) | "Sale starts in" |
| subscribeText | Label above email input | "Subscribe to our newsletter" |
| subscribeButtonText | Subscribe button label | "Subscribe" |
| subscribePlaceholder | Email input placeholder | "Enter your email" |
D) Announcement timer labels (flip clock inside the bar)
Use these keys inside "announcement_timer" → "<locale>" :
| Key | What it controls | Default example |
|---|---|---|
ContentDays |
Label under days | Days |
ContentHours |
Label under hours | Hrs |
ContentMinutes |
Label under minutes | Mins |
ContentSeconds |
Label under seconds | Secs |
E) Sale Tag Text
"sale_tag" → "<locale>" :
| Key | What it controls | Default example |
|---|---|---|
| Text | Sale tag text on products | "SALE" |
F) Landing Page Text (Active Sale)
"landing_page" → "<locale>" :
| Key | What it controls | Default example |
|---|---|---|
| ContentHeading | Main heading | "Black Friday Sale" |
| ContentSubheading | Subheading | "Check out our exclusive deals below" |
| ContentTimerHeading | Timer heading | "Deals expire in" |
| ContentSaveLabel | Product badge label | "Save" |
| ContentSubscribePlaceholder | Email input placeholder | "Enter your email" |
| ContentSubscribeButtonText | Subscribe button text | "Notify me" |
| ContentSubscribeDialogHeading | Dialog heading | "Subscribed successfully" |
| ContentSubscribeDialogBody | Dialog body text | "You will now be notified when the sale starts." |
| ContentSubscribeDialogButton | Dialog button text | "OK" |
| ButtonText_0, ButtonText_1, ... | Navigation button texts | (varies) |
G) Coming Soon Page Text
"coming_soon_page" → "<locale>" :
| Key | What it controls | Default example |
|---|---|---|
| ContentHeading | Main heading | "Coming Soon" |
| ContentSubheading | Subheading | "A big sale is on its way!" |
| ContentTimerHeading | Timer heading | "Sale starts in" |
| ContentSaveLabel | Product badge label | "Save" |
| ContentSubscribePlaceholder | Email input placeholder | "Enter your email" |
| ContentSubscribeButtonText | Subscribe button text | "Notify me" |
| ContentSubscribeDialogHeading | Dialog heading | "Subscribed successfully" |
| ContentSubscribeDialogBody | Dialog body text | "You will now be notified when the sale starts." |
| ContentSubscribeDialogButton | Dialog button text | "OK" |
| ButtonText_0, ButtonText_1, ... | Navigation button texts | (varies) |
5) Examples you can copy
Example 1 — Simple French countdown labels
{
"countdown": {
"fr": {
"ContentHeading": "Se termine dans",
"ContentDays": "Jours",
"ContentHours": "Heures",
"ContentMinutes": "Minutes",
"ContentSeconds": "Secondes"
}
}
}
Example 2 — Per-sale French announcement copy (for a specific sale)
Replace YOUR_SALE_ID with your sale’s ID (found in the Disco app where you configure the sale).
{
"announcement": {
"sales": {
"YOUR_SALE_ID": {
"fr": {
"TextLeft": "Vente éclair aujourd’hui seulement",
"TextButton": "Magasiner"
}
}
}
}
}
Example 3 — Full configuration example
{
"countdown": {
"it": {
"ContentHeading": "Affrettati! La vendita termina tra",
"ContentDays": "Giorni",
"ContentHours": "Ore",
"ContentMinutes": "Minuti",
"ContentSeconds": "Secondi"
}
},
"announcement_timer": {
"it": {
"ContentDays": "G",
"ContentHours": "O",
"ContentMinutes": "M",
"ContentSeconds": "S"
}
},
"announcement": {
"it": {
"TextLeft": "Vendita lampo!",
"TextButton": "Acquista ora",
"TextLeftBeforeStart": "Prossimamente!",
"TextButtonBeforeStart": "Avvisami",
"EmailPlaceholder": "Indirizzo email",
"SubscribedLabel": "Iscritto"
}
},
"hero_banner": {
"it": {
"title": "Grande Svendita",
"subtitle": "Tutta la collezione in saldo",
"buttonText": "Acquista la collezione",
"timerHeading": "La vendita termina tra",
"timerHeadingSubscribe": "La vendita inizia tra"
}
},
"landing_page": {
"it": {
"ContentHeading": "Svendita del Black Friday",
"ContentSubheading": "Scopri le nostre offerte esclusive",
"ContentTimerHeading": "Le offerte scadono tra",
"ContentSaveLabel": "Risparmia",
"ContentSubscribeButtonText": "Acquista ora"
}
},
"coming_soon_page": {
"it": {
"ContentHeading": "Prossimamente",
"ContentSubheading": "Una grande vendita sta arrivando!",
"ContentTimerHeading": "La vendita inizia tra",
"ContentSubscribePlaceholder": "Inserisci la tua email",
"ContentSubscribeButtonText": "Avvisami",
"ContentSubscribeDialogHeading": "Iscrizione completata",
"ContentSubscribeDialogBody": "Riceverai una notifica quando inizierà la vendita.",
"ContentSubscribeDialogButton": "OK"
}
}
}
6) Common tips & gotchas
-
Only override what you need. You can include just one section (e.g., only
"announcement_timer").Valid JSON is required. Use straight quotes
"and commas between items. Remove any/* comments */before saving.Locale keys are case-sensitive. Use lowercase language codes and uppercase country codes, e.g.,
fr-CA,en-GB.Per-sale vs global:
- Global: put text under
"countdown"or"announcement"→"<locale>". - Per-sale: put text under
"sales"→"<SALE_ID>"→"<locale>". Per-sale wins over global for that sale.
- Global: put text under
- Testing: Switch your storefront language (or add
?locale=frto your storefront URL, if supported) to verify the correct strings show.
7) Quick troubleshooting
- Nothing changed:
- Confirm the JSON is valid.
- Make sure you pasted into Disco App Embed → Translation overrides and saved.
-
Verify the storefront language matches your locale key (e.g.,
fr-CAvsfr).Wrong labels in the announcement timer:
-
Those come from
"announcement_timer"(not"countdown").Per-sale overrides not showing:
- Double-check the exact SALE_ID and that you placed overrides under
"announcement"or"countdown"→"sales"→"<SALE_ID>"→"<locale>".