Documento personalizado
Un Document
personalizado puede actualizar las etiquetas <html>
y <body>
utilizadas para renderizar una Página.
Para sobrescribir el Document
predeterminado, crea el archivo pages/_document
como se muestra a continuación:
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
Es bueno saber
_document
solo se renderiza en el servidor, por lo que no se pueden usar manejadores de eventos comoonClick
en este archivo.<Html>
,<Head />
,<Main />
y<NextScript />
son necesarios para que la página se renderice correctamente.
Consideraciones
- El componente
<Head />
usado en_document
no es el mismo quenext/head
. El<Head />
usado aquí solo debe utilizarse para código<head>
común a todas las páginas. Para otros casos, como etiquetas<title>
, recomendamos usarnext/head
en tus páginas o componentes. - Los componentes de React fuera de
<Main />
no serán inicializados por el navegador. No añadas lógica de aplicación aquí ni CSS personalizado (comostyled-jsx
). Si necesitas componentes compartidos en todas tus páginas (como un menú o barra de herramientas), consulta Layouts en su lugar. Document
actualmente no soporta los métodos de obtención de datos de Next.js comogetStaticProps
ogetServerSideProps
.
Personalizando renderPage
Personalizar renderPage
es avanzado y solo necesario para bibliotecas como CSS-in-JS que requieren renderizado del lado del servidor (SSR). No es necesario para el soporte integrado de styled-jsx
.
No recomendamos este patrón. En su lugar, considera adoptar gradualmente el App Router, que permite obtener datos más fácilmente para páginas y layouts.
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from 'next/document'
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const originalRenderPage = ctx.renderPage
// Ejecuta la lógica de renderizado de React sincrónicamente
ctx.renderPage = () =>
originalRenderPage({
// Útil para envolver todo el árbol de React
enhanceApp: (App) => App,
// Útil para envolver por página
enhanceComponent: (Component) => Component,
})
// Ejecuta el `getInitialProps` padre, que ahora incluye el `renderPage` personalizado
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
// Ejecuta la lógica de renderizado de React sincrónicamente
ctx.renderPage = () =>
originalRenderPage({
// Útil para envolver todo el árbol de React
enhanceApp: (App) => App,
// Útil para envolver por página
enhanceComponent: (Component) => Component,
})
// Ejecuta el `getInitialProps` padre, que ahora incluye el `renderPage` personalizado
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
Es bueno saber
getInitialProps
en_document
no se llama durante transiciones del lado del cliente.- El objeto
ctx
para_document
es equivalente al recibido engetInitialProps
, con la adición derenderPage
.