next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Next 13 - error multiples <title> / <meta> on tag <head>

Open john-dufrene-dev opened this issue 2 years ago • 11 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System: Platform: darwin Arch: x64 Version: Darwin Kernel Version 21.6.0: Wed Aug 10 14:25:27 PDT 2022; root:xnu-8020.141.5~2/RELEASE_X86_64 Binaries: Node: 16.13.1 npm: 8.19.2 Yarn: 1.22.19 pnpm: N/A Relevant packages: next: 13.0.0 eslint-config-next: 13.0.0 react: 18.2.0 react-dom: 18.2.0

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

next dev

Describe the Bug

When a create files

head.js :

export default async function Head({ params }) {
  return (
    <>
      <title>Title head</title>
      <meta name="description" content="Generated by head" />
    </>
  );
}

layout.js :

export default async function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <title>Title layout</title>
        <meta name="description" content="Generated by layout" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </head>
      <body>{children}</body>
    </html>
  );
}

Tags < title > and < meta > are not deleted, just add another tags in html structure :

Capture d’écran 2022-10-31 à 23 53 25

I tried with async function and normal functions,

Thank's

Expected Behavior

and <meta> tag replacement <h3>Link to reproduction</h3> <p>https://github.com/john-dufrene-dev/test-nextjs13</p> <h3>To Reproduce</h3> <p>npm run dev with this repository</p>

john-dufrene-dev avatar Oct 31 '22 23:10 john-dufrene-dev

That's interesting, because in #42239 I am not able to change the title at all like this, and I'm not getting any duplicate tags. But our setup looks similar, although I tried with canary.

johnrackles avatar Nov 01 '22 10:11 johnrackles

I have the same issue on 13.0.1-canary.4

if the layout <head> has <title> only then, otherwise #42239

professorhaseeb avatar Nov 01 '22 11:11 professorhaseeb

I have a similar issue, I'm using meta tags inside the body for schema org metadata, but all these metadata are moved to/rendered in the head section, creating multiple titles and other metatags. NextJS 13.0.2

SergeySypalo avatar Nov 05 '22 10:11 SergeySypalo

Just updated the docs - you should only use head special file instead of putting <head> tags in the root layout:

// app/head.js

export default async function Head() {
  return (
    <>
      <title>Title</title>
      <meta name="description" content="Generated by head" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="icon" href="/favicon.ico" />
    </>
  );
}
// app/layout.js

export default async function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

leerob avatar Nov 05 '22 23:11 leerob

Then it might be worth it changing the default template that create next app produces, bc in there the root layout has the title 🙂

johannes-rackles avatar Nov 05 '22 23:11 johannes-rackles

The default template has been fixed in https://github.com/vercel/next.js/pull/42357

balazsorban44 avatar Nov 06 '22 01:11 balazsorban44

Should tags that are commonly used on all pages (eg favicon) also be moved to head.js? I have the following method working fine for now:

// app/layout.js

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </head>
      <body>{children}</body>
    </html>
  );
}
// app/head.js

export default function Head() {
  return (
    <>
      <title>Title</title>
      <meta name="description" content="Generated by head" />
    </>
  );
}
// app/blog/[slug]/head.js

export default function PostHead() {
  return (
    <>
      <title>Post Title</title>
      <meta name="description" content="Generated by post head" />
    </>
  );
}

komzweb avatar Nov 06 '22 09:11 komzweb

komzweb, I'm doing more/less the same now, but previously I simply accessed the post title in layout via children.props.title It was a much more convenient way instead of creating a separate head file for each post. I'm not using API for posts (they are simply stored in js files, because of better SEO optimization possibilities, which are not available when JSON/markdown is in use). Would be nice if someone from dev tell here how to access children's post title from the layout, if possible. As from the docs passing props and vice versa is not possible.

SergeySypalo avatar Nov 06 '22 10:11 SergeySypalo

on "next": "^13.0.3-canary.0", With RootLayout without a

and using head.tsx in the app dir I get Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.

And worst of all, the title doesnt change on page navigation even though each route has a head.tsx with the

being exported as a react fragment

chukwumaokere avatar Nov 07 '22 07:11 chukwumaokere

And worst of all, the title doesnt change on page navigation even though each route has a head.tsx with the

being exported as a react fragment

@chukwumaokere The docs have a workaround for that and it says "to be fixed in the future".

komzweb avatar Nov 07 '22 08:11 komzweb

Updated today to NextJS 13.0.3, but the issue is still present, all my schema.org meta tags are moved from the body to the page head creating a mess of multiple titles and descriptions on the posts list page.

SergeySypalo avatar Nov 11 '22 08:11 SergeySypalo

And worst of all, the title doesnt change on page navigation even though each route has a head.tsx with the

being exported as a react fragment

@chukwumaokere The docs have a workaround for that and it says "to be fixed in the future".

I don't see the workaround for this in the docs. On navigation using the next.js Link, the head stays the same as the route you landed on and doesn't change with navigation.

Any fix for this?

christo9090 avatar Dec 23 '22 16:12 christo9090

Dynamic header title & meta tags on NextJs 13

My solution (without duplicates headers):

I am faced with the problem of changing title and meta tags on the new version of NextJs 13

After a couple of hours, I found an elegant solution...

As it turned out, it is not necessary to use the head file.tsx

Therefore, we can easily create an empty head.tsx in the root of the /app folder:

// app/head.tsx

import React from 'react';

export default function RootHead() {
    return undefined;  // Disable root head
}

And then, in places where it is necessary to prescribe the usual <head/> and <meta/> from the HTML markup:

// app/page.tsx OR app/blog/[slug]/page.tsx

import React from "react";

export default function RootPage() {
    return (
        <div>
            // Set title & description without <Head/> components
            <title>Home</title>
            <meta name="description" content="My homepage"/>
          
            // Set page code
            <p>Other content...</p>
        </div>
    )
}

P.S. You can create a separate component called AppHead.tsx and add it where necessary by specifying parameters, for example:

// app/page.tsx OR app/blog/[slug]/page.tsx

import React from "react";
import AppHead from "./app-head.tsx";

export default function RootPage() {
    return (
        <div>
            // Set title & description with custom <AppHead/> component
            <AppHead title="Home" description="My homepage"/>
          
            // Set page code
            <p>Other content...</p>
        </div>
    )
}

P.P.S. If you are superman, then you can create a HeadProvider.tsx component and not write <AppHead/> in each file.

Example adding head context to your web application:

// app/layout.tsx

import React from "react";

import HeadProvider from "../context/head";
import AppHead from "./AppHead";

export default function RootLayout({children}: { children: React.ReactNode }) {
    return (
        <html lang="en">
        <HeadProvider>  // <-- this wrapper look like: <HeadContext.Provider>{children}</HeadContext.Provider>
            <AppHead/>  // <-- this component set <title/> & <meta/> from HeadContext
            <body>
                {children}  // <-- on any file we will get & change context: React.useContext(HeadContext);
            </body>
        </HeadProvider>
        </html>
    )
}

See gist code: https://gist.github.com/MakStashkevich/23e8059f3b018a3c6e8e811b1a2d59b9

I hope it will be useful. :heart:

MakStashkevich avatar Jan 03 '23 11:01 MakStashkevich

MakStashkevich, now try to add any meta tag inside body, for example

<article itemScope itemType="https://schema.org/BlogPosting">
   <meta itemProp="title" content="My title" />
   <p>Bla-bla-bla</p>
</article>

And check if you have two titles in the head.

SergeySypalo avatar Jan 03 '23 11:01 SergeySypalo

MakStashkevich, now try to add any meta tag inside body, for example

<article itemScope itemType="https://schema.org/BlogPosting">
   <meta itemProp="title" content="My title" />
   <p>Bla-bla-bla</p>
</article>

And check if you have two titles in the head.

Create HeadProvider and use hook on every page without duplicates <meta> tags, example:

const {setTitle} = useHead();
setTitle("bla-bla-bla");

MakStashkevich avatar Jan 20 '23 06:01 MakStashkevich

It doesn't solve the issue, meta tags are removed from the article body, so no rich schema org markup. Just tested on the latest Next JS 13.1.3.

SergeySypalo avatar Jan 20 '23 13:01 SergeySypalo

Updated to 13.1.4 - the same issue, 13.1.5 - still there. Any updates from the developers?

SergeySypalo avatar Jan 24 '23 09:01 SergeySypalo

We're also experiencing this issue on 13.1.5 with pages/ (not app/)

klarstrup avatar Jan 26 '23 21:01 klarstrup

Hi there, is there anyone going to look into this ongoing issue? Still the same in 13.1.6

SergeySypalo avatar Jan 28 '23 08:01 SergeySypalo

Another clue for this happening with /pages too (still in 13.1.6) is that we are using suspense in that universe (via @tanstack/query)

klarstrup avatar Feb 07 '23 13:02 klarstrup

So sad to see the issue is still here after almost 4 months discussion and present in the latest 13.2.1. @ijjk is it something you can help with?

SergeySypalo avatar Feb 24 '23 09:02 SergeySypalo

Found an interesting thing today, then decided to try from newly create NextJS 13.2.1 from scratch and use /app directory npx create-next-app@latest --experimental-app Then copied <div itemscope itemtype="https://schema.org/NewsArticle"> with its contents from https://developers.google.com/search/docs/appearance/structured-data/article And it worked as expected 😀 When I compared what was is the difference between this project and a test one I have, the dealbreaker was itemProp in my test site vs itemprop in Google example, same applies to other item... Schema.org metadata. I remember VSCode previously suggested me to change from all lowercase to 1 uppercase letter, otherwise highlighted a page as containing errors. Going to move my devops blog to a newer version finally 🙂

SergeySypalo avatar Feb 25 '23 08:02 SergeySypalo

Turns out my problem, which I think is in fact separate from this one, was caused in my project by using react@next (18.3.0-next-0f4a83596-20230110 to be precise). Returning to [email protected] has restored sanity to my project.

Repro for my actual bug: npx create-next-app@latest and npm install react@next react-dom@next, now any <meta> tags that were supposed to render within <div id="__next"> will render before it, right into <body>.

klarstrup avatar Mar 03 '23 13:03 klarstrup

Turns out this was the erroneous behavior I was happening upon: https://github.com/facebook/react/pull/26256

klarstrup avatar Mar 05 '23 00:03 klarstrup

Closing this as stale since there is a new Metadata API since this issue was opened.

https://nextjs.org/docs/app/building-your-application/optimizing/metadata

leerob avatar Sep 09 '23 17:09 leerob

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Sep 24 '23 00:09 github-actions[bot]