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

duplicate meta tags in head

Open macrozone opened this issue 2 years ago • 4 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.4.0: Fri Mar 18 00:45:05 PDT 2022; root:xnu-8020.101.4~15/RELEASE_X86_64 Binaries: Node: 14.20.0 npm: 6.14.17 Yarn: 1.22.18 pnpm: N/A Relevant packages: next: 12.2.2 eslint-config-next: 12.0.10 react: 17.0.2 react-dom: 17.0.2

What browser are you using? (if relevant)

chrome, safari

How are you deploying your application? (if relevant)

No response

Describe the Bug

some meta tags in the head are duplicated.

this can be even seen on the official nextjs page (viewport meta tag):

Bildschirmfoto 2022-07-21 um 18 25 32

interestingly, in chrome this happens on my computer only when in a guest / icognito window.

those duplication are not present on the SSR source, so its a hydration problem

Expected Behavior

no duplicate tags

Link to reproduction

https://nextjs.org/

To Reproduce

open https://nextjs.org/

use inspector, look at the head

macrozone avatar Jul 21 '22 16:07 macrozone

Hi, it looks like this is related to a change in google tag manager where it's injecting a new script to the head breaking the next-head-count order. Can you confirm this is similar to the case you are seeing in your project as well?

ijjk avatar Jul 23 '22 03:07 ijjk

@ijjk Can confirm. For some reason, GTM is inserting it's scripts above next-head-count, causing meta tags duplication when navigating between pages image

snelsi avatar Jul 29 '22 07:07 snelsi

Hi, it looks like this is related to a change in google tag manager where it's injecting a new script to the head breaking the next-head-count order. Can you confirm this is similar to the case you are seeing in your project as well?

Hi, yes, that could be indeed the case, it uses GTM and it injects various stuff in the header, in our case i see a clarity.ms script and analytics:

Bildschirmfoto 2022-07-29 um 09 48 08

macrozone avatar Jul 29 '22 07:07 macrozone

Same issue here using Next.js v10.2.3. Any updates?

velialiev avatar Aug 03 '22 14:08 velialiev

duplicate meta tags when use with preact. https://github.com/garmeeh/next-seo/issues/864

Z2Y avatar Aug 25 '22 13:08 Z2Y

Any fix for this yet?

mikeldoka1 avatar Dec 23 '22 20:12 mikeldoka1

Same issue with Next.js v12

KingMatrix1989 avatar Dec 28 '22 15:12 KingMatrix1989

definitely not a silver bullet: but could we address by keeping a different count for scripts, meta tags, etc. rather than just one next-head-count we could keep one for each? Better yet would be some sort of hash of each specific tag so we know that this one already exists and don't need to create another m:d ().

zargold avatar Jan 04 '23 21:01 zargold

Also seeing this issue in nextjs v12

guzz avatar Feb 20 '23 09:02 guzz

Have you guys tried placing the GTM scripts at the top, immediately after the web page's opening <head> tag?

jheweSE avatar Apr 14 '23 10:04 jheweSE

👋🏻 Also encountering this and curious if there are any good work arounds.

lindseybradford avatar Apr 24 '23 19:04 lindseybradford

👋🏻 Also encountering this and curious if there are any good work arounds.

Yes, switched back to wordpress !

mikeldoka1 avatar Apr 24 '23 20:04 mikeldoka1

Facing the same issue: The is duplicated on every page. The <meta name="viewport" .../> is duplicated after navigating, even if the viewport meta is not set.

[email protected]

victoriaSh avatar May 30 '23 20:05 victoriaSh

Also having this problem - any plans to fix?

finevans avatar Jun 09 '23 08:06 finevans

Hi everyone, please try moving any scripts that appends additional scripts, e.g., GTM, to _document, and at the top of the <Head> stack, so it doesn't mess up the next-head-count order.

jheweSE avatar Jun 09 '23 09:06 jheweSE

Any update on this? Facing the same issue after integrating google tag manager.

ghost avatar Jun 18 '23 06:06 ghost

Any update on this? Facing the same issue

ing-ivan-31 avatar Jun 29 '23 23:06 ing-ivan-31

I'm actually not seeing this on the current NextJS site, so maybe someone from the team could chime in for how this was officially fixed and update the docs?

image

in our case, moving GTM to document resolved.

EDIT: it actually did not. Moving <Scripts /> to Document just meant they didn't load at all which removed the duplicates but obviously we need these scripts to load.

Edit 2: Okay, I have no idea what is going on here but the resulting solution

  1. Do not abstract these scripts to their own components, they need to use the Script component imported in _document
  2. Use strategy beforeInteractive on these scripts
  3. Include these scripts as children of the <Head /> component in _document
  4. Also include the affected meta tags that were previously in _app in _document

1 - they did not show up otherwise no matter what else changed (strategy, child of Head which yes broke NextJS rules but I tried it) 2 - they did not show up otherwise 3 - again, did not show up otherwise 4 - when we had a sitewide meta tag in _app it still got moved around until it was included in document

Our use case included the usual GTM inline script that appends to the document head as well as an external script.

pm0u avatar Jul 11 '23 18:07 pm0u

Still had issues, ended up doing a custom implementation for GTM so that it at least didn't append itself to the head of the document - we do have other scripts bundled so that may still happen somewhere down the line and will require some further testing. For now:


import { gtmId } from "../../../constants"
import Script from "next/script"
import { useEffect } from "react"

export const GTMScript = () => {
  useEffect(() => {
    window.dataLayer = window.dataLayer ?? []
    window.dataLayer.push({
      "gtm.start": new Date().getTime(),
      event: "gtm.js",
    })
  }, [])
  return <Script src={`https://www.googletagmanager.comgtm.js?id=${gtmId}`} />
}

pm0u avatar Jul 17 '23 16:07 pm0u

Thank you @pm0u . If possible please keep us updated if you find anything else.

ghost avatar Jul 17 '23 16:07 ghost

Following up -

We ended up moving these scripts to afterInteractive so they end up in the body rather than the head and this seems to work although I haven't stress tested bundling scripts with GTM

image

https://nextjs.org/docs/pages/api-reference/components/script#afterinteractive

This was primarily spurred after getting this linter error: https://nextjs.org/docs/messages/next-script-for-ga as well as the note in the docs there re: intended uses.

pm0u avatar Jul 21 '23 19:07 pm0u

Following up -

We ended up moving these scripts to afterInteractive so they end up in the body rather than the head and this seems to work although I haven't stress tested bundling scripts with GTM

image https://nextjs.org/docs/pages/api-reference/components/script#afterinteractive

This was primarily spurred after getting this linter error: https://nextjs.org/docs/messages/next-script-for-ga as well as the note in the docs there re: intended uses.

So I am assuming the <Script /> tag is not in _document.js. So did you move it to an _app.js component or someplace else?

hitarthdesai avatar Jul 21 '23 20:07 hitarthdesai

So I am assuming the <Script /> tag is not in _document.js. So did you move it to an _app.js component or someplace else?

Correct, these scripts are now in _app.tsx. Also just for the record we are using the pages router currently on Next 13.4

pm0u avatar Jul 21 '23 20:07 pm0u

@pm0u so I shifted the <Script /> tag in the _app.tsx file, but, duplication in my case still persists. Do you have any idea on why this may not have worked in my case OR any other possible solutions on your mind?

hitarthdesai avatar Jul 24 '23 13:07 hitarthdesai

Any update on this? Facing the same issue. I think the problem it's the GTM script

SamuelePiazzesi avatar Aug 01 '23 09:08 SamuelePiazzesi

I ended up slightly modifying the default gtm loading script to essentially not allow next-head-count to mess things up because of time constraints. However, the issue still persists in next 12.

The default gtm script finds the first <script /> element and loads all gtm scripts before it. Now you can change the first step to be something else like find the first css link tag or anything else that you see fit, and then load the gtm scripts below it. Just make sure it is below the <meta name="next-head-count" /> tag.

Also another thing to note is that you could upgrade to next13 and try the experimental.nextStrictHead flag which throws next-head-count out the window, but I was unable to try it due to constraints on the next version we use at out company.

hitarthdesai avatar Aug 01 '23 16:08 hitarthdesai

@hitarthdesai thank you so much for the update. Actually i have the same problem: my company still use the 12 version of Next. Do you have any implementation example of how did you changed the script?

SamuelePiazzesi avatar Aug 02 '23 15:08 SamuelePiazzesi

I did the following:

var p=d.head.getElementsByTagName("meta").namedItem("next-head-count")
p.parentNode.insertBefore(i, p.nextElementSibling);
p.parentNode.insertBefore(j, i.nextElementSibling);

where j is the script element created in the default gtm script. All I changed was how they created a var f = ... and used the above replacement instead.

hitarthdesai avatar Aug 02 '23 15:08 hitarthdesai