Next.js: Using <title> in _document.js's <Head> tag should show a warning to use _app.js instead

Created on 13 Jun 2018  路  18Comments  路  Source: vercel/next.js

Bug report

Based on #3527

Describe the bug

Currently, users might add <title> in _document.js which will lead to unexpected results with next/head since _document.js is only rendered on the initial pre-render. _app.js is rendered on the server and client side, and is rendered as a normal React tree, whereas _document.js is rendered as static HTML.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Copy the default _document.js and add <title>:
// _document is only rendered on the server side and not on the client side
// Event handlers like onClick can't be added to this file

// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <html>
        <Head>
          <title>Hello World</title>
        </Head>
        <body className="custom_class">
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

Expected behavior

Above example should show a warning that <title> should only be used in _app.js and other pages. This can be done using err.sh, create a link like: https://err.sh/next.js/no-document-title and create a file in the errors directory: errors/no-document-title.md

good first issue

Most helpful comment

What if I purposely want this behavior? How can I stop it from saying...

Warning: <title> should not be used in _document.js's <Head>. https://err.sh/next.js/no-document-title

All 18 comments

Question on this issue - is including <head><title>xyz</title></head> okay? (note this is the regular head element and not the React element.

Can I also ask what's the thinking behind title being set in _app.js over _document.js? It _seems_ (without background) to be more intuitive that I would set the title in the document.

A title is directly correlated to a page. So it should be set in a page. <Head> from next/document is a wrapper around the real <head> tag, you shouldn't implement it yourself. The reason you should use next/head for this is that next/head managed the title and all other head elements.

Hi @timneutkens, I could take this one

@davscro go ahead 馃憤馃檶

Ok, thanks.
Over the weekend, between soccer matches 鈿斤笍馃嚟馃嚪, I will take care of this task. 馃榾

Hi :)
This is what I came to trying to solve this problem. (I was bored and tried to help 馃槵) However, I don't know how to go further :(

I've added isTitleExists() in Head server/document.js

isTitleExists () {
  if (this.props.children.filter(children => children.type != "title").length > 0) {
    return;
  }
  console.log("Warning: the <title> should be used only in _app.js and other pages. https://err.sh/next.js/url-deprecated")
}

Any hints?

p.s. sorry, @davscro I was bored 馃槂 looking forward for your solution 馃憤

Hi @teleginzhenya, you are on the right direction but children could be an object too so your code will break. Also be careful with equality comparisons, I would suggest you to always use strict comparison 馃槈
@timneutkens I did it, but I think this is not a right way to fix it, IMO it should be one-time check probably during the build time, what do u think?

https://github.com/zeit/next.js/tree/canary/examples/with-styled-components

This example should be fixed?

it use <Head> tag in _document.js

@timneutkens

Yes, feel free to update it @rainstormza.

I'm going to close this issue as it was fixed in #5160.

@timneutkens
How can we inject css-in-js on server side if we can't use<Head>tag in _document.js ?

ref: https://github.com/zeit/next.js#custom-document

You can use the head tag, just not for setting as it leads to unexpected behavior</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/6324199?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="timneutkens picture"> <strong>timneutkens</strong> <span class="text-muted ml-1">on 4 Oct 2018</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">5</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>Using react helmet seems to trigger this warning.</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/11298496?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="zargold picture"> <strong>zargold</strong> <span class="text-muted ml-1">on 4 May 2019</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>What if I purposely want this behavior? How can I stop it from saying...</p> <pre><code class="prettyprint">Warning: <title> should not be used in _document.js's <Head>. https://err.sh/next.js/no-document-title </code></pre> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars1.githubusercontent.com/u/2536442?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="mattdell picture"> <strong>mattdell</strong> <span class="text-muted ml-1">on 16 May 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">4</span> ❤<span class="ml-2 mr-3">2</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>import Head from 'next/head';</p> <p>from your pages e.g. index.js etc.</p> <p><Head> <title> cool title

Hi There, I followed the error message, landing up here, moved my Head element, title and description meta tag to _app and received the following:

TypeError: Cannot read property '_documentProps' of null
    at Head.render (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:665:22)
    at processChild (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3134:18)
    at resolve (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:2960:5)
    at ReactDOMServerRenderer.render (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3435:22)
    at ReactDOMServerRenderer.read (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3373:29)
    at renderToString (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3988:27)
    at render (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/server/render.js:83:16)
    at renderPage (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/server/render.js:406:16)
    at Object.ctx.renderPage (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:1693:28)
    at Function.getInitialProps (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:506:19)
    at Function.module.exports../src/pages/_document.js.MyDocument.getInitialProps (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:1704:85)
    at Object.loadGetInitialProps (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/lib/utils.js:59:29)
    at Object.renderToHTML (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/server/render.js:410:36)

Hi There, I followed the error message, landing up here, moved my Head element, title and description meta tag to _app and received the following:

TypeError: Cannot read property '_documentProps' of null
    at Head.render (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:665:22)
    at processChild (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3134:18)
    at resolve (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:2960:5)
    at ReactDOMServerRenderer.render (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3435:22)
    at ReactDOMServerRenderer.read (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3373:29)
    at renderToString (/Users/paul/repositories/coronasepush-web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3988:27)
    at render (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/server/render.js:83:16)
    at renderPage (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/server/render.js:406:16)
    at Object.ctx.renderPage (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:1693:28)
    at Function.getInitialProps (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:506:19)
    at Function.module.exports../src/pages/_document.js.MyDocument.getInitialProps (/Users/paul/repositories/coronasepush-web/.next/server/static/development/pages/_document.js:1704:85)
    at Object.loadGetInitialProps (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/lib/utils.js:59:29)
    at Object.renderToHTML (/Users/paul/repositories/coronasepush-web/node_modules/next/dist/next-server/server/render.js:410:36)

See https://github.com/vercel/next.js/issues/9647#issuecomment-583844001

import Head from 'next/head';

from your pages e.g. index.js etc.

cool title

so then, if I'm understanding right, the current best practice to insert <Head> tag with <title> tags in every page, rather than jut setting it once in _document.js?

@crevulus Afaik, you can set a "global" title in _app.tsx or in individual pages

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sospedra picture sospedra  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

jesselee34 picture jesselee34  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

formula349 picture formula349  路  3Comments