sveltesvelte-3snowpack

Svelte-i18n with Snowpack shows blank page without errors


I am using Svelte 3 + Snowpack 3 + Routify + Svelte-i18n. I am not using Sapper. I installed everything with this template. And this is my repo where you can see all my files.

I am following the official tutorial of svelte-i18n.

Problem: I can't translate my page with their tutorial. I want it to work async because I will have lots of translations for lots of pages.

But when I use this script in my .svelte file it just works:

import { _ } from 'svelte-i18n';
import { addMessages, init } from "svelte-i18n";

import en from "./lang/en.json";
import az from "./lang/az.json";

addMessages("en", en);
addMessages("az", az);

init({
    initialLocale: "az",
});

When I delete it and use only this as they suggest, I get a blank screen without any error:

import { _ } from 'svelte-i18n';

Everything other than that is exactly the same as the tutorial. I suspect the source of reason in _layout.svelte file as I don't know what is that for. And as my researches, it is something related to Sapper. I don't know if Snowpack uses it but maybe I need to make some changes to make it work with Snowpack. Also, it looks like the tutorial is written Sapper in mind as they call its name several times.


Solution

  • You can see the error that you are getting if you open your browser's developer tools. I ran your app locally and saw the following error: Uncaught (in promise) Error: [svelte-i18n] Cannot format a message without first setting the initial locale.

    The issue is that you are using register to load your dictionaries and trying to retrieve messages before the dictionaries are ready. This method runs asynchronously, so your locales might not be loaded by the time the Svelte template renders. You have two options:

    1. Load the dictionaries synchronously using addMessages in your entry point. This way you don't have to wait for the dictionaries to load in order to retrieve messages.
    // index.js
    import { register, init, getLocaleFromNavigator, addMessages } from 'svelte-i18n';
    import en from './pages/lang/en.json'
    import az from './pages/lang/az.json'
    addMessages('en', en);
    addMessages('az', az);
    

    This could be less performant if you have a lot of locales since they would all need to be loaded before starting your app.

    1. Continue to load the dictionaries asynchronously and wait for them to load before retrieving messages using the $isLoading store. The value of this store will tell you if it's safe to retrieve messages or not.
    <!-- index.svelte -->
    <script>
        import { _, isLoading } from 'svelte-i18n';
    </script>
    
    {#if $isLoading}
        <p>Loading</p>
    {:else}
        <h1 class="mx-auto mb-10 font-semibold text-4xl text-shadow text-gray-900">{$_('home.hero-h')}</h1>
        <h5 class="text-gray-700 mb-12">{$_('home.hero-p')}</h5>
    {/if}