Next.js
App Router, Next.js 16. Funciona con Turbopack (por defecto) y con next build --webpack.
npm install pennantsHoja de estilos
Importa una sola vez, en el layout raíz, la hoja de cada forma que uses:
import 'pennants/css'; // className="pn pn-ar"
import 'pennants/css/circle'; // className="pn-circle pn-ar"pennants/css/rect y pennants/css/square funcionan igual, con las clases base pn-rect y pn-square.
Next.js emite los 271 SVG como archivos en /_next/static/media/. Cada imagen se descarga solo cuando se usa.
Server Components: PennantSvg
Importa el arte de la bandera de forma estática y muéstrala con PennantSvg en cualquier forma. El SVG va directo al HTML, y esto no añade JavaScript en el cliente. pennants/react se puede importar sin problemas desde Server Components.
import Image from 'next/image';
import { PennantSvg } from 'pennants/react';
import ar from 'pennants/art/1x1/ar'; // pennant, square, circle
import ar4x3 from 'pennants/art/4x3/ar'; // rect
import jpUrl from 'pennants/svg/circle/jp.svg';
export default function Page() {
return (
<main>
<PennantSvg art={ar} size={48} locale="es" />
<PennantSvg art={ar4x3} shape="rect" size={48} locale="es" />
<PennantSvg art={ar} shape="square" size={48} locale="es" />
<PennantSvg art={ar} shape="circle" size={48} locale="es" />
<span className="pn pn-de pn-2x" role="img" aria-label="Alemania" />
<Image src={jpUrl} alt="Japón" height={48} width={48} />
</main>
);
}next/image sirve los SVG importados tal cual (sin optimizarlos). Son vectoriales, así que se ven nítidos a cualquier tamaño.
Client Components: Pennant
Usa <Pennant> cuando el código o la forma se conocen recién en tiempo de ejecución. Necesita 'use client'.
'use client';
import { useState } from 'react';
import { Pennant } from 'pennants/react';
import { SHAPES, type PennantCode, type PennantShape } from 'pennants';
export function FlagPicker() {
const [code, setCode] = useState<PennantCode>('br');
const [shape, setShape] = useState<PennantShape>('circle');
return (
<p>
<Pennant code={code} shape={shape} size={48} locale="es" />
<button type="button" onClick={() => setCode('mx')}>
México
</button>
{SHAPES.map((choice) => (
<button key={choice} type="button" onClick={() => setShape(choice)}>
{choice}
</button>
))}
</p>
);
}Detalles de SSR
- Durante el SSR,
<Pennant>renderiza una caja vacía del tamaño correcto (conrole="img"yaria-label). El SVG llega tras la hidratación, desde un chunk diferido. Para banderas conocidas al compilar, usaPennantSvgcon un import estático del arte. <Pennant mode="img" />renderiza un<img>en el servidor.mode="fetch"pide el SVG por red en lugar de empaquetar chunks. Los dos apuntan a jsDelivr por defecto; pasabasepara servir los archivos tú.- En Client Components,
<Pennant>suma 4,7 kB con gzip, más unos pocos KB por cada bandera que se muestra.PennantSvgcon un módulo de arte suma3,7 kB con gzip si se usa en el cliente.