fix: no more duplicates for already fully supported languages (#58)

Co-authored-by: hugo <hugoms@me.com>
This commit is contained in:
Georg Bauer
2026-03-22 16:52:53 +01:00
committed by GitHub
parent 6564ea5b63
commit 72ff998537
3 changed files with 84 additions and 8 deletions

View File

@@ -628,6 +628,16 @@ export class BlogGenerationEngine {
.map((lang) => lang.trim().toLowerCase())
.filter((lang) => lang.length > 0 && lang !== mainLanguage);
// When a language has a dedicated subtree (e.g. /fr/), suppress its .lang
// translation variant pages (e.g. /2025/01/15/post.fr/) to avoid duplicate
// content. The subtree already contains the translated version at a clean URL.
if (additionalLanguages.length > 0) {
const subtreeLanguages = new Set(additionalLanguages);
publishedRoutePosts = publishedRoutePosts.filter(
(p) => !(p as any).translationSourceSlug || !subtreeLanguages.has((p.language ?? '').trim().toLowerCase()),
);
}
// Determine whether to use worker threads for page generation
const useWorkers = !!options.dbPath;
@@ -1409,9 +1419,23 @@ export class BlogGenerationEngine {
.map(([category]) => category);
const { publishedPosts, publishedListPosts } = await loadPublishedGenerationSets(this.postEngine, listExcludedCategories);
const { routePosts: publishedRoutePosts } = await this.buildPublishedRoutePosts(publishedPosts);
let { routePosts: publishedRoutePosts } = await this.buildPublishedRoutePosts(publishedPosts);
const generationPostIndex = buildGenerationPostIndex(publishedListPosts);
// --- Build per-language expected paths ---
const mainLanguage = (options.language ?? 'en').trim().toLowerCase();
const additionalLanguages = (options.blogLanguages ?? [])
.map((lang) => lang.trim().toLowerCase())
.filter((lang) => lang.length > 0 && lang !== mainLanguage);
// Suppress .lang variant pages for languages that have a dedicated subtree
if (additionalLanguages.length > 0) {
const subtreeLanguages = new Set(additionalLanguages);
publishedRoutePosts = publishedRoutePosts.filter(
(p) => !(p as any).translationSourceSlug || !subtreeLanguages.has((p.language ?? '').trim().toLowerCase()),
);
}
const { sitemapXml } = buildSitemapAndFeeds({
baseUrl: options.baseUrl,
projectName: options.projectName,
@@ -1427,12 +1451,6 @@ export class BlogGenerationEngine {
await fs.mkdir(htmlDir, { recursive: true });
const sitemapPath = path.join(htmlDir, 'sitemap.xml');
// --- Build per-language expected paths ---
const mainLanguage = (options.language ?? 'en').trim().toLowerCase();
const additionalLanguages = (options.blogLanguages ?? [])
.map((lang) => lang.trim().toLowerCase())
.filter((lang) => lang.length > 0 && lang !== mainLanguage);
let sitemapToWrite = sitemapXml;
const additionalExpectedPaths: string[] = [];
const additionalPostTimestampChecks: Array<{