Translations

Learn how to use translations to localize your notifications.

Translations localize the notifications you send with Knock.

Enterprise plan feature. Translations are only available on our Enterprise plan.

Get started

To get started, enable translations for your account. Go to “Settings” under your account name in the left sidebar and click “Enable translations”.

Next you'll need to set a default locale. Knock uses the default locale when it can't find a translation for a given recipient’s locale.

Once you've set your default locale, you should see a new “Translations” page under “Developers” in the sidebar. This is where you’ll be working with your translations.

Basic usage

Translations are JSON objects that contain the text for your messages in various locales. For example, let’s say you have a customer order notification that you want to localize for French and English users.

en translation
1{
2  "OrderReady": "Your order is ready.",
3  "OrderDelayed": "Your order is delayed."
4}

fr translation
1{
2  "OrderReady": "Votre commande est prête.",
3  "OrderDelayed": "Votre commande est retardée."
4}

Once you have those translations created for the en and fr locales, you can reference their translation strings in your message templates using the t filter:

Message template editor
1<p> {{ "OrderReady" | t }} </p>

Your users must have a locale property set for the helper to find translations in their locale, otherwise Knock will use the default locale. You can set a user's locale with the identify endpoint.

Translation methods: filter vs. tag

There are two methods available to you to translate your message templates: the t filter and the t tag.

We cover how to use the t filter and t tag in more detail below.

Using the t filter

You can use t filter to reference your translations from within a message template. The t filter also allows you to use variables, other filters, and special pluralization rules.

Variables and interpolation

You can use variable interpolation in your translations.

en translation
1{
2  "comment": "New comment from {{ actorName }} on your post {{ postName }}.",
3  "like": "{{ actorName }} liked your photo {{ photoTitle}}!"
4}

You can pass variables to the t filter:

Message template editor
1<p> {{ "like" | t: actorName: actor.name, photoTitle: likedPhoto.title }} </p>

Pluralization

Translations support pluralization rules. When you pass the count variable to a translation, it looks for pluralization keys in your translation. Those keys are zero, one, and other. You don’t need to reference these in the template. If you pass the count variable, it will evaluate it and choose one for you.

en translation
1{
2  "orders": {
3    "shipping": {
4      "zero": "You have no orders currently being shipped.",
5      "one": "You have one order being shipped.",
6      "other": "You have {{ count }} orders being shipped."
7    }
8  }
9}

To pluralize content in a message template, pass the count variable:

Message template editor
1<p> {{ "orders.shipping" | t: count: count }} </p>
  • If the count is 0, it will choose zero, unless zero does not exist and then it will use other.
  • 1 corresponds to one, and everything else will fall under others.

Other filters in combination

You can still use other filters in combination with t but you’ll use them after you use the t filter.

For example, to titlecase a translation:

Message template editor
1<p> {{ "congratulationsMessage" | t | titlecase }} </p>

Namespaced translations

When you create a translation, you can supply an optional “namespace.” The namespace helps organize translations of the same locale so you can keep similar concepts together. Below you'll see examples of how to reference namespaced translations from your message templates.

Let's start with a translation with a namespace of shipping:

en:shipping translation
1{
2  "backordered": "Your order has been backordered so shipping will be delayed.",
3  "shipped": "Your order has been shipped.",
4  "canceled": "Your shipment has been canceled."
5}

To access the contents of the shipping translation in your message template you’ll reference the namespace before the key followed by a colon (”:”):

Message template editor
1<p> {{ "shipping:canceled" | t }} </p>

This can be helpful if you use the canceled key else where in your translations so that there isn’t a collision. For example, if you had a payments translation like this:

en:payments translation
1{
2  "success": "Your payment has been processed.",
3  "canceled": "Your payment was canceled."
4}

You would reference it with the payments namespace as well:

Message template editor
1<p> {{ "payments:canceled" | t }} </p>

And if you had a translation that wasn’t namespaced, say the en translation, you would simply use the key alone. All together in a template, it would look like this:

Message template editor
1<p> Hello, </p>
2<p> {{ "payments:canceled" | t }} </p>
3<p> {{ "shipments:canceled" | t }} </p>
4<p> {{ "canceled" | t }} </p>

Nested translations

You can create whatever JSON structure you need to hold your translations.

Given the following translation:

en translation
1{
2  "customers": {
3    "orders": {
4      "beenReceived": "Have you received your order?",
5      "survey": "How was your order?"
6    },
7    "reminder": {
8      "paymentInfo": "Remember to update your payment information!"
9    }
10  }
11}

You can access the content with dot-syntax like this:

Message template editor
1<p> {{ "customers.orders.beenReceived" | t }} </p>

The same goes for namespaced translations. If the above translation was in a translation named services , you would do the following:

Message template editor
1<p> {{ "services:customers.orders.beenReceived" | t }} </p>

Using the t tag

Knock also provides an editor-friendly t tag which you can use to write templates in your default language. Translation files for any supported languages will be automatically generated in the background when you commit a workflow.

1

Write your message templates

Wrap content you want to translate in a t tag. Any content between the opening and closing t tags will be used as the content for your account's default locale.

Message template
1<p> {% t %}Have you received your order?{% endt %} </p>
2

Commit your workflow

After you commit your workflow, Knock will look for changes to your message templates and update a system translation file. Translation keys will be automatically generated based off of the content of the t tag.

A Knock bot will commit these changes to your account with a message indicating which workflow generated the new translations.

System translation file
1{
2  "Have you received your order?": "Have you received your order?"
3}
3

Translate the default content into additional locales

You can then translate the default content into additional locales by manually editing your translation files or programmatically updating them using the Knock API and a translation service.

Translation version control

Translations follow the same version control flow in Knock as workflows and layouts. You create them in Development and then promote them to subsequent environments. You can archive translations that are no longer needed.

🚨
Remember: in order to see translation updates in your template previews, you'll need to commit them to your development environment first.

Locale prioritization

When Knock renders a template for a given user and encounters our t helper, it runs through the following locale prioritization:

  1. Language + region (e.g. fr-BE)
  2. Language (e.g. fr)
  3. Default locale (e.g. en)

Regional locales take precedence over language locales. If a translation is not found in the user’s locale, Knock will fall back to the default locale.

Automate localization with our CLI

In addition to working with translations in the Knock dashboard, you can programmatically create and update translations using the Knock CLI or our Management API.

If you manage your own translation files within your application, you can automate the creation and management of Knock translations so that they always reflect the state of the translation files you keep in your application code.

The Knock CLI supports both JSON and the Portable Object (PO) file formats. When using PO files, the Knock CLI will handle converting between the Knock translation format and the PO format.

The Knock CLI can also be used to commit changes and promote them to production, which means you can automate Knock translation management as part of your CI/CD workflow.

Translation directory structure

When translations are pulled from Knock, they are stored in directories named by their locale codes. Their filename will be their locale code. Any namespaced translations will prepend the namespace to the filename, with . used as a separator.

Local translation files structure
1translations/
2├── en/
3│  ├── en.json
4│  └── admin.en.json
5└── en-GB/
6   ├── en-GB.json
7   └── tasks.en-GB.json

If you're migrating your local translation files into Knock, you can arrange them using the file structure above and then push them into Knock with a single command using knock translation push --all. Each <locale>.json or <namespace>.<locale>.json file should follow the structure defined here.

You can learn more about automating translation management in the Knock CLI reference. Feel free to contact us if you have questions.

Supported locales

Below is a list of the available locales to choose from for your translations. If you need one added, contact us at support@knock.app.