SEO e i18n
title/meta/Open Graph/JSON-LD por página, y traducciones con t().
seo{}
export const seo = {
title: `${data.name} | Mi Tienda`,
description: data.description,
canonical: `/products/${params.slug}`,
openGraph: { title: data.name, image: data.image },
twitter: { card: "summary_large_image" }
};title/description/canonical/Open Graph/Twitter card por página. Cada campo es un string, una plantilla, o t("...") — nunca una función. Un campo que no se resuelve se omite, nunca se rellena a medias.
schema{} — JSON-LD real
export const schema = {
type: "Product",
name: data.name,
offers: { type: "Offer", price: data.price, priceCurrency: "USD" }
};Se resuelve a un <script type="application/ld+json"> real. type/@type es intercambiable; un @type explícito nunca se sobreescribe.
sitemap.xml y robots.txt automáticos
NEXA_SITE_URL=https://misitio.com nexa build
# dist/sitemap.xml y dist/robots.txt con URLs absolutas
# Sin NEXA_SITE_URL: URLs relativas + un avisonexa build genera ambos para todas las rutas estáticas compiladas. nexa-seo avisa (NEXA-SEO-001..) si falta title/description/canonical, o si una imagen no tiene alt — nunca bloquea el build.
i18n básico: t() y [locale]
// src/locales/es.json
{ "home": { "title": "Bienvenido" } }
<h1>{t("home.title")}</h1>src/locales/<locale>.json es un diccionario plano. t("home.title") se resuelve contra el diccionario del locale actual — sin fallback a otro idioma: una clave ausente se omite (en seo) o queda inerte en el cuerpo.
Interpolación en t()
// src/locales/es.json
{ "profile": { "donateTo": "Apoyar a {name}" } }
<p>{t("profile.donateTo", { name: data.creatorName })}</p>t("clave", { variable: data.x }) sustituye el placeholder correspondiente dentro del texto del diccionario. nexa build/nexa lint fallan con un error claro si una clave y sus argumentos no se corresponden.
hreflang automático
<!-- generado solo, en <head>, para cada locale disponible -->
<link rel="alternate" hreflang="es" href="/es/products/iphone-17">
<link rel="alternate" hreflang="en" href="/en/products/iphone-17"><link rel="alternate" hreflang="..."> se genera solo si la ruta vive bajo [locale] y hay más de un src/locales/*.json — sin escribirlo a mano.