Layouts compartidos
Un src/layout.tsx opcional envuelve el HTML de toda página — header, footer, nav — sin reabrir la composición de componentes.
El elemento data-nexa-slot
// src/layout.tsx
export default function Layout() {
return (
<div>
<header>Mi sitio</header>
<div data-nexa-slot></div>
<footer>© 2026</footer>
</div>
);
}Debe estar vacío, y debe haber exactamente uno en todo el layout — ahí se inserta, tal cual, el HTML que ya renderizó cada página.
Por qué no es composición
// Rust renderiza el layout, encuentra el ÚNICO data-nexa-slot
// (debe estar vacío), e inserta ahí el HTML que ya renderizó
// la página — un splice de texto, no una llamada de función.El layout se compila igual que cualquier página. Ni el layout ni la página se conocen entre sí antes del splice final.
export const head: lo único que sí llega al <head> real
// src/layout.tsx
export const head = {
icon: "/static/logo.svg",
appleTouchIcon: "/static/icon-180.png",
stylesheets: ["/static/site.css"]
};
export default function Layout() { /* ... */ }Todo lo demás que devuelve el layout termina dentro de <body> (vía el splice de arriba) — un <link rel="icon"> puesto ahí queda atrapado en <body>, donde no todos los navegadores lo detectan de forma confiable (este mismo sitio tuvo exactamente ese bug). export const head = { icon, appleTouchIcon, stylesheets } se resuelve aparte y se mezcla en el <head> de verdad del documento — mismo patrón que seo/schema, un objeto literal, nunca código ejecutado.