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
/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...
Jump to solution
2 Replies
Trekiros
Trekiros6mo ago
Example of the result I get:
No description
Solution
Trekiros
Trekiros6mo ago
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]
...
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]
...