这是Secure Authentication in Svelte using Hooks的后续文章,以扩展我们的挂钩文件。如果您正在寻找一种在Sveltekit应用中实现身份验证的方法,请肯定地查看该文章。
如果您曾经构建了一个具有多个主题的站点,那么您有可能会遇到令人讨厌的问题,即在计算主题值的客户端之前让网站闪存。在本教程中,我们将设置hooks.server.js
文件,以允许在发送给客户端之前处理一个动态主题。
初始设置
如果您还没有hooks.server.js
文件,则最基本的版本如下:
// hooks.server.js
export const handle = async({event, resolve}) => {
const response = await resolve(event);
return response;
}
这在上一篇文章中解释了这一点,但这是任何新读者的进修:
event
属性包含与文件请求有关的所有信息。这包括用户的cookie,浏览器HTTP标头和特定请求的URL。您可以在此处阅读更多Indepth文档:SvelteKit Hooks。
第二个项目resolve
是创建完成HTML的函数。
我们的handle()
函数是await resolve(event)
调用。这是一件Sveltekit的东西,本质上告诉服务器在将HTML发送给客户端之前就可以构建HTML了。返回该response
值以正常方式呈现页面。
在本教程中,我们将使用一个简单的HTML数据属性来处理将使用CSS的。在您的app.html
页面中,继续将其添加到您的<html>
标签中:
<html lang="en" data-theme="">
这就是我们为HTML页面所需的所有设置。继续关闭它,让我们打开我们的hooks.server.js
文件。
现在,我们要修改我们的resolve()
功能以查找字符串data-theme=""
并用用户的主题cookie值替换。我们可以这样做:
// hooks.server.js
export const handle = async({event, resolve}) => {
const response = await resolve(event, {
// Processing will go here
});
return response;
}
第一步是将对象添加为resolve()
的第二个属性。在此处,我们可以调用Svelte对象属性transformPageChunk
,并将其传递给函数。看起来像这样:
// hooks.server.js
export const handle = async({event, resolve}) => {
const response = await resolve(event, {
transformPageChunk: ({html}) => {
// This section will modify the HTML
// before being returned to the client
}
});
return response;
}
我们想首先检查用户的主题cookie是否存在。这可能是没有cookie的新用户,也可以是现有用户。一种简单的方法是检查从root handle()
函数传递的event.cookies
// hooks.server.js
export const handle = async({event, resolve}) => {
const response = await resolve(event, {
transformPageChunk: ({html}) => {
// This section will modify the HTML
// before being returned to the client
let currentTheme = cookies.get("theme");
// Make sure the cookie was found, if not, set it to dark
if(!currentTheme) {
currentTheme = "dark";
cookies.set("theme", currentTheme)
}
}
});
return response;
}
此值如果不存在,将返回null,因此添加默认值很有用。我们还可以将其作为为所有新用户设置主题cookie的机会。在上面的代码中,我们将默认值设置为dark
。
现在我们已经准备好主题值,我们可以在发送给客户端之前更新HTML。最简单的方法是在整个HTML上使用replace()
JavaScript函数。请注意,replace()
是无损的,因此,如果要进行其他处理,则必须将其保存到新变量中。
// hooks.server.js
export const handle = async({event, resolve}) => {
const response = await resolve(event, {
transformPageChunk: ({html}) => {
// This section will modify the HTML
// before being returned to the client
let currentTheme = cookies.get("theme");
// Make sure the cookie was found, if not, set it to dark
if(!currentTheme) {
currentTheme = "dark";
cookies.set("theme", currentTheme)
}
return html.replace(`data-theme=""`, `data-theme="${currentTheme}"`);
}
});
return response;
}
这样,在发送到客户端之前,您的主题现在正在处理。不再闪烁!
CSS示例
如果您很好奇如何使用CSS访问此问题,则可以使用CSS变量这样:
:root {
--body: #fff;
--text: #000;
}
[data-theme='dark']:root {
--body: #000;
--text: #fff;
}
body {
background-color: var(--body);
color: var(--text);
}