next.js + daisyui + shiki 代码块多主题支持一例
文中给出的例子同时也是本站使用的方案(有改动,截至文章发布时间,以后说不定会重构,哈哈)。
另,shiki 版本为 3.x。
使用 shiki 生成代码块
创建 highlighter:
TYPESCRIPT
const highlighter = await createHighlighter({
// 这里列会用到的主题
// 注意,不是说 themes 要以 [light, dark] 的格式填主题
// 你完全可以多列几个
themes: ["github-light", "github-dark"],
// 这里列你有用到的语言
langs: ["typescript"],
});
生成代码块:
TYPESCRIPT
const rsl = highlighter.codeToHast(code, {
lang,
// 这里才是控制 light 和 dark 要用什么主题的
themes: {
light: "github-light",
dark: "github-dark",
},
});
编写 css
直接用的问题是:shiki 不会自己生成 css 文件,所以,要手动写切换主题的 css。正好 daisyui 也有主题切换这一概念:
HTML
<html data-theme="light"></html>
我们就利用一下这个:
CSS
@media (prefers-color-scheme: dark) {
html:not([data-theme]) .shiki,
html:not([data-theme]) .shiki span {
color: var(--shiki-dark) !important;
}
}
html[data-theme="dark"] .shiki,
html[data-theme="dark"] .shiki span {
color: var(--shiki-dark) !important;
}
另外,shiki 会注入背景色到 <pre> 的 style 里,所以要写 js 代码把 style 里的 background-color 干掉。