给博客接入一言(Hitokoto):四种展示位的统一思路
弄完天气组件之后,侧边栏总觉得还差点意思。一言(Hitokoto)这种一句小句子很适合:侧边栏挂一条、首页横幅打字机刷一句、页脚来一句、文章里随手插一句。
两个核心决定
1. 语句从哪来:local 打包 vs remote 拉取
sentences-bundle 按 a~l 共 12 类分文件存。组件里两种模式靠 bundleSource 切换:
local:构建时打包进public/hitokoto/hitokoto.json,零外部依赖,加载最快;remote:运行时直接拉 jsDelivr 远程包,不想跑构建就选它,但多一个fallbackToLocal开关。
2. 四类展示位统一
侧边栏 widget、首页横幅、页脚、文章内 ::hitokoto 指令,共用同一个配置中心 hitokotoConfig 和同一个 fetcher src/utils/hitokoto.ts。区别只在”展示参数”和”装数据的容器”。横幅额外有个独立 banner 块(独立开关 + 分类白名单 + 打字机),其它三个读全局开关再用各自 data-* 覆盖。
一句话概括:一个配置中心 + 一个 fetcher + N 个展示位各自接线。把开关收拢到 hitokotoConfig 之后,想调展示、换来源、加展示位都是局部改动,不会牵一发动全身。
几个真坑
1. 缓存没 TTL → 换不了句子
早期直接裸数组缓存,部署更新了 hitokoto.json 对已缓存老访客无效,表现就是”换不了句子”。加 6 小时 TTL 后,老访客最多 6 小时内自动拿到新库;旧格式裸数组兼容成 ts=0,自然失效重拉。缓存 key 要含 bundleSource + 启用分类 + remoteUrl——你关了某分类 key 就变,缓存立刻失效,不会显示关掉的类别。
2. fallbackToLocal 的两种行为别混
开关开 → 退本地包,组件照常显示;开关关且远程挂 → 侧边栏/页脚/文章内直接隐藏,但首页横幅副标题要切到主题 TypewriterText 预设节点(无预设才隐藏)。这两类行为不一样,写回退逻辑时得分开处理。
3. 页脚在 Swup 容器外
其它展示位在 Swup 容器里,页面切换 DOM 重渲染会重新触发绑定;页脚不在,跨页面不换 DOM。所以每次导航要把它的 dataset.filled 重置成 "0" 强制重拉,否则翻页后那句不更新。
4. 打字机按码点切分
Array.from(full) 而不是 String[i],否则中文/emoji 会截一半乱码。
5. remoteUrl 必须 @master
sentences-bundle 没 release tag,@latest 在 jsDelivr 直接 404。另外六个语言文件的 i18nKey 漏一个,astro check 就报翻译缺 key,部署前过一遍 check。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!











