Svelte: Internationalization support

Created on 20 Dec 2017  Â·  5Comments  Â·  Source: sveltejs/svelte

I'm opening this issue to discuss what would be the suggested pattern to handle translations with svelte. The ideal output of this discussion might be examples for docs, maybe a new feature that makes it simpler, not sure yet. Let's assume that we build a big app that handles few languages. Some ideas:

a)

Import where needed:

// Hello.html
<p>{{translate('hello')}}</p>
<script>
import { translate } from './utilities/translations'
export default {
  helpers: { translate }
}
</script>

Pros: simple, works out of the box, available only where needed
Cons: repetition of the import

b)

Pass it to all child components inside of the top component

// Main.html
<Hello/>
<script>
import Hello from './Hello.html'
import { translate } from './utilities/translations'
export default {
  // somehow pass the translation method to all child components that it's available in the template (?)
  components: { Hello }
}
</script>
// Hello.html
<p>{{translate('hello')}}</p>

Pros: no repetition, saves keystrokes
Cons: global dependency, available everywhere

c)

Pass it to all child components outside of the top component

// main.js
import Main from './Main.html'
import { translate } from './utilities/translations'
new Main({
   // somehow pass the translation method to all child components so that it's available in the templates
  // maybe:
  helpers: { translate }
})
// Hello.html
<p>{{translate('hello')}}</p>

Pros: no repetition, saves keystrokes
Cons: global dependency, available everywhere

I don't have a strong opinion which one is better, any other ideas? Maybe there's an option to do so already and I missed it :) Please let me know what you think.

Most helpful comment

What about Store?

// main.js
const store = new Store({
  translate: str => {
    // some logic happens
  }
});

const app = new App({ target, store });
<p>{{$translate('hello')}}</p>

translate could even be set lazily (after you've lazy-loaded the translations, for example) or a computed property that depends on a lang property that the user can select — whatever is most suitable for the app in question.

All 5 comments

There is this https://github.com/sveltejs/svelte/pull/1023

But I suppose that's a variation of (a) just moving the repetition to oncreate. Unless you want to sprinkle your templates with {{root.options.translate('hello')}}

This seems like another case for dependency injection.

What about Store?

// main.js
const store = new Store({
  translate: str => {
    // some logic happens
  }
});

const app = new App({ target, store });
<p>{{$translate('hello')}}</p>

translate could even be set lazily (after you've lazy-loaded the translations, for example) or a computed property that depends on a lang property that the user can select — whatever is most suitable for the app in question.

Thanks guys :)

Having the translate method defined as a part of the store works fine. I thought the purpose of the store is to hold the data and not the utility methods. The only concern I have is that it might be unexpected for people to have it there, but maybe it just shouldn't be passed this way. A computed texts property might be a better choice in some scenarios.

Seems like it would not work with Svelte3 ...
Any other ideas? Maybe somebody have tool like i18nliner?

I've written a library using the store approach.
Forked it from the svelte-intl package and just send a PR.

There's also the svelte-i18n, but I didn't use because the bundle is too bloated (about 73kB gz)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matt3224 picture matt3224  Â·  3Comments

Rich-Harris picture Rich-Harris  Â·  3Comments

sskyy picture sskyy  Â·  3Comments

robnagler picture robnagler  Â·  3Comments

st-schneider picture st-schneider  Â·  3Comments