//
Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
function BlogPost({ post }: { post: { title: string; description: string; author: string } }) {
return (
<article>
{/* Estas se elevan a <head> automáticamente */}
<title>{post.title}</title>
<meta name="description" content={post.description} />
<meta name="author" content={post.author} />
<link rel="canonical" href={`https://example.com/blog/${post.title}`} />
<h1>{post.title}</h1>
<p>{post.description}</p>
</article>
);
}Cuándo usarlo: Usa metadatos integrados siempre que un componente necesite establecer el título de la página, descripción u otras etiquetas head. Esto elimina la necesidad de react-helmet o efectos manuales de document.title.
// Una aplicación de varias páginas donde cada ruta establece sus propios metadatos
function ProductPage({ product }: {
product: {
name: string;
description: string;
price: number;
image: string;
category: string;
};
}) {
return (
<main>
{/* Título de la página */}
<title>{product.name} | My Store</title>
{/* Etiquetas meta SEO */}
<meta name="description" content={product.description} />
<meta name="keywords" content={`${product.category}, buy, shop`} />
{/* Etiquetas Open Graph */}
<meta property="og:title" content={product.name} />
<meta property="og:description" content={product.description} />
<meta property="og:image" content={product.image} />
<meta property="og:type" content="product" />
{/* Tarjeta de Twitter */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={product.name} />
<meta name="twitter:image" content={product.image} />
{/* Precarga la imagen del producto */}
<link rel="preload" href={product.image} as="image" />
{/* Hoja de estilos para esta página */}
<link rel="stylesheet" href="/styles/product.css" precedence="default" />
{/* Contenido de la página */}
<div className="max-w-4xl mx-auto p-6">
<img src={product.image} alt={product.name} />
<h1 className="text-3xl font-bold">{product.name}</h1>
<p className="text-xl">${product.price.toFixed(2)}</p>
<p>{product.description}</p>
</div>
</main>
);
}
function SettingsPage() {
return (
<div>
<title>Settings | My Store</title>
<meta name="robots" content="noindex" />
<h1>Account Settings</h1>
{/* ... */}
</div>
);
}
export { ProductPage, SettingsPage };Lo que esto demuestra:
<title> renderizado en línea, automáticamente elevado a <head><link rel="preload"> para optimización del rendimiento<link rel="stylesheet"> con precedence para ordenar CSS<title>, <meta> y <link> cuando se renderizan dentro de un componente y los eleva al <head> del documento automáticamente.<head> HTML inicial. Durante la navegación del lado del cliente, React actualiza el <head> agregando, eliminando o actualizando los elementos elevados.<title> se deduplicanplicamos -- solo gana la última <title> renderizada si varios componentes renderizan una.<meta> se desduplican por el atributo name o property. Dos etiquetas <meta name="description"> de diferentes componentes resultarán en solo la más reciente.<link rel="stylesheet"> soportan un atributo precedence que controla el orden de inserción. Las hojas de estilo con el mismo precedence se agrupan juntas. React también deduplica enlaces de hojas de estilo por href.<link> (preload, icon, canonical, etc.) se elevan pero no se deduplicanplican por defecto.Título dinámico con datos en vivo:
function ChatRoom({ roomName, unreadCount }: { roomName: string; unreadCount: number }) {
const titlePrefix = unreadCount > 0 ? `(${unreadCount}) ` : "";
return (
<div>
<title>{titlePrefix}{roomName} | Chat</title>
<h1>{roomName}</h1>
{/* chat UI */}
</div>
);
}Componentes anidados agregando metadatos:
function Layout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
{/* Metadatos base */}
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
{children}
</body>
</html>
);
}
function AboutPage() {
return (
<Layout>
{/* Los metadatos específicos de la página se fusionan con los metadatos del layout */}
<title>About Us</title>
<meta name="description" content="Learn about our company" />
<h1>About Us</h1>
</Layout>
);
}Orden de precedencia de hojas de estilo:
function App() {
return (
<>
{/* precedencia "default" carga primero */}
<link rel="stylesheet" href="/base.css" precedence="default" />
{/* precedencia "high" carga después de "default" */}
<link rel="stylesheet" href="/theme.css" precedence="high" />
</>
);
}
function Widget() {
return (
<>
{/* Misma precedencia se agrupa con otras hojas de estilo "default" */}
<link rel="stylesheet" href="/widget.css" precedence="default" />
<div>Widget content</div>
</>
);
}<title>, <meta> y <link> usan sus tipos de atributos HTML estándar de React.JSX.IntrinsicElements.precedence en <link> es una extensión específica de React tipada como string | undefined.<title> -- Solo se aplica la última <title> renderizada. Si dos componentes hermanos renderizan ambos <title>, el resultado depende del orden de renderizado. Solución: Establece <title> en solo un componente por ruta, típicamente el componente a nivel de página.metadata y generateMetadata. Usar ambas eso y etiquetas <title> en línea puede causar duplicados. Solución: Elige un enfoque por proyecto. Para aplicaciones Next.js, prefiere el API metadata del framework.<head> en HTML SSR -- React eleva las etiquetas durante el renderizado, pero si inspeccionas la respuesta HTML sin procesar, aparecen en <head>. Si ocurren desincronizaciones de hidratación, comprueba las diferencias servidor/cliente. Solución: Asegúrate de que los valores de metadatos sean deterministas (sin Date.now() o Math.random()).<link rel="stylesheet"> sin precedence -- Si omites precedence, el enlace de la hoja de estilo se trata como un enlace regular y no se deduplica ni ordena por React. Solución: Siempre agrega precedence a los enlaces de hojas de estilo para la ordenación administrada por React.<script> -- React 19 no eleva las etiquetas <script> al <head>. Solución: Usa preinit de react-dom para scripts, o coloca etiquetas script en tu plantilla HTML.| Enfoque | Cuándo elegir |
|---|---|
| Metadatos integrados (React 19) | Opción predeterminada para nuevos proyectos React 19 |
Exportación metadata de Next.js | Proyectos Next.js App Router con metadatos estáticos o dinámicos |
react-helmet / react-helmet-async | Proyectos React 18 o anteriores |
document.title manual en useEffect | Cambios de título rápidos solo del cliente |
<head> HTML en plantilla | Metadatos estáticos que nunca cambian |
<head> del documento automáticamente<head> agregando, eliminando o actualizando elementos elevados<title> renderizada -- React las deduplica<title>, el resultado depende del orden de renderizado<title> en solo un componente por ruta, típicamente el componente a nivel de página<meta> se desduplican por el atributo name o property<meta name="description"> de diferentes componentes resultan en solo la más reciente<link> (preload, icon, canonical) se elevan pero no se deduplicanplicanplicanplican por defectoprecedence controla el orden de inserción de hojas de estilo en el <head>precedence se agrupan juntashref y suspende el renderizado hasta que la hoja de estilo cargafunction Page({ title, description, image }) {
return (
<>
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
{/* page content */}
</>
);
}function ChatRoom({ roomName, unreadCount }) {
const prefix = unreadCount > 0 ? `(${unreadCount}) ` : "";
return (
<>
<title>{prefix}{roomName} | Chat</title>
{/* chat UI */}
</>
);
}El título se actualiza reactivamente mientras unreadCount cambia.
<meta charSet>, <link rel="icon">) y las páginas secundarias agregan etiquetas específicas de página<title> específica de página anula la del layout si ambas renderizan una<meta> por name/property asegura sin duplicadosmetadata y generateMetadata que puede entrar en conflicto con etiquetas en línea<head>metadata del framework<script> al <head>preinit de react-dom para scripts, o coloca etiquetas script en tu plantilla HTML<title>, <meta> y <link>precedence, la hoja de estilo se trata como un enlace regular y no se deduplica ni ordena por Reactprecedence a los enlaces de hoja de estilo que deseas que React administreprecedence en <link> es una extensión específica de React tipada como string | undefined<title>, <meta> y <link> usan sus tipos de atributos HTML estándar de React.JSX.IntrinsicElementsDate.now(), Math.random() u otros valores no deterministaspreload y preinitRevisado por Chris St. John·Última actualización: 19 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥