Experimental fonts API
このコンテンツはまだ日本語訳がありません。
Type: FontFamily[]
astro@5.7.0
This experimental feature allows you to use fonts from your filesystem and various font providers (eg. Google, Fontsource, Bunny) through a unified, fully customizable, and type-safe API.
Web fonts can impact page performance at both load time and rendering time. This API helps you keep your site performant with automatic web font optimizations including preload links, optimized fallbacks, and opinionated defaults. See common usage examples.
The Fonts API focuses on performance and privacy by downloading and caching fonts so they’re served from your site. This can avoid sending user data to third-party sites, and also ensures that a consistent set of fonts is available to all your visitors.
To enable this feature, configure an experimental.fonts object with at least one font:
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.google(), name: "Roboto", cssVariable: "--font-roboto" }] }});Then, add the <Font /> component and site-wide styling in your <head>:
---import { Font } from "astro:assets";---
<Font cssVariable="--font-roboto" preload />
<style>body { font-family: var(--font-roboto);}</style>-
experimental.fontsaccepts an array of font objects. For each font, you must specify aprovider, the familyname, and define acssVariableto refer to your font.provider: You can choose from the list of built-in providers or build your own custom font provider.name: Choose a font family supported by your provider.cssVariable: Must be a valid ident in the form of a CSS variable.
The following example configures the “Roboto” family from Google Fonts:
astro.config.mjs import { defineConfig, fontProviders } from "astro/config";export default defineConfig({experimental: {fonts: [{provider: fontProviders.google(),name: "Roboto",cssVariable: "--font-roboto"}]}});More configuration options, such as defining fallback font families and which
weights,styles,subsetsandformatsto download, are available and some will depend on your chosen provider.See the full configuration reference to learn more.
-
Apply styles using the
<Font />component. It must be imported and added to your page<head>. Providing the font’scssVariableis required, and you can optionally output preload links:src/components/Head.astro ---import { Font } from "astro:assets";---<Font cssVariable="--font-roboto" preload />This is commonly done in a component such as
Head.astrothat is used in a common site layout.See the full<Font>component reference for more information.Since the
<Font />component generates CSS with font declarations, you can reference the font family using thecssVariable:<style>body {font-family: var(--font-roboto);}</style>src/styles/global.css @import "tailwindcss";@theme inline {--font-sans: var(--font-roboto);}tailwind.config.mjs /** @type {import("tailwindcss").Config} */export default {content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],theme: {extend: {},fontFamily: {sans: ["var(--font-roboto)"]}},plugins: []};
Available font providers
Section titled “Available font providers”Fonts are loaded using a provider, which either downloads font files from a remote service or loads local font files from disk. Astro exports built-in providers for common services. You can also make a custom Astro font provider.
To use a built-in font provider, import fontProviders and configure provider with the appropriate value for your chosen font provider:
import { fontProviders } from "astro/config";Retrieves fonts from Adobe:
provider: fontProviders.adobe({ id: "your-id" })Pass the Adobe font provider an ID loaded as an environment variable in your Astro config file.
Retrieves fonts from Bunny:
provider: fontProviders.bunny()Fontshare
Section titled “Fontshare”Retrieves fonts from Fontshare:
provider: fontProviders.fontshare()Fontsource
Section titled “Fontsource”Retrieves fonts from Fontsource:
provider: fontProviders.fontsource()Retrieves fonts from Google:
provider: fontProviders.google()The provider comes with family specific options.
experimental.glyphs
Section titled “experimental.glyphs”Type: string[]
Allows specifying a list of glyphs to be included in the font for each font family. This can reduce the size of the font file:
{ // ... provider: fontProviders.google(), options: { experimental: { glyphs: ["a"] } }}experimental.variableAxis
Section titled “experimental.variableAxis”Type: Partial<Record<VariableAxis, ([string, string] | string)[]>>
Allows setting variable axis configuration:
{ // ... provider: fontProviders.google(), options: { experimental: { variableAxis: { slnt: [["-15", "0"]], CASL: [["0", "1"]], CRSV: ["1"], MONO: [["0", "1"]], } } }}Google Icons
Section titled “Google Icons”
追加:
astro@5.16.9
New
Retrieves fonts from Google Icons:
provider: fontProviders.googleicons()The provider comes with family specific options.
experimental.glyphs
Section titled “experimental.glyphs”Type: string[]
when resolving the new Material Symbols icons, allows specifying a list of glyphs to be included in the font for each font family. This can reduce the size of the font file:
{ // ... provider: fontProviders.googleicons(), options: { experimental: { glyphs: ["a"] } }}
追加:
astro@5.16.13
New
Retrieves fonts from disk:
provider: fontProviders.local()The provider comes with required family specific options.
variants
Section titled “variants”Type: LocalFontFamily["variants"]
The options.variants property is required. Each variant represents a @font-face declaration and requires a src.
Additionally, some other properties may be specified within each variant.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.local(), name: "Custom", cssVariable: "--font-custom", options: { variants: [ { weight: 400, style: "normal", src: ["./src/assets/fonts/custom-400.woff2"] }, { weight: 700, style: "normal", src: ["./src/assets/fonts/custom-700.woff2"] } // ... ] } }] }});weight
Section titled “weight”Type: number | string
Default: undefined
A font weight:
weight: 200If the associated font is a variable font, you can specify a range of weights:
weight: "100 900"When the value is not set, by default Astro will try to infer the value based on the first source.
Type: "normal" | "italic" | "oblique"
Default: undefined
A font style:
style: "normal"When the value is not set, by default Astro will try to infer the value based on the first source.
Type: (string | URL | { url: string | URL; tech?: string })[]
Font sources. It can be a path relative to the root, a package import or a URL. URLs are particularly useful if you inject local fonts through an integration:
src: ["./src/assets/fonts/MyFont.woff2", "./src/assets/fonts/MyFont.woff"]src: [new URL("./custom.ttf", import.meta.url)]src: ["my-package/SomeFont.ttf"]We recommend not putting your font files in the public/ directory. Since Astro will copy these files into that folder at build time, this will result in duplicated files in your build output. Instead, store them somewhere else in your project, such as in src/.
You can also specify a tech by providing objects:
src: [{ url:"./src/assets/fonts/MyFont.woff2", tech: "color-COLRv1" }]Other properties
Section titled “Other properties”The following options from font families are also available for local font families within variants:
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.local(), name: "Custom", cssVariable: "--font-custom", options: { variants: [ { weight: 400, style: "normal", src: ["./src/assets/fonts/custom-400.woff2"], display: "block" } ] } }] }});Usage examples
Section titled “Usage examples”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: ["latin"], // fallbacks: ["sans-serif"], // formats: ["woff2"], }, { 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: ["latin", "cyrillic"], // Download more font formats formats: ["woff2", "woff"], }, { name: "JetBrains Mono", cssVariable: "--font-jetbrains-mono", provider: fontProviders.fontsource(), // Download only font files for characters used on the page subsets: ["latin", "latin-ext"], // Use a fallback font family matching the intended appearance fallbacks: ["monospace"], }, { name: "Poppins", cssVariable: "--font-poppins", provider: fontProviders.local(), options: { // 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", ] }, ] } } ], }});<Font /> component reference
Section titled “<Font /> component reference”This component outputs style tags and can optionally output preload links for a given font family.
It must be imported and added to your page <head>. This is commonly done in a component such as Head.astro that is used in a common site layout for global use but may be added to individual pages as needed.
With this component, you have control over which font family is used on which page, and which fonts are preloaded.
cssVariable
Section titled “cssVariable”Example type: "--font-roboto" | "--font-comic-sans" | ...
The cssVariable registered in your Astro configuration:
---import { Font } from "astro:assets";---
<Font cssVariable="--font-roboto" />preload
Section titled “preload”Type: boolean | { weight?: string | number; style?: string; subset?: string }[]
Default: false
Whether to output preload links or not:
---import { Font } from "astro:assets";---
<Font cssVariable="--font-roboto" preload />With the preload directive, the browser will immediately begin downloading all possible font links during page load.
Granular preloads
Section titled “Granular preloads”
追加:
astro@5.15.0
You may not always want to preload every font link, as this can block loading other important resources or may download fonts that are not needed for the current page.
To selectively control which font files are preloaded, you can provide an array of objects describing any combination of font weight, style, or subset to preload.
The following example will only preload font files with a 400 weight or a normal style in the latin subset:
---import { Font } from "astro:assets";---
<Font cssVariable="--font-roboto" preload={[ { subset: "latin", style: "normal" }, { weight: "400" }, ]}/>Variable weight font files will be preloaded if any weight within its range is requested. For example, a font file for font weight 100 900 will be included when 400 is specified in a preload object.
Accessing font data programmatically
Section titled “Accessing font data programmatically”The fontData object allows you to retrieve lower-level font family data programmatically, for example, in an API Route or to generate your own meta tags.
The getFontBuffer() function can then be used on retrieved URLs to get font buffers, for example, in an API Route to generate OpenGraph images using satori, combined with proper formats configuration:
import type{ APIRoute } from "astro"import { fontData, getFontBuffer } from "astro:assets"import satori from "satori"
export const GET: APIRoute = (context) => { const data = fontData["--font-roboto"]
const svg = await satori( <div style={{ color: "black" }}>hello, world</div>, { width: 600, height: 400, fonts: [ { name: "Roboto", data: await getFontBuffer(data[0].src[0].url), weight: 400, style: "normal", }, ], }, )
// ...}fontData
Section titled “fontData”Type: Record<CssVariable, Array<FontData>>
astro@5.16.12
New
An object where each key is a cssVariable and the value is an array describing the associated fonts. Each font is an object containing an array of src available for that font and the following optional properties: weight and style.
getFontBuffer()
Section titled “getFontBuffer()”Type: (url: string) => Promise<Buffer>
astro@5.16.13
New
Returns a buffer for the font file from a source URL obtained from fontData.
getFontBuffer() is only available on the server. Calling the function on the client will throw an error.
Font configuration reference
Section titled “Font configuration reference”All properties of your fonts must be configured in the Astro config. Set these to customize the data loaded from your font provider, for example, to only download certain font weights or styles. For more control, more granular configuration is available.
Each provider is responsible for handling these options, so availability and support for the following properties may vary.
provider, name, and cssVariable are required.
provider
Section titled “provider”Type: FontProvider
The source of your font files. You can use a built-in provider or write your own custom provider:
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ experimental: { fonts: [{ provider: fontProviders.google(), name: "Roboto", cssVariable: "--font-roboto" }] }});Type: string
The font family name, as identified by your font provider:
name: "Roboto"cssVariable
Section titled “cssVariable”Type: string
A valid ident of your choosing in the form of a CSS variable (i.e. starting with --):
cssVariable: "--font-roboto"fallbacks
Section titled “fallbacks”Type: string[]
Default: ["sans-serif"]
An array of fonts to use when your chosen font is unavailable, or loading. Fallback fonts will be chosen in the order listed. The first available font will be used:
fallbacks: ["CustomFont", "serif"]To disable fallback fonts completely, configure an empty array:
fallbacks: []Specify at least a generic family name matching the intended appearance of your font. Astro will then attempt to generate optimized fallbacks using font metrics. To disable this optimization, set optimizedFallbacks to false.
optimizedFallbacks
Section titled “optimizedFallbacks”Type: boolean
Default: true
Whether or not to enable Astro’s default optimization when generating fallback fonts. You may disable this default optimization to have full control over how fallbacks are generated:
optimizedFallbacks: falseweights
Section titled “weights”Type: (number | string)[]
Default: [400]
An array of font weights. If no value is specified in your configuration, only weight 400 is included by default to prevent unnecessary downloads. You will need to include this property to access any other font weights:
weights: [200, "400", "bold"]If the associated font is a variable font, you can specify a range of weights:
weights: ["100 900"]styles
Section titled “styles”Type: ("normal" | "italic" | "oblique")[]
Default: ["normal", "italic"]
An array of font styles:
styles: ["normal", "oblique"]subsets
Section titled “subsets”Type: string[]
Default: ["latin"]
Defines a list of font subsets to preload.
subsets: ["latin"]formats
Section titled “formats”Type: ("woff2" | "woff" | "otf" | "ttf" | "eot")[]
Default: ["woff2"]
astro@5.16.7
New
An array of font formats:
formats: ["woff2", "woff"]options
Section titled “options”Type: Record<string, any>
astro@5.16.12
New
An object to pass provider specific options. It is typed automatically based on the font family provider:
options: { experimental: { glyphs: ["a"] }}display
Section titled “display”Type: "auto" | "block" | "swap" | "fallback" | "optional"
Default: "swap"
Defines how a font displays based on when it is downloaded and ready for use:
display: "block"unicodeRange
Section titled “unicodeRange”Type: string[]
Default: undefined
Determines when a font must be downloaded and used based on a specific range of unicode characters. If a character on the page matches the configured range, the browser will download the font and all characters will be available for use on the page. To configure a subset of characters preloaded for a single font, see the subsets property instead.
This can be useful for localization to avoid unnecessary font downloads when a specific part of your website uses a different alphabet and will be displayed with a separate font. For example, a website that offers both English and Japanese versions can prevent the browser from downloading the Japanese font on English versions of the page that do not contain any of the Japanese characters provided in unicodeRange.
unicodeRange: ["U+26"]stretch
Section titled “stretch”Type: string
Default: undefined
A font stretch:
stretch: "condensed"featureSettings
Section titled “featureSettings”Type: string
Default: undefined
Controls the typographic font features (e.g. ligatures, small caps, or swashes):
featureSettings: "'smcp' 2"variationSettings
Section titled “variationSettings”Type: string
Default: undefined
Font variation settings:
variationSettings: "'xhgt' 0.7"Granular font configuration
Section titled “Granular font configuration”
追加:
astro@5.15.6
A font family is defined by a combination of properties such as weights and styles (e.g. weights: [500, 600] and styles: ["normal", "bold"]), but you may want to download only certain combinations of these.
For greater control over which font files are downloaded, you can specify the same font (ie. with the same cssVariable, name, and provider properties) multiple times with different combinations. Astro will merge the results and download only the required files. For example, it is possible to download normal 500 and 600 while downloading only italic 500:
import { defineConfig, fontProviders } from "astro/config"
export default defineConfig({ experimental: { fonts: [ { name: "Roboto", cssVariable: "--roboto", provider: fontProviders.google(), weights: [500, 600], styles: ["normal"] }, { name: "Roboto", cssVariable: "--roboto", provider: fontProviders.google(), weights: [500], styles: ["italic"] } ] }})Build your own font provider
Section titled “Build your own font provider”If you do not wish to use one of the built-in providers (e.g. you want to use a 3rd-party unifont provider or build something for a private registry), you can build your own.
The preferred method for implementing a custom font provider is to export a function that returns the FontProvider object and takes the configuration as a parameter.
The font provider object
Section titled “The font provider object”The experimental Fonts API allows you to access fonts in a unified way. Each family requires the use of an Astro Font Provider to retrieve font faces.
A FontProvider is an object containing required name and resolveFont() properties. It also has optional config, init() and listFonts() properties available.
The FontProvider type accepts a generic for family options.
Type: string
A unique name for the provider, used in logs and for identification.
resolveFont()
Section titled “resolveFont()”Type: (options: ResolveFontOptions) => Awaitable<{ fonts: FontFaceData[] } | undefined>
Used to retrieve and return font face data based on the given options.
config
Section titled “config”Type: Record<string, any>
Default: undefined
A serializable object, used for identification.
init()
Section titled “init()”Type: (context: FontProviderInitContext) => Awaitable<void>
Default: undefined
Optional callback, used to perform any initialization logic.
context.storage
Section titled “context.storage”Type: Storage
Useful for caching
context.root
Section titled “context.root”Type: URL
The project root, useful for resolving local files paths.
listFonts()
Section titled “listFonts()”Type: () => Awaitable<string[] | undefined>
Default: undefined
Optional callback, used to return the list of available font names.
Supporting a private registry
Section titled “Supporting a private registry”The following example defines a font provider for a private registry:
import type { FontProvider } from "astro";import { retrieveFonts, type Fonts } from "./utils.js",
export function registryFontProvider(): FontProvider { let data: Fonts = {}
return { name: "registry", init: async () => { data = await retrieveFonts(token); }, listFonts: () => { return Object.keys(data); }, resolveFont: ({ familyName, ...rest }) => { const fonts = data[familyName]; if (fonts) { return { fonts }; } return undefined; }, };}import type { FontProvider } from "astro";import { retrieveFonts, type Fonts } from "./utils.js",
interface Config { token: string;}
export function registryFontProvider(config: Config): FontProvider { let data: Fonts = {}
return { name: "registry", config, init: async () => { data = await retrieveFonts(token); }, listFonts: () => { return Object.keys(data); }, resolveFont: ({ familyName, ...rest }) => { const fonts = data[familyName]; if (fonts) { return { fonts }; } return undefined; }, };}import type { FontProvider } from "astro";import { retrieveFonts, type Fonts } from "./utils.js",
interface FamilyOptions { minimal?: boolean;}
export function registryFontProvider(): FontProvider<FamilyOptions | undefined> { let data: Fonts = {}
return { name: "registry", init: async () => { data = await retrieveFonts(token); }, listFonts: () => { return Object.keys(data); }, // options is typed as FamilyOptions | undefined resolveFont: ({ familyName, options, ...rest }) => { const fonts = data[familyName]; if (fonts) { return { fonts }; } return undefined; }, };}You can then register this font provider in the Astro config:
import { defineConfig } from "astro/config";import { registryFontProvider } from "./font-provider";
export default defineConfig({ experimental: { fonts: [{ provider: registryFontProvider(), name: "Custom", cssVariable: "--font-custom" }] }});import { defineConfig } from "astro/config";import { registryFontProvider } from "./font-provider";
export default defineConfig({ experimental: { fonts: [{ provider: registryFontProvider({ token: "..." }), name: "Custom", cssVariable: "--font-custom" }] }});import { defineConfig } from "astro/config";import { registryFontProvider } from "./font-provider";
export default defineConfig({ experimental: { fonts: [{ provider: registryFontProvider(), options: { minimal: true }, name: "Custom", cssVariable: "--font-custom" }] }});Supporting a 3rd-party unifont provider
Section titled “Supporting a 3rd-party unifont provider”You can define an Astro font provider using a unifont provider under the hood:
import type { FontProvider } from "astro";import type { InitializedProvider } from "unifont";import { acmeProvider } from "@acme/unifont-provider"
export function acmeFontProvider(): FontProvider { const provider = acmeProvider(); let initializedProvider: InitializedProvider | undefined; return { name: provider._name, async init(context) { initializedProvider = await provider(context); }, async resolveFont({ familyName, ...rest }) { return await initializedProvider?.resolveFont(familyName, rest); }, async listFonts() { return await initializedProvider?.listFonts?.(); }, };}import type { FontProvider } from "astro";import type { InitializedProvider } from "unifont";import { acmeProvider, type AcmeOptions } from "@acme/unifont-provider"
export function acmeFontProvider(config?: AcmeOptions): FontProvider { const provider = acmeProvider(config); let initializedProvider: InitializedProvider | undefined; return { name: provider._name, config, async init(context) { initializedProvider = await provider(context); }, async resolveFont({ familyName, ...rest }) { return await initializedProvider?.resolveFont(familyName, rest); }, async listFonts() { return await initializedProvider?.listFonts?.(); }, };}import type { FontProvider } from "astro";import type { InitializedProvider } from "unifont";import { acmeProvider, type AcmeFamilyOptions } from "@acme/unifont-provider"
export function acmeFontProvider(): FontProvider<AcmeFamilyOptions | undefined> { const provider = acmeProvider(); let initializedProvider: InitializedProvider<AcmeFamilyOptions> | undefined; return { name: provider._name, async init(context) { initializedProvider = await provider(context); }, async resolveFont({ familyName, ...rest }) { return await initializedProvider?.resolveFont(familyName, rest); }, async listFonts() { return await initializedProvider?.listFonts?.(); }, };}You can then register this font provider in the Astro config:
import { defineConfig } from "astro/config";import { acmeFontProvider } from "./font-provider";
export default defineConfig({ experimental: { fonts: [{ provider: acmeFontProvider(), name: "Custom", cssVariable: "--font-custom" }] }});import { defineConfig } from "astro/config";import { acmeFontProvider } from "./font-provider";
export default defineConfig({ experimental: { fonts: [{ provider: acmeFontProvider({ token: "..." }), name: "Custom", cssVariable: "--font-custom" }] }});import { defineConfig } from "astro/config";import { acmeFontProvider } from "./font-provider";
export default defineConfig({ experimental: { fonts: [{ provider: acmeFontProvider(), options: { minimal: true }, name: "Custom", cssVariable: "--font-custom" }] }});Caching
Section titled “Caching”The Fonts API caching implementation was designed to be practical in development and efficient in production. During builds, font files are copied to the _astro/fonts output directory, so they can benefit from HTTP caching of static assets (usually a year).
To clear the cache in development, remove the .astro/fonts directory. To clear the build cache, remove the node_modules/.astro/fonts directory
Further reading
Section titled “Further reading”For full details and to give feedback on this experimental API, see the Fonts RFC.
Reference