У меня есть опыт работы с React, но я перехожу на Svelte и Sapper для своего следующего приложения, чтобы бороться с огромным размером пакетов, которые сейчас поставляются с React. Однако у меня возникли проблемы с инициализацией хранилища Svelte данными, полученными из localStorage.
Согласно документации Sapper (https://sapper.svelte.dev/docs#Getting_started) , Я создал свой проект, запустив npx degit "sveltejs/sapper-template#rollup" my-app
из командной строки. Затем я установил зависимости и удалил демонстрационный код в папке src
.
Затем я создал два файла: src/routes/index.svelte
и 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
который затем почти сразу обновляется и меняется на
Ваш предпочтительный язык: en
когда в localStorage нет lang
элемента, и меняется на
Ваш предпочтительный язык: fr
После явной установки localStorage.setItem("lang", "fr")
в консоли разработчика и обновления.
Я знаю, что хранилище сначала инициализируется на сервере, где window
равно undefined
, а затем выполняется регидратация на клиенте. Так что такое поведение ожидаемо.
Итак, мой вопрос: как я могу полностью пропустить инициализацию сервера? Можно ли настроить магазин только на клиенте (где определено localStorage
), чтобы язык, выбранный пользователем, был доступен сразу же?
Я не могу по умолчанию иметь все на английском или любом другом языке после того, как пользователь решил изменить свой предпочтительный язык. Я также не могу получить язык пользователя из браузера через navigator.language
при начальной загрузке страницы, поскольку navigator
также undefined
на сервере.
И появление вспышки пустого текста до регидратации магазина испортит UX для моего приложения, особенно когда значение userLang
будет использоваться повсюду с переводами.
Так что любые стратегии или хаки для этого определенно приветствуются.
**** Более глубокая проблема ****
На самом деле я бы предпочел, чтобы для этого приложения не был вообще рендеринг на стороне сервера, но мне нужны все другие отличные функции, которые предоставляет Sapper, такие как маршрутизация, предварительная выборка и создание статических сайтов.
Поэтому я попытался запустить npx sapper export
в соответствии с docs, чтобы создать полностью статический сайт и попытаться удалить сервер из уравнения, но та же проблема все еще возникает, даже если сервер вообще не используется.
Есть ли у кого-нибудь совет, как настроить Sapper и отключить SSR, но сохранить другие функции?
Спасибо!
**** Обновление ****
Согласно ответу Рича Харриса, упаковка разметки с помощью {#if process.browser}
отлично справляется. Итак, я обновил src/routes/index.svelte
file вот так:
<script>
import {userLang} from "../store";
</script>
{#if process.browser}
<p>Your Preferred Language: {$userLang}</p>
{/if}
И переменная userLang
сразу устанавливается со значением от localStorage
или по умолчанию на en
, как я задумал для этой простой демонстрации. Вспышки null
больше нет, так что, по сути, он ведет себя как клиентская только в этот момент.
Я буду работать над конкретизацией своего проекта и посмотрю, с какими еще проблемами я столкнусь. А пока, думаю, это решит мою проблему.