@epic-web/客户点
使用客户端提示删除错误内容的闪光检测用户的设备偏好( 如时区和颜色方案) 和 将它们发送到服务器, 这样您就可以让服务器渲染正确的内容 他们.
npm install @epic-web/client-hints
问题
有时,你的服务器提供了代码,需要了解客户端 浏览器不会发送。 例如,服务器可能需要知道 用户首选的语言,或者用户是否偏好光线模式或暗线模式.
对于其中的一些,您应该有用户的偏好,这些偏好可以在 饼干或数据库,但你不能这样做 对于第一次访客。 尽你所能 当然是猜测 很不幸,如果你猜错了,你最后会遇到糟糕的经历 用于用户.
经常发生的情况是 我们制造HTML 这是错误的 然后水分 与客户端 JavaScript 交互的应用程序 用户偏好,现在我们知道该做什么了。 这是伟大的, 不过我们已经弄错了 所以用水浇水就会引起转变 从错误的事物到正确的事物, 它的叫声,甚至更糟糕 用户的经验比把错误的东西留在原地还要多(我称之为“闪光” 内容不正确”。 在控制台里你会出错的,当这时 发生的原因.
解决办法
客户提示是一种避免这个问题的方法. 这个 标准 由于这项工作仍在进行之中,而且他们何时会 降落在所有主要浏览器中 我们所关心的支持。 所以这是 "poryfill" 类似客户端提示头的功能 标准.
标准背后的想法是当浏览器提出请求时,而不是 服务器立即响应请求, 而不是回复客户端 通知它需要某些信头 然后客户端会重复 添加了这些信头的请求。 服务器然后可以正确回答 内容.
我们的解决方案是受这个启发的,但是我们不用信封,而是使用饼干(cookie)
实际上,相对于标题来说,可以有一些好处。 想法是让一些
Java 脚本位于顶端 <head> 将我们的文件放在其他文件之前。 这是
一个快速的小型内置脚本, 可以检查用户的 cookie 是否为预期
客户提示 。 如果它们不在场,或者它们已经过时, 它会设置饼干
并触发重新装入页面。 有效做同样的事情浏览器
和客户的提示头有关.
这样我们就可以在服务器上 第一次做对了 触发内容布局变化或错误内容的闪光。 在那之后,我们.. 首先,客户端将拥有正确的饼干,服务器将 以后每次都做对的事.
小心小费 打开 EpicWeb.dev (英语)数字 :
使用量
就是这样 @epic-web/client-hints 用于 Epic Stack 中:
import { getHintUtils } from '@epic-web/client-hints'
import {
clientHint as colorSchemeHint,
subscribeToSchemeChange,
} from '@epic-web/client-hints/color-scheme'
import { clientHint as timeZoneHint } from '@epic-web/client-hints/time-zone'
import { useRevalidator } from 'react-router'
import * as React from 'react'
import { useRequestInfo } from './request-info.ts'
const hintsUtils = getHintUtils({
theme: colorSchemeHint,
timeZone: timeZoneHint,
// add other hints here
})
export const { getHints } = hintsUtils
export function useHints() {
const requestInfo = useRequestInfo()
return requestInfo.hints
}
export function ClientHintCheck({ nonce }: { nonce: string }) {
const { revalidate } = useRevalidator()
React.useEffect(
() => subscribeToSchemeChange(() => revalidate()),
[revalidate],
)
return (
<script
nonce={nonce}
dangerouslySetInnerHTML={{
__html: hintsUtils.getClientHintCheckScript(),
}}
/>
)
}
然后在根加载器中安装服务器侧码(何方授权
useRequestInfo 钩子)看起来像这样:
export async function loader({ request }: DataFunctionArgs) {
return {
// other stuff here...
requestInfo: {
hints: getHints(request),
},
}
}
说明包括:
@epic-web/client-hints/color-scheme(也出口)subscribeToSchemeChange(中文(简体) )@epic-web/client-hints/time-zone@epic-web/client-hints/reduced-motion(也出口)subscribeToMotionChange(中文(简体) )
财务问题
自定义饼干名称
如果您想要自定义饼干名称, 您可以像这样简单地覆盖它 :
const hintsUtils = getHintUtils({
theme: {
...colorSchemeHint,
cookieName: 'my-custom-cookie-name',
},
})
如果你在使用一个 subscribeTo*Change 函数,您需要通过
您的定制饼干名称 与这些.
自定义提示
如果你有什么习惯,你想检测, 提示实际上是漂亮的 很简单 以下是时区提示的代码:
import { type ClientHint } from '@epic-web/client-hints'
export const clientHint = {
cookieName: 'CH-time-zone',
getValueCode: 'Intl.DateTimeFormat().resolvedOptions().timeZone',
fallback: 'UTC',
} as const satisfies ClientHint<string>
如果您出于某种原因( 如从字符串中更改) 需要转换值
然后,你可以使用布尔等 transform 方法。 颜色是这样的
方案提示使用如下:
import { type ClientHint } from '@epic-web/client-hints'
export const clientHint = {
cookieName: 'CH-prefers-color-scheme',
getValueCode: `window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'`,
fallback: 'light',
transform(value) {
return value === 'dark' ? 'dark' : 'light'
},
} as const satisfies ClientHint<'dark' | 'light'>
这样做的好处是 提示的类型只会是
'dark' | 'light' 没有 string。 。 。 .
许可证
麻省理工学院
