From f8dfe026ec9a3daf9359e361291780d06154b085 Mon Sep 17 00:00:00 2001 From: Luc Date: Fri, 28 Sep 2018 00:24:12 +0200 Subject: [PATCH] Show warning if there is a title in _document.js's Head (#5160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * show warning if there is a title in _document.js Head * dont loop through children in production * only 1 loop through this.props.children 💪 * also raise warning in test env * check for null childs --- errors/no-document-title.md | 43 +++++++++++++++++++++++++++++++++++++ server/document.js | 13 ++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 errors/no-document-title.md diff --git a/errors/no-document-title.md b/errors/no-document-title.md new file mode 100644 index 00000000..1e539cf8 --- /dev/null +++ b/errors/no-document-title.md @@ -0,0 +1,43 @@ +# `` should not be used in _document.js's `<Head>` + +#### Why This Error Occurred + +Adding `<title>` in `pages/_document.js` will lead to unexpected results with `next/head` since `_document.js` is only rendered on the initial pre-render. + +#### Possible Ways to Fix It + +Set `<title>` in `pages/_app.js` instead : + +```js +// pages/_app.js +import App, {Container} from 'next/app' +import Head from 'next/head' +import React from 'react' + +export default class MyApp extends App { + static async getInitialProps ({ Component, router, ctx }) { + let pageProps = {} + + if (Component.getInitialProps) { + pageProps = await Component.getInitialProps(ctx) + } + + return {pageProps} + } + + render () { + const {Component, pageProps} = this.props + return <Container> + <Head> + <title>My new cool app + + + + } +} +``` + + +### Useful Links + +- [The issue this was reported in: #4596](https://github.com/zeit/next.js/issues/4596) diff --git a/server/document.js b/server/document.js index 812da7d1..d3c41817 100644 --- a/server/document.js +++ b/server/document.js @@ -104,6 +104,17 @@ export class Head extends Component { const { page, pathname, buildId } = __NEXT_DATA__ const pagePathname = getPagePathname(pathname) + let children = this.props.children + // show a warning if Head contains (only in development) + if (process.env.NODE_ENV !== 'production') { + children = React.Children.map(children, (child) => { + if (child && child.type === 'title') { + console.warn("Warning: <title> should not be used in _document.js's <Head>. https://err.sh/next.js/no-document-title") + } + return child + }) + } + return <head {...this.props}> {(head || []).map((h, i) => React.cloneElement(h, { key: h.key || i }))} {page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} />} @@ -113,7 +124,7 @@ export class Head extends Component { {this.getPreloadMainLinks()} {this.getCssLinks()} {styles || null} - {this.props.children} + {children} </head> } }