next.js
next.js copied to clipboard
Next 13 - error multiples <title> / <meta> on tag <head>
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 :
I tried with async function and normal functions,
Thank's
Expected Behavior
Link to reproduction
https://github.com/john-dufrene-dev/test-nextjs13
To Reproduce
npm run dev with this repository
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.
I have the same issue on 13.0.1-canary.4
if the layout <head> has <title> only then, otherwise #42239
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
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>
);
}
Then it might be worth it changing the default template that create next app produces, bc in there the root layout has the title 🙂
The default template has been fixed in https://github.com/vercel/next.js/pull/42357
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, 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.
on "next": "^13.0.3-canary.0",
With RootLayout without a
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
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".
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.
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?
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, 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.
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");
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.
Updated to 13.1.4 - the same issue, 13.1.5 - still there. Any updates from the developers?
We're also experiencing this issue on 13.1.5 with pages/ (not app/)
Hi there, is there anyone going to look into this ongoing issue? Still the same in 13.1.6
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)
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?
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 🙂
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>.
Turns out this was the erroneous behavior I was happening upon: https://github.com/facebook/react/pull/26256
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
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.