The Document
component in app/pages/_document.tsx
can be used to
augment your application's <html>
and <body>
tags. This is necessary
because Blitz pages skip the definition of the surrounding document's
markup.
The default _document.tsx
file looks like this:
import {
Document,
Html,
DocumentHead,
Main,
BlitzScript /*DocumentContext*/,
} from "blitz"
class MyDocument extends Document {
// Only uncomment if you need to customize this behaviour
// static async getInitialProps(ctx: DocumentContext) {
// const initialProps = await Document.getInitialProps(ctx)
// return {...initialProps}
// }
render() {
return (
<Html lang="en">
<DocumentHead />
<body>
<Main />
<BlitzScript />
</body>
</Html>
)
}
}
export default MyDocument
<Html>
, <DocumentHead />
, <Main />
and <BlitzScript />
are
required for the page to be properly rendered.
Custom attributes are allowed as props, like lang
:
<Html lang="en">
The ctx
parameter is an object containing the following keys:
pathname
- Current route. That is the path of the page in /pagesreq
:
The HTTP IncomingMessage object.res
:
The HTTP response object.err
- Error object if any error is encountered during the renderingrenderPage
: Function
- a callback that runs the actual React
rendering logic (synchronously). It's useful to decorate this function
in order to support server-rendering wrappers for things like
styled-componentsDocument
is only rendered in the server, event handlers like onClick
won't work<Main />
will not be initialized by the
browser. Do not add application logic here. If you need shared
components in all your pages (like a menu or a toolbar), take a look at
the App
component insteadDocument
's getInitialProps
function is not called during client-side
transitions, nor when a page is
statically optimizedctx.req
/ ctx.res
are defined in
getInitialProps
. Those variables will be undefined
when a page is
being statically exported by
Automatic Static Optimization<title>
in the <Head />
tag . These
should be avoided in app/pages/_document.js
as they lead to unexpected
behaviorrenderPage
It should be noted that the only reason you should be customizing
renderPage
is for usage with css-in-js libraries that need to wrap the application to properly work with server-side rendering.
It takes as argument an options object for further customization:
import { Document } from "blitz"
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
ctx.renderPage = () =>
originalRenderPage({
// useful for wrapping the whole react tree
enhanceApp: (App) => App,
// useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
}
export default MyDocument