I'm using app router from next.js. I'd like to add jsonLd datas for both pages, "/blog" and "/blog/[searchKeyword]". but I met some problems about this process.
blog > layout.tsx
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
id="jsonLd-blog"
/>
{children}
</> );
blog/[searchKeyword] > layout.tsx
return ( <>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
id={jsonLd-${params.searchKeyword}}
/>
{children}
</> );
"use client";
import { useEffect } from "react";
const RemoveJsonScript: React.FC<{ elementId: string }> = ({ elementId }) => {
useEffect(() => {
const oldJsonLds = document.getElementById(elementId);
if (oldJsonLds) {
oldJsonLds.remove();
}
}, []);
return <></>;
};
export default RemoveJsonScript;
3. Third, however, it triggered an error below, regardless of whether it is used in server component or client component..
Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
4. In addition, it does not work in <Head> tag from "next/head", but only in <head> tag. This issue is not related to above three issues, but I wonder why it does.
I cannot know how to solve this problem. Next.js is the greatest framework for SEO I've used, but this error make me frustrated.. I need your help.
I want get rid of the parent's jsonLd script tag, without any error message like 'Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.'
This behavior is expected as layout.tsx
will wrap all it's children layouts or pages. So if you have /blog/layout.tsx
and /blog/[searchKeyword]/layout.tsx
, the component tree for /blog/[searchKeyword]/page.tsx
will look like this:
<BlogLayout>
<BlogSearchKeywordLayout>
<BlogSearchKeywordPage />
</BlogSearchKeywordLayout>
</BlogLayout>
The best solution for you is to place your json-ld script tags in the /blog/page.tsx
and /blog/[searchKeyword]/page.tsx