NextJs Script not rendering inside component

991 views Asked by At

I am trying to implement Cookiebot on my NextJs Website. The docs (Link to docs) mention to insert the script for the cookie declaration inside the HTML of the specific page, for me it is an own subpage only for the cookie declaration. If I use the HTML element <script ... /> as mentioned in the docs, the text does not load when I switch to the page, but only after a refresh once I'm on the page. If I use the NextJs Script component Link to docs by switching the <script ..> to and import it from next/script, the cookie declaration loads instantly as expected, but it is placed below everything else of the page, even under the footer (even though i wrap the pages inside a layout with footer). My code for the layout looks like following: `

function BasePage(props: IBasePageProps) {
  return (
    <div>
      <Navbar />
      <main>{props.children}</main>
      <Footer />
    </div>
  );
}

This works for every page and everything - the pages are all between the Navbar and Footer. However if I use following code for the page of the screenshot, the <Script .../> text is loaded below the footer.

export default function CookieRichtlinie() {

  return (
    <>
            <h1 className="pb-8 mt-2 text-3xl font-extrabold leading-8 tracking-tight text-gray-900 sm:text-4xl">
              Cookie Richtlinie
            </h1>
            <div id="CookiePolicyText">
              <Script
                id="CookieDeclaration"
src="https://consent.cookiebot.com/12345/cd.js"
                type="text/javascript"
                async
              />
            </div>
    </>
  );

`

After googling for two days I couldn't find any issue or thread close to this problem. Someone experienced this or know what I could try?

<Script ...> below everything else

Placed <Script ...> tag of next/script anywhere possible to get the loaded text inside the page. Expected to have the result of the script in the placed component, however it is always at the bottom of the page.

2

There are 2 answers

0
Reinis On

Did some global searches in Github and found an useEffect workaround, made some modifications and this worked in my case.

useEffect(() => {
  const cookieBotWrapper = document.getElementById("CookiebotDeclaration")
  if (cookieBotWrapper) {
    const script = document.createElement("script")
    script.id = "CookieDeclaration"
    script.type = "text/javascript"
    script.async = true
    script.src = `https://consent.cookiebot.com/${process.env.NEXT_PUBLIC_COOKIEBOT_DOMAIN_GROUP_ID}/cd.js`

    cookieBotWrapper.appendChild(script)
}
}, [])

return (
  <main>
    {process.env.NODE_ENV !== "development" && (
      <div id="CookiebotDeclaration" />
    )}
  </main>

)

0
dmoz On

You should use the strategy param of the <Script> tag, specifically the "beforeInteractive" value. This would allow you to load the script in the <head> of the page.

Docs: NextJS Script component & Next "beforeInteractive"

One caveat with using strategy="beforeInteractive" is that you can only do so in the custom _document.jsx file(for the /pages router) or root layout.jsx file(for the /app router), making it available for every nested page. But the optimizations that NextJS does with the script would trump any drawbacks IMHO.