Formatting
There are a lot of features i18n libraries offering besides basic string translation. If we DIY i18n, then we need to find those features and copy them in ourselves. In a large app nearing 1,000 different translation strings, I found that surprisingly I only use one of those features (value interpolation) and just once. So I will add that feature.
Add Interpolation
lib/poly-i18n/interpolate.tsts
const VARIABLE_PLACEHOLDER = /{(w+)}/gexport function interpolate(template: string, values?: Record<string, string>) {if (!values)return templatereturn template.replace(VARIABLE_PLACEHOLDER, (match, key) => values[key] || match)}
Look at the source code to this repo for my tests, but here's one just so you can see how the above function works:
lib/poly-i18n/interpolate.tsts
test('replaces placeholders with corresponding values', () => {const template = 'Hi {name}, welcome to {site}!'const values = { name: 'Alice', site: 'Kitbook' }expect(interpolate(template, values)).toEqual('Hi Alice, welcome to Kitbook!')})
You may need more features than that, but I've found that translators often get confused by special syntax in the translation strings and so I often design the UI to avoid the need for more complex features like numbers. Instead of using a sentence structure like There are {count} entries.
, I will use a label structure like Entries: {count}
.
Now we have all the pieces we need to build our [translator] function.