19

私は React のバックグラウンドを持っていますが、最近の React に付随する巨大なバンドル サイズと戦うために、次のアプリケーションでは Svelte と Sapper に切り替えています。ただし、localStorage から取得したデータを使用して Svelte のストアを初期化するのに問題があります。

Sapper ドキュメント ( https://sapper.svelte.dev/docs#Getting_startednpx degit "sveltejs/sapper-template#rollup" my-app ) に従って、コマンド ラインから実行してプロジェクトを作成しました。src次に、依存関係をインストールし、フォルダー内のデモ コードを削除しました。

src/routes/index.svelte次に、との 2 つのファイルを作成しましsrc/store/index.jsた。

両方のコード:

src/store/index.js

    import {writable} from "svelte/store";
    
    export let userLang;
    
    if(typeof window !== "undefined") {
        userLang = writable(localStorage.getItem("lang") || "en");
    } else {
        userLang = writable(null);
    }

src/routes/index.svelte

    <script>
        import {userLang} from "../store";
    </script>
    
    <p>Your Preferred Language: {$userLang}</p>

アプリケーションを実行してindexルートに到達すると、次のように表示されます。

優先言語: null

その後、ほとんどすぐに更新されて変更されます

優先言語: ja

langlocalStorage に項目がなく、

優先言語: fr

localStorage.setItem("lang", "fr")開発者コンソールから明示的に設定して更新した後。

私は、ストアが最初にサーバー上で初期化され、window次にundefinedクライアント上で再水和されていることを知っています。したがって、この動作は予期されたものです。

私の質問は、サーバーの初期化を完全にスキップするにはどうすればよいですか? localStorageユーザーが選択した言語をすぐに利用できるように、ストアをクライアント ( が定義されている場所) にのみ設定することはできますか?

ユーザーが優先言語を変更することを選択した後、デフォルトですべてを英語または他の言語にすることはできません。サーバー上にもあるnavigator.languageため、最初のページの読み込み時にブラウザーからユーザー言語を取得することもできません。navigatorundefined

また、ストアがリハイドレートする前に空のテキストのフラッシュが表示されると、アプリケーションの UX が台無しになります。特に、 の値がuserLang翻訳であらゆる場所で使用される場合はそうです。

したがって、これに対する戦略やハックは間違いなく高く評価されます。

****より深い問題****

私は実際には、このアプリケーションにサーバー側のレンダリングがまったくないことを望んでいますが、ルーティング、プリフェッチ、静的サイト構築など、Sapper が提供する他のすべての優れた機能が必要です。

したがって、ドキュメントnpx sapper exportに従って実行して、サーバーを方程式から削除するために完全に静的なサイトを生成しようとしましたが、サーバーがまったく使用されていなくても、まったく同じ問題が発生します。

Sapper を設定して SSR をオフにし、他の機能を維持する方法について誰かアドバイスはありますか?

ありがとうございました!

****更新****

Rich Harris の回答によると、マークアップを でラップすると{#if process.browser}うまくいきます。だから私は次のsrc/routes/index.svelteようにファイルを更新しました:

    <script>
        import {userLang} from "../store";
    </script>

    {#if process.browser}
        <p>Your Preferred Language: {$userLang}</p>
    {/if}

そして、この単純なデモで意図したように、userLang変数はすぐに値localStorageまたはデフォルト値で設定されます。enのフラッシュはもうないnullので、基本的にはこの時点でのみクライアント側のように動作します。

プロジェクトの肉付けに取り組み、さらに問題が発生するかどうかを確認します。それまでは、これで問題は解決すると思います。

4

1 に答える 1