我来自React的背景,但是我要切换到Svelte和Sapper来开发我的下一个应用程序,以应对这些天React随附的庞大捆绑包规模。但是,我无法使用从localStorage检索的数据初始化Svelte的存储。
根据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
然后几乎立即更新并更改为
您的首选语言:
在localStorage中没有lang
项并且更改为
您的首选语言:fr
在开发者控制台中明确设置localStorage.setItem("lang", "fr")
并刷新后。
我知道商店首先在window
为undefined
的服务器上初始化,然后在客户端重新补水。因此,这种行为是预期的。
所以我的问题是:如何完全跳过服务器初始化?是否可以仅在客户端(定义为localStorage
的客户端上设置商店,以便用户选择的语言立即可用?
在用户选择更改其首选语言之后,我不能默认将所有内容都用英语或其他任何语言显示。我也无法通过初始页面加载时的navigator.language
从浏览器获取用户语言,因为navigator
在服务器上也是undefined
。
在商店重新命名之前,会出现空白文本提示,这会弄乱我的应用程序的UX,尤其是当userLang
的值将在翻译中随处使用时。
因此,对此表示赞赏的任何策略或技巧。
**** 更深的问题 ****
我实际上更愿意完全不为该应用程序提供服务器端渲染,但是我确实需要Sapper提供的所有其他出色功能,例如路由,预取和静态站点构建。
因此,我尝试按照docs运行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
不再闪耀,因此从本质上讲,它仅在此时像客户端一样。
我将努力完善我的项目,看看是否还有其他问题。直到那时,我认为这解决了我的问题。
答案 0 :(得分:2)
当前,SSR是非可选的。 SPA模式存在一个问题https://github.com/sveltejs/sapper/issues/383,它会按照您描述的方式运行,我们只需要解决这个问题即可。
我们还计划在以后的版本中https://github.com/sveltejs/sapper/issues/576
内置对i18n的支持。同时,您可以通过将所有标记包装在{#if process.browser}
中来伪造它-内部的任何内容都不会由服务器呈现,但是一旦JavaScript插入就会显示出来。