Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
timneutkens opened this issue Jun 13, 2018 · 22 comments
Labels
good first issue Easy to fix issues, good for newcomers

Comments

@timneutkens
Copy link
Member

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

@remy
Copy link
Contributor

remy commented Jun 13, 2018

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.

@timneutkens
Copy link
Member Author

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.

@davscro
Copy link
Contributor

davscro commented Jun 15, 2018

Hi @timneutkens, I could take this one

@timneutkens
Copy link
Member Author

@davscro go ahead 👍🙌

@davscro
Copy link
Contributor

davscro commented Jun 15, 2018

Ok, thanks.
Over the weekend, between soccer matches ⚽️🇭🇷, I will take care of this task. 😀

@teleginzhenya
Copy link
Contributor

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 👍

@davscro
Copy link
Contributor

davscro commented Jun 19, 2018

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?

@rainstormza
Copy link
Contributor

rainstormza commented Oct 2, 2018

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

@timneutkens
Copy link
Member Author

Yes, feel free to update it @rainstormza.

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

@rainstormza
Copy link
Contributor

rainstormza commented Oct 4, 2018

@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

@timneutkens
Copy link
Member Author

You can use the head tag, just not for setting <title> as it leads to unexpected behavior

@zargold
Copy link

zargold commented May 4, 2019

Using react helmet seems to trigger this warning.

@mattdell
Copy link

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

@itpreneur
Copy link

import Head from 'next/head';

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

<title> cool title </title>

@Pushplaybang
Copy link

Pushplaybang commented Apr 5, 2020

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)

@rjerue
Copy link

rjerue commented Jun 16, 2020

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 #9647 (comment)

@crevulus
Copy link

import Head from 'next/head';

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

<title> cool title </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?

@filipesmedeiros
Copy link

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

zackads added a commit to mcagov/beacons-webapp that referenced this issue Jan 29, 2021
@Oosasukel
Copy link

You should import Head from 'next/head' instead 'next/document' to put the title

@phiberber
Copy link

Hey, I'm having some problems related to this issue. When creating a _document file, it prompts the following message:

warn - Your custom Document (pages/_document) did not render all the required subcomponent. Missing component: <Head /> Read how to fix here: https://nextjs.org/docs/messages/missing-document-component

For some reason, it prompts another warning saying.

Missing required 'title' element

And obviously, I can't set the title in the _document. Is someone having the same problem? Didn't think it was enough to create a new issue.

@nazywamsiepawel
Copy link

Hey did anyone manage to solve this with Next 12? Using 12.0.6 currently.

I have a _document.js but not specifying title/head in there. Using next/head in my pages and all of the tags land in the body not in head. It's a pretty bad result for SEO.

@balazsorban44
Copy link
Member

If you have issues, I suggest opening a new bug report with a reproduction. 🙏

@vercel vercel locked as resolved and limited conversation to collaborators Dec 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Easy to fix issues, good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.