npm install react-content-font
如果你正在为如日语这类语言开发React应用,并且希望使用非系统字体,那么你可能会对此包产生兴趣。
如日语这类语言的字体文件体积巨大。例如,Noto Sans Japanese的单个字重(font weight)就有5.7 MB。让你的用户下载这样大的文件显然不理想。尤其是如果你需要的不止一个字重...
此包能检查一个页面,提取出该页面上所有的独特字符,并使用优化请求从Google Fonts请求只包含这些字符的字体!
在初始渲染时,它使用createTreeWalker高效地遍历DOM并获取所有字符。在初始渲染之后,它使用MutationObserver 只检查那些动态添加了新文本的更新节点。
使用方式非常简单,只需在应用的某个高层次位置添加上下文提供者即可。
例如,如果你有一个使用 App Router 的 Next.js应用,你可以像这样更新你的 app/layout.tsx
文件:
import FontProvider from 'react-content-font';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="jp">
<body>
<FontProvider fontName="Noto Sans JP">{children}</FontProvider>
</body>
</html>
);
}
只需通过 fontName
属性提供你需要的字体,默认情况下它将只请求普通的字重(也就是400)。
如果我需要多个字重怎么办?
请求额外字重只需要添加 fontWeights
属性,如下所示:
import FontProvider from 'react-content-font';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="jp">
<body>
<FontProvider fontName="Noto Sans JP" fontWeights={[400, 600]}>
{children}
</FontProvider>
</body>
</html>
);
}
我不确定是否有日语字体包含斜体样式,但也许你需要使用的字体有?如果是这样,你可以按照下面的方式请求你需要的任何字重的斜体样式:
import FontProvider from 'react-content-font';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="jp">
<body>
<FontProvider
fontName="Noto Sans JP"
fontWeights={[400, 600, ['ital', 400], ['ital', 900]]}
>
{children}
</FontProvider>
</body>
</html>
);
}
在这个例子中,除了常规的400和600字重,我们还会获取到400和900的斜体。
在Google Fonts API文档中,它提到 "通常更适合指定除默认 auto 以外的值"。默认情况下,当你为 Google Font 生成一个链接标签时,它设置 display=swap
。因此,这个包也会采用相同的设置。
但是,如果你需要别的配置,只需设置 display
属性即可,如下:
import FontProvider from 'react-content-font';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="jp">
<body>
<FontProvider fontName="Noto Sans JP" display="block">
{children}
</FontProvider>
</body>
</html>
);
}
display
的有效值是 'auto' | 'block' | 'swap' | 'fallback' | 'optional'
。
幸运的是,这个包还导出了一个具有标志位的上下文挂钩,它能让你知道字体是否已经加载完毕。
下面是一个PageText
组件的例子,该组件根据上下文将display
从hidden
改变为visible
。
'use client';
import { useFontContext } from 'react-content-font';
export default function PageText() {
const { isFontLoaded } = useFontContext();
return (
<p style={{ visibility: isFontLoaded ? 'visible' : 'hidden' }}>
よそはほかまあこの威圧心というのの後をしないう。きっと場合で仕事帰りはひょろひょろその評でたなりでするが行くたをも表裏できなけれでば、なぜにはもっなないうた。個人にできたのはついに十月から向後ますだない。もっと岡田さんから批評その道それほど説明が云った他人その自力いつか修養にというお吹聴だでますでて、この先刻は私か同人引込で思うば、大森さんののを自分の私に勢いごろかと広めよば私手でご話の出ように引続きお[#「に解らうだので、とにかくたとい指図にするだろといるです事を考えだう。
</p>
);
}
重要的一点是,你必须渲染文本否则字符将不会被发现,并且不会被包含在请求的字体中。
例如,不要这样做:
'use client';
import { useFontContext } from 'react-content-font';
export default function PageText() {
const { isFontLoaded } = useFontContext();
return (
<>
{isFontLoaded && (
<p>
よそはほかまあこの威圧心というのの後をしないう。きっと場合で仕事帰りはひょろひょろその評でたなりでするが行くたをも表裏できなけれでば、なぜにはもっなないうた。個人にできたのはついに十月から向後ますだない。もっと岡田さんから批評その道それほど説明が云った他人その自力いつか修養にというお吹聴だでますでて、この先刻は私か同人引込で思うば、大森さんののを自分の私に勢いごろかと広めよば私手でご話の出ように引続きお[#「に解らうだので、とにかくたとい指図にするだろといるです事を考えだう。
</p>
)}
</>
);
}
幸运的是,上下文中还有另一个标志位,它能让你知道字体是否正在被更新。
与前面的例子类似,你可以推迟显示更新的内容,像这样:
'use client';
import { useFontContext } from 'react-content-font';
export default function PageText() {
const { isFontUpdating } = useFontContext();
return (
<p style={{ visibility: isFontUpdating ? 'visible' : 'hidden' }}>
よそはほかまあこの威圧心というのの後をしないう。きっと場合で仕事帰りはひょろひょろその評でたなりでするが行くたをも表裏できなけれでば、なぜにはもっなないうた。個人にできたのはついに十月から向後ますだない。もっと岡田さんから批評その道それほど説明が云った他人その自力いつか修養にというお吹聴だでますでて、この先刻は私か同人引込で思うば、大森さんののを自分の私に勢いごろかと広めよば私手でご話の出ように引続きお[#「に解らうだので、とにかくたとい指図にするだろといるです事を考えだう。
</p>
);
}
重要的一点是,你必须渲染文本否则字符将不会被发现,并且不会被包含在请求的字体中。
当然可以!