Theo's Typesafe CultTTC
Theo's Typesafe Cult3y ago
4 replies
Trekiros

Setting the open graph title on a dynamic route within the nextjs pages router

Hi!
I'm trying to implement the open graph protocol for my website, but I'm having an issue with dynamic routes because the first render doesn't have access to query params yet.

Note: I am using the pages router, and
next-seo
for the meta tags.

Here is an example:
/rules/[id].tsx

import { useRouter } from "next/router";
import { Rule, RuleType } from "@/components/rules";

const Rules: {[ruleId: string]: RuleType} = ...

const RulePage = ({}) => {
    const router = useRouter()
    const id = String(router.query.id)
    const rule = Rules[id]

    return (
        <>
            <NextSeo 
                title={rule?.name || "Article not found"}
                openGraph={{ title: rule?.name || "Article not found" }} />
            <Rule rule={rule} />
        </>
    )
}

export default RulePage


During the first render, the router isn't initialized, so
router.query.id
is undefined, and as a result,
rule
is undefined.

So when I link a page like
/rule/1234
on Discord/Twitter/Facebook etc, even if a rule with an id of
1234
exists, the preview says
Article not found...


How can I make sure the first render is correct?
Solution
Managed to fix it
Somehow this is the first time in 2 years with nextjs I've ever needed to use getStaticProps/getStaticPaths 😐

export const getStaticProps: GetStaticProps<{id: string}> = async (context) => {
    const id = context.params?.id as string
    return { props: { id } }
}

export const getStaticPaths: GetStaticPaths<{id: string}> = async () => {
    return {
        paths: Object.keys(Rules).map(id => ({ params: { id } })),
        fallback: true,
    }
}

const RulePage = ({ id }) => {
    const rule = Rules[id]
    ...
Was this page helpful?