Localization
The localization process for the runner involves loading the appropriate locale and translation based on the form or respondent's language.
🌐 Runner locale
The locale instructs the runner which locale data to use. This locale data contains the number and date/time formats the runner will use. The stock runner packages contain all the locales. Locale information is stored in a JSON file per locale. The locale JSON files are in the runner/locales
folder of each stock runner package.
Depending on your use case, there are two options to load the locale data:
- Static locale: If you use the runner to serve a static form in a fixed language and a fixed locale, you can load the locale statically at compile-time;
- Dynamic locale: If you want to load the appropriate locale based on the form language and/or user browser locale, you can dynamically load the locale.
If no locale is specified, the default locale en
is used.
Using a static locale (compile-time)
If your runner needs a static, fixed locale you can load the locale during compile-time.
- Autoscroll
- Chat
- Classic
import { run } from "@tripetto/runner-autoscroll";
// Import the dutch locale data
import locale from "@tripetto/runner-autoscroll/runner/locales/nl.json";
run({
definition: /* Supply your form definition here */,
locale
});
import { run } from "@tripetto/runner-chat";
// Import the dutch locale data
import locale from "@tripetto/runner-autoscroll/runner/locales/nl.json";
run({
definition: /* Supply your form definition here */,
locale
});
import { run } from "@tripetto/runner-classic";
// Import the dutch locale data
import locale from "@tripetto/runner-autoscroll/runner/locales/nl.json";
run({
definition: /* Supply your form definition here */,
locale
});
Make sure to enable the --resolveJsonModule
compiler flag in your TypeScript configuration to allow importing JSON files.
Using a dynamic locale (run-time)
To dynamically load the locale, you need a server endpoint to deliver the locale JSON files to your application. In the following example, we assume the locales are available on the domain that runs the runner. The runner tries to load the appropriate locale based on the form language, user browser locale, or the supplied l10n
object.
- Autoscroll
- Chat
- Classic
import { run } from "@tripetto/runner-autoscroll";
// Load the locale using await
run({
definition: /* Supply your form definition here */,
locale: async (locale) => {
const response = await fetch(`/locales/${locale}.json`);
return await response.json();
}
});
// Or use a promise
run({
definition: /* Supply your form definition here */,
locale: (locale) =>
new Promise((resolve, reject) => {
fetch(`/locales/${locale}.json`)
.then((response) => {
if (response.ok) {
response.json().then((data) => resolve(data));
} else {
reject();
}
})
.catch(() => reject());
}),
});
If you use webpack and want to copy all the locale files to a static distribution folder of your application, you could use copy-webpack-plugin
to copy the files as part of the build process:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "node_modules/@tripetto/runner-autoscroll/runner/locales/", to: "build/static/locales/" },
],
}),
],
};
import { run } from "@tripetto/runner-chat";
// Load the locale using await
run({
definition: /* Supply your form definition here */,
locale: async (locale) => {
const response = await fetch(`/locales/${locale}.json`);
return await response.json();
},
});
// Or use a promise
run({
definition: /* Supply your form definition here */,
locale: (locale) =>
new Promise((resolve, reject) => {
fetch(`/locales/${locale}.json`)
.then((response) => {
if (response.ok) {
response.json().then((data) => resolve(data));
} else {
reject();
}
})
.catch(() => reject());
}),
});
If you use webpack and want to copy all the locale files to a static distribution folder of your application, you could use copy-webpack-plugin
to copy the files as part of the build process:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "node_modules/@tripetto/runner-chat/runner/locales/", to: "build/static/locales/" },
],
}),
],
};
import { run } from "@tripetto/runner-classic";
// Load the locale using await
run({
definition: /* Supply your form definition here */,
locale: async (locale) => {
const response = await fetch(`/locales/${locale}.json`);
return await response.json();
},
});
// Or use a promise
run({
definition: /* Supply your form definition here */,
locale: (locale) =>
new Promise((resolve, reject) => {
fetch(`/locales/${locale}.json`)
.then((response) => {
if (response.ok) {
response.json().then((data) => resolve(data));
} else {
reject();
}
})
.catch(() => reject());
}),
});
If you use webpack and want to copy all the locale files to a static distribution folder of your application, you could use copy-webpack-plugin
to copy the files as part of the build process:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "node_modules/@tripetto/runner-classic/runner/locales/", to: "build/static/locales/" },
],
}),
],
};
🔤 Runner translations
The stock runner packages come bundled with a set of translations (see a list here) for all the static text labels used in the runners. To load a runner translation, you need to load the appropriate translation JSON and feed it to the translations
property of the runner. The translation JSON files are in the runner/translations
folder of each stock runner package. If omitted, the default language is English.
Just like for the locale, there are two options for loading translations:
- Fixed translation: If you use the runner to serve a static form in a fixed language, you can load the appropriate translation at compile-time;
- Dynamic translation: If you want to load the appropriate translation based on the form language and/or user browser locale, you can dynamically load the translation.
It is possible to override translations or add a custom translation using the l10n
property of the runner.
Using a fixed translation (compile-time)
If your runner needs a fixed translation, you can load the translation during compile-time.
- Autoscroll
- Chat
- Classic
import { run } from "@tripetto/runner-autoscroll";
// Import the dutch translations
import translations from "@tripetto/runner-autoscroll/runner/translations/nl.json";
run({
definition: /* Supply your form definition here */,
translations
});
import { run } from "@tripetto/runner-chat";
// Import the dutch translations
import translations from "@tripetto/runner-chat/runner/translations/nl.json";
run({
definition: /* Supply your form definition here */,
translations
});
import { run } from "@tripetto/runner-classic";
// Import the dutch translations
import translations from "@tripetto/runner-classic/runner/translations/nl.json";
run({
definition: /* Supply your form definition here */,
translations
});
Make sure to enable the --resolveJsonModule
compiler flag in your TypeScript configuration to allow importing JSON files.
Using a dynamic translation (run-time)
To dynamically load translations, you need a server endpoint to deliver the translation JSON files to your application. In the following example, we assume the translations are available on the domain that runs the runner. The runner tries to load the appropriate translations based on the form language, user browser locale, or the supplied l10n
object.
- Autoscroll
- Chat
- Classic
import { run } from "@tripetto/runner-autoscroll";
// Load the translations using await
run({
definition: /* Supply your form definition here */,
translations: async (language) => {
const response = await fetch(`/translations/${language}.json`);
return await response.json();
},
});
// Or use a promise
run({
definition: /* Supply your form definition here */,
translations: (language) =>
new Promise((resolve, reject) => {
fetch(`/translations/${language}.json`)
.then((response) => {
if (response.ok) {
response.json().then((data) => resolve(data));
} else {
reject();
}
})
.catch(() => reject());
}),
});
If you use webpack and want to copy all the translation files to a static distribution folder of your application, you could use copy-webpack-plugin
to copy the files as part of the build process:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "node_modules/@tripetto/runner-autoscroll/runner/translations/", to: "build/static/translations/" },
],
}),
],
};
import { run } from "@tripetto/runner-chat";
// Load the translations using await
run({
definition: /* Supply your form definition here */,
translations: async (language) => {
const response = await fetch(`/translations/${language}.json`);
return await response.json();
},
});
// Or use a promise
run({
definition: /* Supply your form definition here */,
translations: (language) =>
new Promise((resolve, reject) => {
fetch(`/translations/${language}.json`)
.then((response) => {
if (response.ok) {
response.json().then((data) => resolve(data));
} else {
reject();
}
})
.catch(() => reject());
}),
});
If you use webpack and want to copy all the translation files to a static distribution folder of your application, you could use copy-webpack-plugin
to copy the files as part of the build process:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "node_modules/@tripetto/runner-chat/runner/translations/", to: "build/static/translations/" },
],
}),
],
};
import { run } from "@tripetto/runner-classic";
// Load the translations using await
run({
definition: /* Supply your form definition here */,
translations: async (language) => {
const response = await fetch(`/translations/${language}.json`);
return await response.json();
},
});
// Or use a promise
run({
definition: /* Supply your form definition here */,
translations: (language) =>
new Promise((resolve, reject) => {
fetch(`/translations/${language}.json`)
.then((response) => {
if (response.ok) {
response.json().then((data) => resolve(data));
} else {
reject();
}
})
.catch(() => reject());
}),
});
If you use webpack and want to copy all the translation files to a static distribution folder of your application, you could use copy-webpack-plugin
to copy the files as part of the build process:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "node_modules/@tripetto/runner-classic/runner/translations/", to: "build/static/translations/" },
],
}),
],
};
⚙️ Custom translations and settings
It is possible to supply custom translations and locale settings to the runner using the l10n
property. In combination with dynamic loading of locales and translations, this is a powerful feature where form creators can manage the language and locale to use and specify custom translations.
In the following example, the locale setting is set to auto
. Together with dynamic loading of the locale data, this automatically loads the appropriate locale based on the locale of the respondent.
- Autoscroll
- Chat
- Classic
import { run } from "@tripetto/runner-autoscroll";
run({
definition: /* Supply your form definition here */,
l10n: {
locale: "auto",
translations: {
"": {
language: "nl",
"plural-forms": "nplurals=2; plural=(n != 1);",
"plural-family":
"Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish)",
},
"runner#1|🆗 Buttons\u0004Back": [null, "Vorige"],
},
},
});
import { run } from "@tripetto/runner-chat";
run({
definition: /* Supply your form definition here */,
l10n: {
locale: "auto",
translations: {
"": {
language: "nl",
"plural-forms": "nplurals=2; plural=(n != 1);",
"plural-family":
"Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish)",
},
"runner#1|🆗 Buttons\u0004Back": [null, "Vorige"],
},
},
});
import { run } from "@tripetto/runner-classic";
run({
definition: /* Supply your form definition here */,
l10n: {
locale: "auto",
translations: {
"": {
language: "nl",
"plural-forms": "nplurals=2; plural=(n != 1);",
"plural-family":
"Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish)",
},
"runner#1|🆗 Buttons\u0004Back": [null, "Vorige"],
},
},
});
It is possible to manage the localization settings of the runner using the builder. See this guide to learn how to implement that.
📖 Reference
- Autoscroll
- Chat
- Classic
Have a look at the complete autoscroll runner API reference for detailed documentation. In the examples above, the following symbols were used:
Have a look at the complete chat runner API reference for detailed documentation. In the examples above, the following symbols were used:
Have a look at the complete classic runner API reference for detailed documentation. In the examples above, the following symbols were used: