I'm working on a blog using NextJs13 and Strapi and in some pages/posts, I have a FAQ section.
I'm rendering my page SERVER SIDE
I used this solution on my [slug]/page.tsx
:
const Place = async ({
params,
}: {
params: { slug: string; city: string; lang: string };
}) => {
const id = params.slug.split('-').slice(-1)[0];
if (!Number.isFinite(parseInt(id))) {
notFound();
}
const place = await fetchPlace(id);
const morePlaces = await fetchMorePlaces();
if (
params.slug != `${slugify(place.name)}-${place.id}` ||
params.city != place.city
) {
redirect(
`/${place.city}/${params.lang}/places/${slugify(place.name)}-${place.id}`
);
}
return (
<>
<Script id="faq-schema" strategy="afterInteractive">
{JSON.stringify({
"@context": "http://schema.org",
"@type": "FAQPage",
"mainEntity": place.faq && place.faq.length > 0 && place.faq.map((item) => ({
"@type": "Question",
"name": item.title,
"acceptedAnswer": {
"@type": "Answer",
"text": item.content,
},
}))
})}
</Script>
<Carousel place={place} />
<Layout>
<div className="lg:pt-40 lg:pb-24 md:py-32 sm:py-24 py-8 lg:px-28 md:px-20">
<Header place={place} />
<Content place={place} />
{place.faq && place.faq.length > 0 && <FAQSection faq={place.faq} />}
</div>
<CardsSection places={morePlaces} params={params} />
</Layout>
<StickyDiv />
</>
);
};
But it seems that this solution is not working and doesn't get detected by google, and it somehow triggers an error on the development server saying : Unhandled Runtime Error - SyntaxError: Unexpected token ':'
How can I add the FAQ structured data snippets to my code and make it work correctly and detected by google. Thank you
Instead of passing the structured data for your script tag as children render them directly as raw markup as seen below. Furthermore, there is no need to use the next/script
component for this purpose. A normal script tag will suffice.
const MyComponent = () => {
const schema = {
"@context": "http://schema.org",
"@type": "FAQPage",
mainEntity:
place.faq &&
place.faq.length > 0 &&
place.faq.map((item) => ({
"@type": "Question",
name: item.title,
acceptedAnswer: {
"@type": "Answer",
text: item.content,
},
})),
};
return (
<script
dangerouslySetInnerHTML={{
__html: JSON.stringify(schema),
}}
/>
);
};