跳转到内容

实验性字体 API

类型: FontFamily[]

添加于: astro@5.7.0

此实验性功能允许你通过统一、完全可定制且类型安全的 API 使用来自文件系统和各种字体提供商(例如 Google、Fontsource、Bunny)的字体。

Web 字体会影响页面的加载时间和渲染时间。此 API 通过自动化的 Web 字体优化(包括预加载链接、优化的备用字体和预设的默认值)来帮助你保持网站的高性能。查看常见使用示例

要启用此功能,请配置一个 experimental.fonts 对象,并至少包含一种字体

astro.config.mjs
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
experimental: {
fonts: [{
provider: fontProviders.google(),
name: "Roboto",
cssVariable: "--font-roboto"
}]
}
});

然后,在你的 <head> 中添加 <Font /> 组件和全站样式

src/components/Head.astro
---
import { Font } from 'astro:assets';
---
<Font cssVariable='--font-roboto' preload />
<style>
body {
font-family: var(--font-roboto);
}
</style>
  1. experimental.fonts 接受一个字体对象数组。对于每种字体,你必须指定一个 provider、字体族 name,并定义一个 cssVariable 来引用你的字体。

    以下示例配置了来自 Google Fonts 的“Roboto”字体族

    astro.config.mjs
    import { defineConfig, fontProviders } from "astro/config";
    export default defineConfig({
    experimental: {
    fonts: [{
    provider: fontProviders.google(),
    name: "Roboto",
    cssVariable: "--font-roboto"
    }]
    }
    });

    还有更多配置选项可用,例如定义备用字体族以及要下载的 weights(字重)和 styles(样式),其中一些选项取决于你选择的提供商。

    查看完整的配置参考以了解更多信息。

  2. 使用 <Font /> 组件应用样式。它必须被导入并添加到你页面的 <head> 中。提供字体的 cssVariable 是必需的,你也可以选择性地输出预加载链接

    src/components/Head.astro
    ---
    import { Font } from 'astro:assets';
    ---
    <Font cssVariable="--font-roboto" preload />

    这通常在像 Head.astro 这样的组件中完成,该组件用于通用的网站布局。

    查看完整的 <Font> 组件参考以了解更多信息。

    由于 <Font /> 组件会生成带有字体声明的 CSS,你可以使用 cssVariable 来引用该字体族

    <style>
    body {
    font-family: var(--font-roboto);
    }
    </style>

Astro 重新导出了大部分 unifont 提供商。以下提供商有内置支持

要使用内置的远程提供商,请为 provider 配置所选字体提供商的相应值

provider: fontProviders.adobe({ id: process.env.ADOBE_ID })

你也可以为任何 unifont 提供商制作自定义的 Astro 字体提供商

astro.config.mjs
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
experimental: {
fonts: [
{
name: "Roboto",
cssVariable: "--font-roboto"
provider: fontProviders.google(),
// Default included:
// weights: [400] ,
// styles: ["normal", "italics"],
// subsets: ["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"],
// fallbacks: ["sans-serif"],
},
{
name: "Inter",
cssVariable: "--font-inter",
provider: fontProviders.fontsource(),
// Specify weights that are actually used
weights: [400, 500, 600, 700],
// Specify styles that are actually used
styles: ["normal"],
// Download only font files for characters used on the page
subsets: ["cyrillic"],
},
{
name: "JetBrains Mono",
cssVariable: "--font-jetbrains-mono",
provider: fontProviders.fontsource(),
// Download only font files for characters used on the page
subsets: ["latin"],
// Use a fallback font family matching the intended appearance
fallbacks: ["monospace"],
},
{
name: "Poppins",
cssVariable: "--font-poppins",
provider: "local",
// Weight and style are not specified so Astro
// will try to infer them for each variant
variants: [
{
src: [
"./src/assets/fonts/Poppins-regular.woff2",
"./src/assets/fonts/Poppins-regular.woff",
]
},
{
src: [
"./src/assets/fonts/Poppins-bold.woff2",
"./src/assets/fonts/Poppins-bold.woff",
]
},
]
}
],
}
});

此组件输出样式标签,并可选择性地为给定的字体族输出预加载链接。

它必须被导入并添加到你页面的 <head> 中。这通常在像 Head.astro 这样的组件中完成,用于通用网站布局以实现全局使用,但也可以根据需要添加到单个页面。

通过此组件,你可以控制在哪个页面上使用哪个字体族,以及预加载哪些字体。

示例类型: "--font-roboto" | "--font-comic-sans" | ...

在你的 Astro 配置中注册的 cssVariable

src/components/Head.astro
---
import { Font } from 'astro:assets';
---
<Font cssVariable="--font-roboto" />

类型: boolean
默认值: false

是否输出预加载链接

src/components/Head.astro
---
import { Font } from 'astro:assets';
---
<Font cssVariable="--font-roboto" preload />

所有字体的属性都必须在 Astro 配置中进行配置。一些属性对于远程和本地字体是通用的,而其他属性则根据你选择的字体提供商而可用。

以下属性可用于远程和本地字体。providernamecssVariable 是必需的。

astro.config.mjs
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
experimental: {
fonts: [{
provider: fontProviders.google(),
name: "Roboto",
cssVariable: "--font-roboto"
}]
}
});

类型: AstroFontProvider | "local"

字体文件的来源。你可以使用内置提供商,编写自己的自定义提供商,或设置为 "local" 以使用本地字体文件

astro.config.mjs
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
experimental: {
fonts: [{
provider: fontProviders.google(),
name: "Roboto",
cssVariable: "--font-roboto"
}]
}
});

类型: string

字体族名称,由你的字体提供商识别

name: "Roboto"

类型: string

一个你选择的有效的 CSS 变量形式的标识符(ident)(即以 -- 开头)

cssVariable: "--font-roboto"

类型: string[]
默认值: ["sans-serif"]

一个字体数组,用于在所选字体不可用或正在加载时使用。备用字体将按列出的顺序选择。将使用第一个可用的字体

fallbacks: ["CustomFont", "serif"]

要完全禁用备用字体,请配置一个空数组

fallbacks: []

至少指定一个与你的字体预期外观相匹配的通用字体族名称。然后,Astro 将尝试使用字体度量标准生成优化的备用字体。要禁用此优化,请将 optimizedFallbacks 设置为 false。

类型: boolean
默认值: true

是否在生成备用字体时启用 Astro 的默认优化。你可以禁用此默认优化,以完全控制 fallbacks 的生成方式

optimizedFallbacks: false

远程字体还有更多配置选项可用。设置这些选项可以自定义从字体提供商加载的数据,例如仅下载某些字重或样式。

在底层,这些选项由 unifont 处理。某些提供商可能不支持某些属性,并且每个提供商的处理方式可能不同。

类型: (number | string)[]
默认值: [400]

一个字重数组。如果在配置中未指定值,默认只包含字重 400 以防止不必要的下载。你需要包含此属性才能访问任何其他字重

weights: [200, "400", "bold"]

如果关联的字体是可变字体,你可以指定一个字重范围

weights: ["100 900"]

类型: ("normal" | "italic" | "oblique")[]
默认值: ["normal", "italic"]

一个字体样式数组

styles: ["normal", "oblique"]

类型: string[]
默认值: ["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"]

定义要预加载的字体子集列表。

subsets: ["latin"]

类型: "auto" | "block" | "swap" | "fallback" | "optional"
默认值: "swap"

根据字体的下载和就绪时间,定义字体如何显示

display: "block"

类型: string[]
默认值: undefined

根据特定的 unicode 字符范围来确定何时必须下载和使用字体。如果页面上的字符与配置的范围匹配,浏览器将下载该字体,并且所有字符都将在页面上可用。要为一个字体配置预加载的字符子集,请改用 subsets 属性。

这对于本地化很有用,可以避免不必要的字体下载,当你的网站的特定部分使用不同的字母表并且将使用单独的字体显示时。例如,一个同时提供英文和日文版本的网站可以防止浏览器在不包含 unicodeRange 中提供的任何日文字符的英文版页面上下载日文字体。

unicodeRange: ["U+26"]

类型: string
默认值: undefined

一个字体拉伸(font stretch)

stretch: "condensed"

类型: string
默认值: undefined

控制版式字体特性(例如,连字、小型大写字母或花体字)

featureSettings: "'smcp' 2"

类型: string
默认值: undefined

字体变体设置

variationSettings: "'xhgt' 0.7"

类型: LocalFontFamily["variants"]

使用本地字体文件时,variants 属性是必需的。每个变体代表一个 @font-face 声明,并需要一个 weightstylesrc 值。

此外,远程字体的一些其他属性也可以在每个变体中指定。

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
experimental: {
fonts: [{
provider: "local",
name: "Custom",
cssVariable: "--font-custom",
variants: [
{
weight: 400,
style: "normal",
src: ["./src/assets/fonts/custom-400.woff2"]
},
{
weight: 700,
style: "normal",
src: ["./src/assets/fonts/custom-700.woff2"]
}
// ...
]
}]
}
});

类型: number | string
默认值: undefined

一个字重

weight: 200

如果关联的字体是可变字体,你可以指定一个字重范围

weight: "100 900"

当未设置该值时,Astro 默认会尝试根据第一个 source 推断该值。

类型: "normal" | "italic" | "oblique"
默认值: undefined

一个字体样式

style: "normal"

当未设置该值时,Astro 默认会尝试根据第一个 source 推断该值。

类型: (string | URL | { url: string | URL; tech?: string })[]

字体来源。它可以是相对于根目录的路径、一个包导入或一个 URL。如果你通过集成注入本地字体,URL 特别有用

src: ["./src/assets/fonts/MyFont.woff2", "./src/assets/fonts/MyFont.woff"]

你还可以通过提供对象来指定一个技术(tech)

src: [{ url:"./src/assets/fonts/MyFont.woff2", tech: "color-COLRv1" }]

远程字体族的以下选项也适用于本地字体族的变体中

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
experimental: {
fonts: [{
provider: "local",
name: "Custom",
cssVariable: "--font-custom",
variants: [
{
weight: 400,
style: "normal",
src: ["./src/assets/fonts/custom-400.woff2"],
display: "block"
}
]
}]
}
});

如果你不想使用内置提供商之一(例如,你想使用第三方 unifont 提供商或为私有注册表构建某些东西),你可以构建自己的提供商。

一个 Astro 字体提供商由两部分组成:配置对象和实际的实现。

  1. 使用 defineAstroFontProvider() 类型辅助函数,创建一个返回字体提供商配置对象的函数,该对象包含

    • entrypoint:一个 URL、一个相对于根目录的路径或一个包导入。
    • config:一个可选的可序列化对象,传递给 unifont 提供商。
    provider/config.ts
    import { defineAstroFontProvider } from 'astro/config';
    export function myProvider() {
    return defineAstroFontProvider({
    entrypoint: new URL('./implementation.js', import.meta.url)
    });
    };
  2. 创建第二个文件来导出你的 unifont provider 实现

    implementation.ts
    import { defineFontProvider } from "unifont";
    export const provider = defineFontProvider("my-provider", async (options, ctx) => {
    // fetch/define your custom fonts
    // ...
    });
  3. 将你的自定义提供商添加到你的字体配置中。

    astro.config.mjs
    fonts: [{
    provider: fontProviders.myProvider(),
    name: "Custom Font",
    cssVariable: "--font-custom"
    }]

字体 API 的缓存实现旨在开发中实用,在生产中高效。在构建期间,字体文件被复制到 _astro/fonts 输出目录,因此它们可以受益于静态资源的 HTTP 缓存(通常为一年)。

要在开发中清除缓存,请删除 .astro/fonts 目录。要清除构建缓存,请删除 node_modules/.astro/fonts 目录

有关此实验性 API 的完整详细信息并提供反馈,请参阅字体 RFC

贡献 社区 赞助