Componente Head

El componente <Head> gestiona las etiquetas de <head> desde JSX. No renderiza nada en el body; en el cliente actualiza document.head directamente. Para cadenas HTML programáticas (Open Graph, helpers JSON-LD), consulta SEO y meta. Para títulos de ruta en el build SSR por defecto, usa export const metadataSSR y SSG.

Uso básico

import { Head } from '@emberkit/core';

function MyPage() {
  return (
    <>
      <Head>
        <title>My Page - EmberKit</title>
        <meta name="description" content="A page built with EmberKit" />
      </Head>
      <h1>Hello World</h1>
    </>
  );
}

Durante SSR, esto produce:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My Page - EmberKit</title>
  <meta name="description" content="A page built with EmberKit">
</head>
<body>
  <h1>Hello World</h1>
</body>
</html>

Props abreviadas

Para etiquetas comunes, usa props en lugar de JSX crudo:

<Head
  title="My Page"
  description="Page description"
  keywords={['emberkit', 'framework', 'typescript']}
  author="EmberKit Team"
  robots="index, follow"
  canonical="https://example.com/my-page"
/>

Props soportadas

Referencia de props abreviadas

PropTipoSalida HTML
titlestring<title> + <meta name="title">
descriptionstring<meta name="description">
keywordsstring[]<meta name="keywords"> (separadas por comas)
authorstring<meta name="author">
robotsstring<meta name="robots">
canonicalstring<link rel="canonical">

Open Graph

<Head
  og={{
    type: 'article',
    title: 'My Page',
    description: 'Page description for social sharing',
    url: 'https://example.com/my-page',
    image: 'https://example.com/og-image.png',
    locale: 'en_US',
    siteName: 'My Site',
  }}
/>

Twitter Cards

<Head
  twitter={{
    card: 'summary_large_image',
    site: '@emberkit',
    creator: '@author',
    title: 'My Page',
    description: 'Page description',
    image: 'https://example.com/twitter-image.png',
  }}
/>

Combinar children y props

Puedes mezclar props abreviadas con children JSX crudos:

<Head title="My Page" description="Description">
  <meta property="og:image" content="https://example.com/og.png" />
  <link rel="icon" href="/favicon.ico" />
</Head>

Cuando se proporcionan children, tienen prioridad — las props abreviadas se ignoran.

Varios componentes <Head>

Usa varios componentes <Head> en tu árbol de componentes. Todas las etiquetas se recopilan y fusionan en <head>:

// El layout aporta meta por defecto
function Layout({ children }) {
  return (
    <>
      <Head>
        <meta name="theme-color" content="#0b0f19" />
        <meta property="og:site_name" content="My Site" />
      </Head>
      {children}
    </>
  );
}

// La página aporta meta específica
function AboutPage() {
  return (
    <>
      <Head>
        <title>About Us - My Site</title>
        <meta name="description" content="Learn about our team" />
      </Head>
      <h1>About Us</h1>
    </>
  );
}

Datos estructurados (JSON-LD)

Usa children para scripts de datos estructurados:

import { Head, generateArticleSchema } from '@emberkit/core';

function ArticlePage() {
  const schema = generateArticleSchema({
    title: 'My Article',
    description: 'Article description',
    author: 'John Doe',
    publishedAt: '2025-01-15',
    url: 'https://example.com/article',
  });

  return (
    <>
      <Head>
        <title>My Article</title>
        <script type="application/ld+json">{schema}</script>
      </Head>
      <article>
        <h1>My Article</h1>
      </article>
    </>
  );
}

Cómo funciona

SSR

Durante el renderizado en servidor, <Head>:

  1. Renderiza sus children a una cadena HTML
  2. Registra el HTML en un registro interno de contenido head
  3. Devuelve null (nada en el body de la página)

Durante SSR, las etiquetas registradas están disponibles vía drainHeadContent() desde @emberkit/core. La entrada del servidor CLI integrada inyecta exports metadata de rutas; usa un src/entry-server.tsx personalizado si necesitas fusionar drainHeadContent() en tu plantilla HTML.

Durante la navegación SPA, <Head>:

  1. Renderiza sus children a una cadena HTML
  2. Parsea el HTML y actualiza document.head directamente
  3. Las etiquetas se marcan con data-ek-head para que los re-renders reemplacen (no dupliquen) las etiquetas gestionadas

Referencia API

interface HeadProps {
  children?: JSXNode | JSXNode[];
  title?: string;
  description?: string;
  og?: {
    title?: string;
    description?: string;
    type?: string;
    url?: string;
    image?: string;
    locale?: string;
    siteName?: string;
  };
  twitter?: {
    card?: string;
    site?: string;
    creator?: string;
    title?: string;
    description?: string;
    image?: string;
  };
  canonical?: string;
  robots?: string;
  keywords?: string[];
  author?: string;
}

Próximos pasos

  • SEO y meta — Generación programática de meta con generateMeta()
  • SSR — Pipeline de renderizado en servidor
  • Componentes — Patrones de componentes