Vincent Decaux
Vincent Decaux

Reputation: 10714

Use Svelte i18n in service / simple JS file

I use Svelte i18n for my project, it works perfectly in my Svelte components.

But I have some JS files (for constants for example), I want to use i18n to translate some keys, like (in /services/constants.js) :

import { _ } from 'svelte-i18n'

export const STATUS_OK = 1;
export const STATUS_PENDING = 2;
export const STATUS_ERROR = 3;
export const STATUS_INACTIVE = 4;
export const STATUS_PRICE_NOT_FOUND = 5;

export const STATUTES = {
  [STATUS_OK]: {
    text: _('urls.statutes.ok'),
    class: 'text-green-500',
  },

But I got an error, can I use _ function in a JS file ? Or should I create kind of svelte component to handle my constants ?

Upvotes: 6

Views: 1975

Answers (2)

Pepa Linha
Pepa Linha

Reputation: 31

Answer from Stephane Vanraes is right, but there is a solution from svelte-i18n

import { unwrapFunctionStore, format, formatNumber } from 'svelte-i18n';

const $formatNumber = unwrapFunctionStore(formatNumber);
const $format = unwrapFunctionStore(format);

See FAQ: https://github.com/kaisermann/svelte-i18n/blob/main/docs/FAQ.md#can-i-use-the-formatter-functions-outside-of-a-svelte-component

Upvotes: 3

Stephane Vanraes
Stephane Vanraes

Reputation: 16411

If I understood the way svelte-i18n works correctly, _ is a store, and this is why you can do the following in a component

<p>{$_('urls.statuses.ok')}</p>

The $ creates a subscription and get's the current value of the store, on which you execute a function to get the given key.

In your code you do _('urls.statuses.ok') which is a function you are trying to execute on the store and not on the value of the store. And it is this 'value' that actually provides you with the functionality of internationalization.

You cannot use $ in a javascript file though, so here you are left with two options:

use get()

You can import { get } from 'svelte/store' this gives you a function that would return the current value of a store, meaning you could change your code to look like this:

text: get(_)('urls.statuses.ok')

One downside of this is that it doesn't create a subscription, or in other words, if the language changes this constant will not change because get doesn't run again, it only ran once.

return a function from text

The other option is a bit of a bigger change namely redefining text as a function

text: _ => _('urls.statuses.ok')

Here we pass the store into the function from outside inside of importing it directly into the javascript file. The usage would be

<p>{STATUTES.STATUS_OK($_)}</p>

As you see, we pass the value of the store into the function, meaning that inside the function we can use our store as expected and because when the language change, this block will be re-evaluated, it will always get the current language instead of the initial one like we got with get.

Upvotes: 14

Related Questions