Next.js
Fonts con next/font
Explica cómo next/font autoaloja fuentes, genera clases y variables CSS, y controla pesos, subsets, preload, fallbacks, alcance y privacidad.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
Next.js
Explica cómo next/font autoaloja fuentes, genera clases y variables CSS, y controla pesos, subsets, preload, fallbacks, alcance y privacidad.
next/font descarga o empaqueta fuentes durante el build, las auto-hospeda y genera clases o variables CSS. Elimina requests del navegador hacia proveedores externos y ayuda a evitar layout shift, pero todavía debes elegir archivos, pesos, subsets y fallbacks con criterio.
Una fuente externa típica crea una cadena:
HTML
→ stylesheet del proveedor
→ font file
→ text rerenderEsto puede añadir DNS/TLS, dependencia externa, privacidad y cambios de métricas tipográficas.
Con next/font:
build downloads/reads font
→ optimized files emitted with app
→ CSS generated
→ browser requests same-origin assetNo necesitas un <link> manual a Google Fonts.
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin"],
display: "swap",
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="es" className={inter.className}>
<body>{children}</body>
</html>
);
}Next.js descarga la fuente durante build. El navegador no llama a Google.
import localFont from "next/font/local";
const brandFont = localFont({
src: [
{
path: "./fonts/Brand-Regular.woff2",
weight: "400",
style: "normal",
},
{
path: "./fonts/Brand-Semibold.woff2",
weight: "600",
style: "normal",
},
],
display: "swap",
variable: "--font-brand",
});Usa formatos web modernos como WOFF2 y revisa licencia. No incluyas pesos que no se usan.
Aplica directamente font-family:
<body className={inter.className}>Expone una custom property:
<html className={`${inter.variable} ${brandFont.variable}`}>:root {
--font-sans-fallback: system-ui, sans-serif;
}
body {
font-family: var(--font-inter), var(--font-sans-fallback);
}
.heading {
font-family: var(--font-brand), serif;
}Variable es conveniente para Tailwind, design tokens y varias familias.
Una variable font puede cubrir un rango de pesos con un archivo:
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
});Ventajas:
Trade-off: el archivo puede ser más grande que uno o dos pesos estáticos si solo necesitas pocos.
subsets: ["latin"]Reduce glyphs y bytes. Debe cubrir contenido real. Si la app muestra cirílico o vietnamita y no incluyes el subset, caerá al fallback.
No habilites todos los subsets por prevención; mide idiomas soportados.
Las fuentes se precargan por defecto en función de dónde se instancia la función.
Si la declaras en root layout, puede precargarse globalmente. Si solo se usa en una ruta, declárala en su layout para reducir alcance.
Demasiadas fuentes preload compiten con LCP image/CSS. Usa preload: false para familias secundarias no críticas.
Muestra fallback inmediatamente y cambia cuando llega la fuente. Buena disponibilidad, posible cambio visual.
El navegador puede conservar fallback en conexiones lentas, reduciendo cambios.
Oculta texto un periodo; normalmente perjudica UX.
Elige según marca, contenido y rendimiento; swap es un punto de partida común.
Next/font puede ajustar métricas del fallback para reducir CLS. También puedes proporcionar fallbacks:
const font = localFont({
src: "./font.woff2",
fallback: ["Arial", "sans-serif"],
adjustFontFallback: true,
});Un fallback visualmente cercano reduce salto antes de cargar. Prueba textos reales, no solo Lighthouse.
root layout font
→ all routes
marketing layout font
→ marketing subtree
component module font
→ component imports and generated assetLas llamadas a funciones de font deben estar en módulo top-level y asignarse a una constante. No se crean dinámicamente según props/request.
// layout
<html className={inter.variable}>En CSS/Tailwind actual puedes mapear:
@theme inline {
--font-sans: var(--font-inter);
}La sintaxis depende de la versión de Tailwind; el concepto es exponer el token CSS.
next/font no entrega automáticamente la fuente a ImageResponse. La generación OG necesita cargar el ArrayBuffer dentro de la función de imagen bajo su contrato.
No asumas que una clase CSS del documento existe en Satori.
Google fonts requiere que el build pueda descargar los archivos. En CI sin internet o detrás de firewall puede fallar.
Opciones:
next/font/local.El output producido ya contiene la fuente, así que runtime no necesita el proveedor.
Auto-hosting evita requests de terceros y simplifica CSP font-src 'self'. Si usas otro CDN o loader, añade el origen exacto.
No uses data URLs grandes para fuentes.
Archivos generados tienen hashes y pueden cachearse de forma inmutable. Una nueva fuente/build produce URL nueva.
No cambies archivos locales manteniendo artefactos antiguos sin reconstruir.
const sans = Inter({
subsets: ["latin"],
variable: "--font-sans",
});
const mono = localFont({
src: "./fonts/JetBrainsMono-Variable.woff2",
variable: "--font-mono",
preload: false,
});
<html className={`${sans.variable} ${mono.variable}`}>Aumenta bytes.
Puede duplicar configuración y ampliar precargas.
Glyphs faltantes/fallback inconsistente.
Descarga duplicada.
Compite con recursos críticos.
Line-height, legibilidad y contraste siguen siendo diseño/CSS.
variable integra design tokens.Scripts y recursos de terceros controla cuándo ejecutar código externo sin bloquear el render ni degradar privacidad.