@epic-web/client-hints

中文文档
1.3.9发布于 2026/03/25MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 21.4万

基于服务器的浏览器用户偏好(如主题偏好和时区等).

中文使用文档
文档目录7 节
  1. 问题
  2. 解决办法
  3. 使用量
  4. 财务问题
  5. 自定义饼干名称
  6. 自定义提示
  7. 许可证

@epic-web/客户点

使用客户端提示删除错误内容的闪光

检测用户的设备偏好( 如时区和颜色方案) 和 将它们发送到服务器, 这样您就可以让服务器渲染正确的内容 他们.

npm install @epic-web/client-hints

Build Status MIT License Code of Conduct

问题

有时,你的服务器提供了代码,需要了解客户端 浏览器不会发送。 例如,服务器可能需要知道 用户首选的语言,或者用户是否偏好光线模式或暗线模式.

对于其中的一些,您应该有用户的偏好,这些偏好可以在 饼干或数据库,但你不能这样做 对于第一次访客。 尽你所能 当然是猜测 很不幸,如果你猜错了,你最后会遇到糟糕的经历 用于用户.

经常发生的情况是 我们制造HTML 这是错误的 然后水分 与客户端 JavaScript 交互的应用程序 用户偏好,现在我们知道该做什么了。 这是伟大的, 不过我们已经弄错了 所以用水浇水就会引起转变 从错误的事物到正确的事物, 它的叫声,甚至更糟糕 用户的经验比把错误的东西留在原地还要多(我称之为“闪光” 内容不正确”。 在控制台里你会出错的,当这时 发生的原因.

解决办法

客户提示是一种避免这个问题的方法. 这个 标准 由于这项工作仍在进行之中,而且他们何时会 降落在所有主要浏览器中 我们所关心的支持。 所以这是 "poryfill" 类似客户端提示头的功能 标准.

标准背后的想法是当浏览器提出请求时,而不是 服务器立即响应请求, 而不是回复客户端 通知它需要某些信头 然后客户端会重复 添加了这些信头的请求。 服务器然后可以正确回答 内容.

我们的解决方案是受这个启发的,但是我们不用信封,而是使用饼干(cookie) 实际上,相对于标题来说,可以有一些好处。 想法是让一些 Java 脚本位于顶端 <head> 将我们的文件放在其他文件之前。 这是 一个快速的小型内置脚本, 可以检查用户的 cookie 是否为预期 客户提示 。 如果它们不在场,或者它们已经过时, 它会设置饼干 并触发重新装入页面。 有效做同样的事情浏览器 和客户的提示头有关.

这样我们就可以在服务器上 第一次做对了 触发内容布局变化或错误内容的闪光。 在那之后,我们.. 首先,客户端将拥有正确的饼干,服务器将 以后每次都做对的事.

小心小费 打开 EpicWeb.dev (英语)数字 :

Kent smiling with VSCode showing code in the client-hints.tsx file

使用量

就是这样 @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。 。 。 .

许可证

麻省理工学院

版本与发布记录

@epic-web/client-hints 共发布 15 个版本,首次发布于 2023/11/23;过去 12 个月发布了 1 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.3.9latest2026/03/257 个月前
1.3.82025/08/171.2 年前
1.3.72025/07/041.4 年前
1.3.62025/07/041.4 年前
1.3.52024/10/062 年前
1.3.42024/10/032 年前

关于 @epic-web/client-hints 的常见问题

@epic-web/client-hints 是什么?

基于服务器的浏览器用户偏好(如主题偏好和时区等).

如何安装 @epic-web/client-hints?

在项目目录运行 npm install @epic-web/client-hints,或使用 pnpm add / yarn add / bun add。

@epic-web/client-hints 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@epic-web/client-hints 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@epic-web/client-hints 可以商用吗?

@epic-web/client-hints 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@epic-web/client-hints 的下载量有多少?

根据 npm 官方下载统计,@epic-web/client-hints 在 2026/10/14 – 2026/11/12 这 30 天内被下载 214,059 次,日均约 7,135 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@epic-web/client-hints 还在维护吗?

最新版本 1.3.9 发布于 2026/03/25(7 个月前);至今共发布 15 个版本,其中过去 12 个月发布了 1 个;首次发布于 2023/11/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。