Astro Font Provider API
Añadido en:
astro@6.0.0
La Fonts API te permite acceder a fuentes de manera unificada. Cada familia requiere el uso de un Astro Font Provider, que descarga archivos de fuentes desde un servicio remoto o carga archivos de fuentes locales desde disco.
Proveedores integrados
Sección titulada “Proveedores integrados”Astro exporta font providers integrados desde astro/config:
import { fontProviders } from 'astro/config'Para usar un font provider integrado, establece provider con el valor apropiado para tu font provider elegido:
Obtiene fuentes de Adobe:
provider: fontProviders.adobe({ id: "your-id" })Pasa al font provider de Adobe un ID cargado como una variable de entorno en tu archivo de configuración de Astro.
Obtiene fuentes de Bunny:
provider: fontProviders.bunny()Fontshare
Sección titulada “Fontshare”Obtiene fuentes de Fontshare:
provider: fontProviders.fontshare()Fontsource
Sección titulada “Fontsource”Obtiene fuentes de Fontsource:
provider: fontProviders.fontsource()Obtiene fuentes de Google:
provider: fontProviders.google()El provider viene con las siguientes opciones específicas de familia que pueden añadirse en el objeto font.options.
experimental.glyphs
Sección titulada “experimental.glyphs”Type: string[]
Permite especificar una lista de glifos a incluir en la fuente para cada familia de fuentes. Esto puede reducir el tamaño del archivo de fuente:
{ // ... provider: fontProviders.google(), options: { experimental: { glyphs: ["a"] } }}experimental.variableAxis
Sección titulada “experimental.variableAxis”Type: Partial<Record<VariableAxis, ([string, string] | string)[]>>
Permite configurar la variable axis:
{ // ... provider: fontProviders.google(), options: { experimental: { variableAxis: { slnt: [["-15", "0"]], CASL: [["0", "1"]], CRSV: ["1"], MONO: [["0", "1"]], } } }}Google Icons
Sección titulada “Google Icons”Obtiene fuentes de Google Icons:
provider: fontProviders.googleicons()El provider viene con las siguientes opciones específicas de familia que pueden añadirse en el objeto font.options.
experimental.glyphs
Sección titulada “experimental.glyphs”Type: string[]
Al resolver los nuevos iconos de Material Symbols, permite especificar una lista de glifos a incluir en la fuente para cada familia de fuentes. Esto puede reducir el tamaño del archivo de fuente:
{ // ... provider: fontProviders.googleicons(), options: { experimental: { glyphs: ["a"] } }}Obtiene fuentes desde disco:
provider: fontProviders.local()El provider requiere que variants se definan en el objeto font.options.
variants
Sección titulada “variants”Type: LocalFontFamily["variants"]
La propiedad options.variants es obligatoria. Cada variant representa una declaración @font-face y requiere un src.
Adicionalmente, algunas otras propiedades pueden especificarse dentro de cada variant.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ 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"] } // ... ] } }]});Type: number | string
Default: undefined
weight: 200Si la fuente asociada es una fuente variable, puedes especificar un rango de pesos:
weight: "100 900"Cuando el valor no está establecido, por defecto Astro intentará inferir el valor basándose en el primer source.
Type: "normal" | "italic" | "oblique"
Default: undefined
style: "normal"Cuando el valor no está establecido, por defecto Astro intentará inferir el valor basándose en el primer source.
Type: (string | URL | { url: string | URL; tech?: string })[]
Fuentes de fuente. Puede ser una ruta relativa a la raíz, un import de paquete o una URL. Las URLs son particularmente útiles si inyectas fuentes locales a través de una integración:
src: ["./src/assets/fonts/MyFont.woff2", "./src/assets/fonts/MyFont.woff"]src: [new URL("./custom.ttf", import.meta.url)]src: ["my-package/SomeFont.ttf"]Recomendamos no poner tus archivos de fuentes en el directorio public/. Ya que Astro copiará estos archivos a esa carpeta en el build time, esto resultará en archivos duplicados en tu output de build. En su lugar, almacénalos en otro lugar de tu proyecto, como en src/.
También puedes especificar un tech proporcionando objetos:
src: [{ url:"./src/assets/fonts/MyFont.woff2", tech: "color-COLRv1" }]Otras propiedades
Sección titulada “Otras propiedades”Las siguientes opciones de familias de fuentes también están disponibles para familias de fuentes locales dentro de variants:
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [{ provider: fontProviders.local(), name: "Custom", cssVariable: "--font-custom", options: { variants: [ { weight: 400, style: "normal", src: ["./src/assets/fonts/custom-400.woff2"], display: "block" } ] } }]});Obtiene fuentes de paquetes NPM, ya sea de paquetes instalados localmente en node_modules o desde un CDN:
provider: fontProviders.npm()El provider detecta automáticamente fuentes de las dependencias de tu package.json y puede resolver fuentes de paquetes como @fontsource/*, @fontsource-variable/*, y otros paquetes de fuentes conocidos.
Opciones del provider
Sección titulada “Opciones del provider”El provider NPM acepta las siguientes opciones de configuración:
Type: string
Default: 'https://cdn.jsdelivr.net/npm'
CDN a usar para fetchear paquetes npm remotamente:
provider: fontProviders.npm({ cdn: 'https://esm.sh' })Type: boolean
Default: true
Si hacer fallback a fetchear desde el CDN cuando la resolución local falla. Establece en false para resolver solo desde paquetes instalados localmente:
provider: fontProviders.npm({ remote: false })Opciones de familia
Sección titulada “Opciones de familia”El provider viene con las siguientes opciones específicas de familia que pueden añadirse en el objeto font.options.
package
Sección titulada “package”Type: string
Default: Auto-detectado o inferido del nombre de familia
El nombre del paquete NPM. Cuando no se especifica, el provider intentará encontrar la familia de fuentes en patrones conocidos de paquetes de fuentes o inferir basándose en las convenciones de Fontsource:
{ // ... provider: fontProviders.npm(), options: { package: '@fontsource/roboto' }}version
Sección titulada “version”Type: string
Default: 'latest'
La versión del paquete (usado solo para resolución CDN):
{ // ... provider: fontProviders.npm(), options: { version: '5.0.0' }}Type: string
Default: 'index.css'
El archivo CSS entry a parsear del paquete:
{ // ... provider: fontProviders.npm(), options: { file: 'latin.css' }}Construir un font provider
Sección titulada “Construir un font provider”Si no deseas usar uno de los proveedores integrados (ej. quieres usar un unifont provider de terceros o construir algo para un registro privado), puedes construir el tuyo propio.
El método preferido para implementar un font provider personalizado es exportar una función que devuelva el objeto FontProvider y tome la configuración como parámetro.
El objeto font provider
Sección titulada “El objeto font provider”Un FontProvider es un objeto que contiene las propiedades obligatorias name y resolveFont(). También tiene disponibles las propiedades opcionales config, init() y listFonts().
El tipo FontProvider acepta un genérico para las options de familia.
Type: string
Un nombre único para el proveedor, usado en logs y para identificación.
resolveFont()
Sección titulada “resolveFont()”Type: (options: ResolveFontOptions) => Awaitable<{ fonts: FontFaceData[] } | undefined>
Usado para obtener y devolver datos de font face basados en las opciones dadas.
Type: Record<string, any>
Default: undefined
Un objeto serializable, usado para identificación.
Type: (context: FontProviderInitContext) => Awaitable<void>
Default: undefined
Callback opcional, usado para realizar cualquier lógica de inicialización.
context.storage
Sección titulada “context.storage”Type: Storage
Útil para caching.
context.root
Sección titulada “context.root”Type: URL
La raíz del proyecto, útil para resolver rutas de archivos locales.
listFonts()
Sección titulada “listFonts()”Type: () => Awaitable<string[] | undefined>
Default: undefined
Callback opcional, usado para devolver la lista de nombres de fuentes disponibles.
Soportar un registro privado
Sección titulada “Soportar un registro privado”El siguiente ejemplo define un font provider para un registro privado:
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; }, };}Puedes entonces registrar este font provider en la configuración de Astro:
import { defineConfig } from "astro/config";import { registryFontProvider } from "./font-provider";
export default defineConfig({ fonts: [{ provider: registryFontProvider(), name: "Custom", cssVariable: "--font-custom" }]});import { defineConfig } from "astro/config";import { registryFontProvider } from "./font-provider";
export default defineConfig({ fonts: [{ provider: registryFontProvider({ token: "..." }), name: "Custom", cssVariable: "--font-custom" }]});import { defineConfig } from "astro/config";import { registryFontProvider } from "./font-provider";
export default defineConfig({ fonts: [{ provider: registryFontProvider(), options: { minimal: true }, name: "Custom", cssVariable: "--font-custom" }]});Soportar un proveedor unifont de terceros
Sección titulada “Soportar un proveedor unifont de terceros”Puedes definir un font provider de Astro usando un unifont provider por debajo:
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?.(); }, };}Puedes entonces registrar este font provider en la configuración de Astro:
import { defineConfig } from "astro/config";import { acmeFontProvider } from "./font-provider";
export default defineConfig({ fonts: [{ provider: acmeFontProvider(), name: "Custom", cssVariable: "--font-custom" }]});import { defineConfig } from "astro/config";import { acmeFontProvider } from "./font-provider";
export default defineConfig({ fonts: [{ provider: acmeFontProvider({ token: "..." }), name: "Custom", cssVariable: "--font-custom" }]});import { defineConfig } from "astro/config";import { acmeFontProvider } from "./font-provider";
export default defineConfig({ fonts: [{ provider: acmeFontProvider(), options: { minimal: true }, name: "Custom", cssVariable: "--font-custom" }]});