TASKS-1823 WebManager module
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import type { MetadataRoute } from 'next';
|
||||
import type { SitemapEntry } from '#web-runtime/types';
|
||||
import type { PublicPathResolver } from './page-metadata';
|
||||
|
||||
/**
|
||||
* Turns the backend's page listing into sitemap entries.
|
||||
*
|
||||
* Pages that share a `groupKey` are the same page in different languages, so each entry links
|
||||
* to its siblings through `alternates.languages` — the sitemap equivalent of the `hreflang`
|
||||
* tags on the page itself, and the form Google prefers for multilingual sites.
|
||||
*
|
||||
* Kept free of `next/headers` and routing setup so it can be tested directly: the caller
|
||||
* supplies the path resolver and the absolute origin.
|
||||
*/
|
||||
export function buildSitemap(
|
||||
entries: SitemapEntry[],
|
||||
origin: URL,
|
||||
publicPath: PublicPathResolver
|
||||
): MetadataRoute.Sitemap {
|
||||
const absolute = (locale: string, path: string) => new URL(publicPath(locale, path), origin).href;
|
||||
|
||||
const byGroupKey = new Map<string, SitemapEntry[]>();
|
||||
for (const entry of entries) {
|
||||
if (!entry.groupKey) continue;
|
||||
|
||||
const group = byGroupKey.get(entry.groupKey);
|
||||
if (group) group.push(entry);
|
||||
else byGroupKey.set(entry.groupKey, [entry]);
|
||||
}
|
||||
|
||||
return entries.map((entry) => {
|
||||
const siblings = byGroupKey.get(entry.groupKey) ?? [];
|
||||
const lastModified = entry.updatedAt ?? entry.publishedAt;
|
||||
const item: MetadataRoute.Sitemap[number] = {
|
||||
url: absolute(entry.locale, entry.path)
|
||||
};
|
||||
|
||||
if (lastModified) {
|
||||
item.lastModified = new Date(lastModified);
|
||||
}
|
||||
|
||||
// A single-locale group has nothing to point at but itself; omit the noise.
|
||||
if (siblings.length > 1) {
|
||||
item.alternates = {
|
||||
languages: Object.fromEntries(
|
||||
siblings.map((sibling) => [sibling.locale, absolute(sibling.locale, sibling.path)])
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user