我来自React背景,但是为了应对React巨大的捆绑大小,我将转而使用Svelte和Sapper开发我的下一个应用程序。然而,我在使用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
然后几乎立即更新并更改为
您的首选语言:en
如果在localStorage中没有lang
项,则更改为
您的首选语言:fr
在从开发人员控制台明确设置localStorage.setItem("lang", "fr")
并刷新后。
我知道存储库首先在服务器上初始化,其中window
为undefined
,然后在客户端上重新添加。因此,这种行为是可以预料的。
那么我的问题是:如何完全跳过服务器初始化?是否可能仅在客户端上设置存储库(其中定义了localStorage
),以便用户选择的语言立即可用?
我不能默认为用户更改首选语言后的所有内容都是英语或任何其他语言。我也不能在初始页面加载时通过navigator.language
从浏览器获取用户语言,因为在服务器上navigator
也是undefined
。
并且,在存储库重新添加之前出现空文本的闪烁会破坏我的应用程序的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
闪烁了,所以它基本上表现得像是只有客户端,此时已经可以。
我将继续完善我的项目,并查看是否还遇到其他问题。在那之前,我认为这解决了我的问题。
process.browser
似乎在常规的 JS 代码中也可以工作,而不仅仅是在模板中。谢谢! - Daniel Veihelmann