If your page uses query strings for local-only state, use a canonical URL in your metadata to tell crawlers to ignore the query string.
If the query string defines the content (e.g., a video ID), use createLoader, createSerializer, and urlKeys from nuqs/server to generate a canonical URL that includes the necessary parameters.
import type { Metadata } from 'next'
import {
createParser,
parseAsString,
createLoader,
createSerializer,
type UrlKeys
} from 'nuqs/server'
const youTubeSearchParams = {
videoId: createParser({
parse: (q) => (/^[^"&?\/\s]{11}$/i.test(q) ? q : null),
serialize: (v) => v
})
}
const youTubeUrlKeys: UrlKeys<typeof youTubeSearchParams> = { videoId: 'v' }
const loadYouTubeSearchParams = createLoader(youTubeSearchParams, { urlKeys: youTubeUrlKeys })
const serializeYouTubeSearchParams = createSerializer(youTubeSearchParams, { urlKeys: youTubeUrlKeys })
export async function generateMetadata({ searchParams }) {
const { videoId } = await loadYouTubeSearchParams(searchParams)
return {
alternates: {
canonical: serializeYouTubeSearchParams('/watch', { videoId })
}
}
}