Files
ipal-kit/dist/modules/seo/buildMetadata.js
T

87 lines
2.9 KiB
JavaScript

import { buildLocalizedPath } from '../i18n/index.js';
import { composeTitle } from './composeTitle.js';
import { buildHreflangAlternates } from './hreflang.js';
/**
* Assembles a Next.js-compatible Metadata object from document SEO fields and
* site-level data. Locale-aware: canonical points at the current locale's
* path, and hreflang alternates cover every locale the document exists in.
*
* Designed for use inside Next.js `generateMetadata`. The caller resolves the
* pieces (meta group, site name, image URL, localized slugs) and passes them
* in — the plugin composes, it doesn't fetch.
*/ export function buildMetadata({ baseUrl, config, homeSlug = 'home', imageUrl, locale, meta, order, pageTitle, prefix, query, separator, siteName, slugs }) {
// Title source priority: titleOverride (exact, wins outright) > meta.title
// (SEO title an editor set) > pageTitle (the document's own name). This means
// a page with no SEO title still shows its name (e.g. 'Sprzątanie biur')
// composed with the site name, instead of just the site name or a blank.
const override = meta?.titleOverride?.trim();
const resolvedPageTitle = meta?.title?.trim() || pageTitle?.trim() || undefined;
const title = override || composeTitle({
order,
pageTitle: resolvedPageTitle,
separator,
siteName
});
const description = meta?.description?.trim() || undefined;
const origin = baseUrl?.replace(/\/$/, '') ?? '';
const suffix = query ?? '';
const currentPath = buildLocalizedPath({
config,
homeSlug,
locale,
prefix,
slugs
});
const canonical = currentPath ? `${origin}${currentPath}${suffix}` : undefined;
const languages = buildHreflangAlternates({
baseUrl,
config,
homeSlug,
prefix,
slugs
});
if (suffix) {
for (const code of Object.keys(languages)){
languages[code] = `${languages[code]}${suffix}`;
}
}
const images = imageUrl ? [
{
url: imageUrl
}
] : undefined;
return {
title,
...description && {
description
},
alternates: {
...canonical && {
canonical
},
...Object.keys(languages).length > 0 && {
languages
}
},
openGraph: {
title,
...description && {
description
},
...images && {
images
},
locale
},
// noindex → tell search engines to exclude the page but still follow links
// (authority flows through). For legal/thin/search-result pages.
...meta?.noindex ? {
robots: {
follow: true,
index: false
}
} : {}
};
}
//# sourceMappingURL=buildMetadata.js.map