Guides

How to Translate Shopify Checkout Extensions and Post-Purchase Pages

Merchants lose completed sales at checkout more than at any other step — and showing a French customer an English "Complete order" button is one of the fastest ways to make that happen. Getting Shopify checkout translation right is harder than translating product pages, because the checkout surface is split across multiple distinct areas with different access rules, customization mechanisms, and translation paths. This guide gives you a precise map of what each area is, what you can actually change depending on your plan, and how to do it correctly.


Understanding the Three Separate Checkout Surfaces

Before writing a single line of translation, you need to know which surface you are working on. Shopify's checkout extensibility rollout introduced new surfaces and deprecated others, and conflating them leads to broken implementations.

1. The Checkout Itself (Cart → Payment → Confirmation Flow)

This is the multi-step flow from cart to order placement. Shopify controls the core UI strings here — field labels, error messages, button text — through your active locale files. You translate these by publishing a storefront language in Settings → Languages, which tells Shopify to serve its own built-in checkout strings in that language automatically. You do not write those strings yourself; Shopify ships them.

What you can customize on any plan:

  • Checkout UI extensions placed in supported injection points (e.g., purchase.checkout.block.render, purchase.checkout.shipping-option-item.render-after)
  • Custom fields added via Checkout UI Extensions
  • Banner and delivery instruction blocks

What requires Shopify Plus:

  • Full Branding API access (custom fonts, colors, logo placement)
  • Header and footer replacement via purchase.checkout.header.render-after and purchase.checkout.footer.render-before
  • Custom payment method blocks in restricted injection points
  • The ability to replace the checkout layout itself

Standard and Advanced plan merchants can render extension blocks in a meaningful subset of injection points, but they cannot touch the checkout's overall layout or header/footer. If your translation need is a custom upsell block inside the checkout, that is available to you. If you want a fully branded, fully translated custom checkout shell, that is Plus territory.

2. The Thank You Page (New Post-Purchase Surface)

With Shopify's checkout extensibility rollout, the Thank You page became its own distinct extensible surface, separate from the order status page. Extensions render here immediately after order placement. The injection point is purchase.thank-you.block.render.

This surface is available to merchants on Shopify Basic and above — it is not Plus-gated. You can render extension blocks here, and those blocks can and should be translated.

3. The Order Status Page (Legacy and Ongoing)

The order status page is what customers reach when they return to check their order after the initial thank you. It lives at /orders/{token} and has historically been the most customizable part of the checkout flow via the Additional scripts field. As of 2024–2025, Shopify has been migrating this to the new extensible order status page, which uses the same UI extension model.

Key distinction: If your store has been migrated to the new order status page, you use purchase.order-status.block.render injection points. If your store is still on the legacy order status page, you use the Additional scripts textarea. Check your Checkout settings — if you see a "Customize" button that opens the checkout editor for the order status page, you are on the new surface.

Do not copy Thank You page extension code to the order status page or vice versa — the injection point names differ, and the context object exposes different data on each surface.


How to Translate Text Inside Checkout UI Extensions

Shopify's UI extension framework uses a localization system built on JSON files. Here is how to implement it correctly.

Step 1: Create Locale Files as Separate JSON Files

Inside your extension directory, create a locales/ folder with one file per language:

extensions/
  my-checkout-block/
    locales/
      en.default.json
      fr.json
      de.json
    src/
      Checkout.jsx

Each file holds only the key-value pairs for that language. en.default.json:

{
  "upsell": {
    "heading": "Complete your order with",
    "addButton": "Add to order",
    "declineLink": "No thanks"
  }
}

fr.json:

{
  "upsell": {
    "heading": "Complétez votre commande avec",
    "addButton": "Ajouter à la commande",
    "declineLink": "Non merci"
  }
}

Step 2: Use the useTranslate Hook in Your Component

import { useTranslate, BlockStack, Text, Button, Link } from "@shopify/ui-extensions-react/checkout";

export function UpsellBlock() {
  const translate = useTranslate();

  return (
    <BlockStack>
      <Text>{translate("upsell.heading")}</Text>
      <Button>{translate("upsell.addButton")}</Button>
      <Link>{translate("upsell.declineLink")}</Link>
    </BlockStack>
  );
}

The useTranslate hook reads the buyer's active locale from the checkout context and automatically serves the matching locale file. You never hardcode locale strings inline in your component — that is what the separate JSON files are for, and it is also what makes the system maintainable when you add a fifth or fifteenth language.

Step 3: Handle Pluralization and Interpolation

For dynamic strings (e.g., "Add {productName} to order"), use interpolation:

{
  "upsell": {
    "addButtonDynamic": "Add {productName}"
  }
}
translate("upsell.addButtonDynamic", { productName: product.title })

Translating Post-Purchase Pages Built With Shopify Functions

Post-purchase offers built via Shopify Functions (e.g., discount logic, shipping customizations) contain merchant-facing or buyer-facing strings in their configuration. These strings are typically set in the app's admin UI, not in your extension code directly. To translate them:

  1. Check whether the app or function provider exposes a locale-aware configuration field.
  2. For custom-built functions, store translated strings in metafields keyed to locale and retrieve them at runtime.
  3. For third-party post-purchase apps, contact the vendor — translation support varies significantly by app.

What Translation Apps Cover (and Don't Cover) in Checkout

Translation apps — including StoreLingo, which translates your store's products, collections, pages, and articles — translate the storefront content that lives in Shopify's translation API: product titles, descriptions, metafields, page content, and SEO fields.

What a translation app handles:

  • Product and variant names shown in the cart summary inside checkout
  • Store policies linked from the checkout footer
  • Any metafield-driven content surfaced in checkout blocks that reads from Shopify's translation layer

What a translation app cannot handle:

  • The strings inside your custom UI extension code — those require locale JSON files as described above
  • Core checkout UI strings (button labels, field placeholders) — Shopify serves those automatically when you publish the language
  • Content rendered by third-party checkout apps that bypass Shopify's translation API

This is why a complete checkout translation requires both the right Shopify language setup and correctly localized extension code. Neither alone covers everything.

For a complete picture of what translation apps can and cannot touch across your store, The Complete Shopify Translation Checklist for Going Multilingual is worth working through before you start.


Configuring Shopify Markets So Translated Checkout Is Actually Served

The most common reason a translated checkout does not appear has nothing to do with missing strings — it is Markets configuration. Shopify only serves a translated checkout when the buyer reaches checkout from a correctly configured market URL.

Go to Settings → Markets and confirm:

  • The target market has the correct language assigned
  • The market has a domain or subpath configured (/fr or fr.yourstore.com)
  • The buyer lands on the store via that domain or subpath before adding to cart

If a French buyer navigates directly to yourstore.com (your primary domain without the /fr prefix), Shopify serves them the default language checkout regardless of their browser locale. The storefront language is determined by the URL, not the browser. Fix this at the domain level first, then test checkout translation. See How to Set Up Shopify Markets for Multiple Languages and Currencies Together for the full Markets setup walkthrough.

You should also ensure your language switcher correctly redirects to the market-scoped URL rather than just changing a display preference client-side. How to Add a Language Switcher to Your Shopify Store covers the correct implementation.


A Note on Email Notifications Triggered From Checkout

The order confirmation email fires immediately after the checkout completes. That email is a separate translation task — it uses Shopify's notification templates, not the checkout extension system. If your checkout is translated but the confirmation email arrives in English, you have a gap in the customer experience. How to Translate Shopify Email Notifications and Transactional Messages covers that surface in detail.


Add StoreLingo on the Shopify App Store →

StoreLingo is the app behind this blog. The link above is a direct product recommendation from us.


FAQ

Does Shopify automatically translate the checkout into my published languages? Shopify automatically translates its own built-in checkout UI strings (field labels, error messages, button text) when you publish a language in Settings → Languages. It does not translate the content inside your custom UI extensions — you must implement locale JSON files and the useTranslate hook in your extension code for those strings.

My checkout shows English even though I published French — what's wrong? The most common cause is Markets configuration, not missing translations. Shopify determines the checkout language from the storefront URL the buyer arrived on, not their browser settings. If your French buyers are reaching your store via yourstore.com instead of yourstore.com/fr (or fr.yourstore.com), Shopify serves the default language. Verify that your market has a domain or subpath assigned, that the language switcher redirects to that URL correctly, and only then check for cache or CDN issues.

Can merchants on standard Shopify plans (not Plus) translate their checkout extensions? Yes. Translating the content inside your UI extensions using locale JSON files works on any plan — it is part of the extension framework itself. What is restricted to Shopify Plus is full checkout layout customization via the Branding API and certain injection points. If you only need to translate a custom upsell block or a custom shipping message, the locale file approach works without a Plus subscription.

Translate your store into 47 languages

StoreLingo translates products, collections, pages and articles with AI — review before publishing, keep your brand terms consistent.

Add to Shopify →