import { resolveRoute } from '../content/index.js'; import { buildMetadata } from './buildMetadata.js'; import { readSiteMetaConfig } from './readSiteMetaConfig.js'; import { slugsAcrossLocales } from './slugsAcrossLocales.js'; /** plugin-seo stores the OG image as an upload relationship. */ function resolveOgImage(doc) { const image = doc.meta?.image; if (image && typeof image === 'object' && 'url' in image) { return image.url ?? null; } return null; } /** * Metadata for the page route, with every resolver already wired. * * `createMetadataGenerator` asks the client for resolvers because it can't know * their collections. But for the plugin's own conventions it does know: pages * live in one collection, the site name sits on SiteSettings, the OG image sits * on the plugin-seo `meta` group, the home page is whatever System Pages points * at, and — with `content` — entries live under their collection's archive page. * Re-declaring all that in every project is copy-paste, so this resolves it. * * Reach for `createMetadataGenerator` instead when a route doesn't follow those * conventions — custom image logic, a different global, hand-rolled paths. * * The plugin never calls getPayload, and Next calls generateMetadata without a * payload, so the client keeps a small wrapper: * * ```ts * const pageMetadata = createPageMetadata({ config: i18nConfig, baseUrl, content }) * * export async function generateMetadata({ params }) { * const { locale, slug } = await params * return pageMetadata({ payload: await getPayload({ config }), locale, slug }) * } * ``` */ export function createPageMetadata(args) { const { baseUrl, collection = 'pages', config, content, settingsSlug = 'site-settings', siteNameField = 'siteName' } = args; return async function pageMetadata({ slug, locale, page, payload }) { const site = await readSiteMetaConfig({ locale, payload, settingsSlug, siteNameField }); const base = { baseUrl, config, homeSlug: site.homeSlug, locale, order: site.order, separator: site.separator, siteName: site.siteName }; const route = await resolveRoute({ content, locale, page, pagesSlug: collection, payload, segments: slug, settingsSlug }); // Unknown route (the page component will 404) — still return something // coherent rather than throwing during metadata generation. if (!route) { return buildMetadata({ ...base, meta: null, slugs: {} }); } const doc = route.doc; // An entry sits under its archive, so its URLs need that segment — and the // segment differs per locale, since it's the archive page's own slug. const prefix = route.type === 'entry' ? await slugsAcrossLocales({ id: route.archive.id, collection, config, payload }) : undefined; const slugs = await slugsAcrossLocales({ id: doc.id, collection: route.type === 'entry' ? route.collection : collection, config, payload }); // Page 2 of a listing is its own URL, not a variant of page 1. const query = route.type === 'archive' && route.page > 1 ? `?page=${route.page}` : undefined; return buildMetadata({ ...base, imageUrl: resolveOgImage(doc), meta: doc.meta, prefix, query, slugs }); }; } //# sourceMappingURL=createPageMetadata.js.map //# sourceMappingURL=createPageMetadata.js.map