fix(landing): fix 404ing OG images for every model and integration page (#5636)

Google Search Console flagged every /models/{provider}/{model}/opengraph-image
and /integrations/{slug}/opengraph-image URL as 404 (~230 pages total: 5
sample model pages plus ~130 more models, plus every integration).

Root cause: the sibling page.tsx for each of these routes sets
`dynamicParams = false`, a segment-level restriction that also blocks
the metadata route (opengraph-image.tsx) from rendering any param
combination it wasn't statically told about - but Next does not share
generateStaticParams between a page and its sibling metadata routes.
Since none of the three opengraph-image.tsx files exported their own
generateStaticParams, every param was "unknown" to that restriction and
404d, for every single model and integration.

Added a matching generateStaticParams to all three files, mirroring
each route's own page.tsx.

Note: the exact URLs in the audit report (bare /opengraph-image, no
suffix) aren't the real ones - Next serves these at a build-generated
hash suffix (e.g. /opengraph-image-15dal5?<hash>), which is what's
actually embedded in each page's <meta property="og:image"> tag. The
underlying bug the report surfaced is real regardless; verified by
requesting the actual hash-suffixed URL each page embeds (previously
404, now 200) for both a model and an integration page, on a real
production build.
This commit is contained in:
Waleed
2026-07-13 11:21:59 -07:00
committed by GitHub
parent f9cc73f534
commit 4b3c688fec
3 changed files with 40 additions and 0 deletions
@@ -19,6 +19,17 @@ const AUTH_LABEL: Record<AuthType, string> = {
none: 'No auth required',
}
/**
* The sibling page.tsx sets `dynamicParams = false`, a segment-level
* restriction that also blocks this metadata route from rendering any
* param combination it wasn't statically generated for - but Next does not
* share generateStaticParams between a page and its sibling metadata
* routes, so without this export every integration's OG image 404s.
*/
export async function generateStaticParams() {
return integrations.map((integration) => ({ slug: integration.slug }))
}
export default async function Image({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params
const integration = bySlug.get(slug)
@@ -1,5 +1,6 @@
import { notFound } from 'next/navigation'
import {
ALL_CATALOG_MODELS,
formatPrice,
formatTokenCount,
getModelBySlug,
@@ -13,6 +14,20 @@ export const size = {
height: 630,
}
/**
* The sibling page.tsx sets `dynamicParams = false`, a segment-level
* restriction that also blocks this metadata route from rendering any
* param combination it wasn't statically generated for - but Next does not
* share generateStaticParams between a page and its sibling metadata
* routes, so without this export every model's OG image 404s.
*/
export async function generateStaticParams() {
return ALL_CATALOG_MODELS.map((model) => ({
provider: model.providerSlug,
model: model.slug,
}))
}
export default async function Image({
params,
}: {
@@ -5,6 +5,7 @@ import {
getCheapestProviderModel,
getLargestContextProviderModel,
getProviderBySlug,
MODEL_PROVIDERS_WITH_CATALOGS,
} from '@/app/(landing)/models/utils'
import { createLandingOgImage } from '@/app/(landing)/og-utils'
@@ -14,6 +15,19 @@ export const size = {
height: 630,
}
/**
* The sibling page.tsx sets `dynamicParams = false`, a segment-level
* restriction that also blocks this metadata route from rendering any
* param combination it wasn't statically generated for - but Next does not
* share generateStaticParams between a page and its sibling metadata
* routes, so without this export every provider's OG image 404s.
*/
export async function generateStaticParams() {
return MODEL_PROVIDERS_WITH_CATALOGS.map((provider) => ({
provider: provider.slug,
}))
}
export default async function Image({ params }: { params: Promise<{ provider: string }> }) {
const { provider: providerSlug } = await params
const provider = getProviderBySlug(providerSlug)