Fix llms.txt and llms-full.txt language variants filtering (#4179)

This commit is contained in:
Nolann B.
2026-04-13 21:53:42 +02:00
committed by GitHub
parent 7fd381c0b1
commit ecb4292551
3 changed files with 58 additions and 6 deletions
@@ -1,20 +1,17 @@
import { languages } from '@/intl/translations';
import type { GitBookSiteContext } from '@/lib/context';
import { getSiteSpaceLanguages, normalizeLanguage } from '@/lib/sites';
/**
* Categorize the variants of the space into generic and translation variants.
*/
export function categorizeVariants(context: GitBookSiteContext) {
const { siteSpace, visibleSiteSpaces: siteSpaces } = context;
const normalizeLanguage = (language: string | undefined) =>
language === undefined ? languages.en.locale : language;
const currentLanguage = normalizeLanguage(context.locale);
// Get all languages of the variants.
const variantLanguages = [
...new Set(siteSpaces.map((space) => normalizeLanguage(space.space.language))),
];
const variantLanguages = getSiteSpaceLanguages(siteSpaces);
// We show the language picker when there are at least 2 distinct languages.
// Spaces without an explicit language are treated as English, matching runtime defaults.
+31
View File
@@ -0,0 +1,31 @@
import { describe, expect, it } from 'bun:test';
import type { SiteSpace } from '@gitbook/api';
import { TranslationLanguage } from '@gitbook/api';
import { filterSiteSpacesByLocale } from './sites';
function makeSiteSpace(language: TranslationLanguage | undefined): SiteSpace {
return { space: { language } } as unknown as SiteSpace;
}
describe('filterSiteSpacesByLocale', () => {
it('returns all spaces on a single-language site', () => {
const spaces = [makeSiteSpace(undefined), makeSiteSpace(undefined)];
expect(filterSiteSpacesByLocale(spaces, TranslationLanguage.En)).toEqual(spaces);
});
it('filters by locale on a multi-language site', () => {
const en = makeSiteSpace(TranslationLanguage.En);
const fr = makeSiteSpace(TranslationLanguage.Fr);
expect(filterSiteSpacesByLocale([en, fr], TranslationLanguage.Fr)).toEqual([fr]);
});
it('treats undefined language as English', () => {
const undefinedLanguage = makeSiteSpace(undefined);
const en = makeSiteSpace(TranslationLanguage.En);
expect(filterSiteSpacesByLocale([undefinedLanguage, en], TranslationLanguage.En)).toEqual([
undefinedLanguage,
en,
]);
});
});
+25 -1
View File
@@ -1,3 +1,4 @@
import { languages } from '@/intl/translations';
import type { GitBookSiteContext } from '@/lib/context';
import type {
LocalizedString,
@@ -39,6 +40,21 @@ export function getSiteStructureSections(
: [];
}
/**
* Normalize a space language to a locale string.
* Spaces without an explicit language are treated as English, matching runtime defaults.
*/
export function normalizeLanguage(language: string | undefined): string {
return language === undefined ? languages.en.locale : language;
}
/**
* Return the distinct normalized languages across a set of site spaces.
*/
export function getSiteSpaceLanguages(siteSpaces: SiteSpace[]): string[] {
return [...new Set(siteSpaces.map((space) => normalizeLanguage(space.space.language)))];
}
/**
* Filter site spaces to only include those matching the given locale
*/
@@ -46,7 +62,15 @@ export function filterSiteSpacesByLocale(
siteSpaces: SiteSpace[],
locale: TranslationLanguage | undefined
): SiteSpace[] {
return siteSpaces.filter((siteSpace) => siteSpace.space.language === locale);
const variantLanguages = getSiteSpaceLanguages(siteSpaces);
if (variantLanguages.length <= 1) {
return siteSpaces;
}
const normalizedLocale = normalizeLanguage(locale);
return siteSpaces.filter(
(siteSpace) => normalizeLanguage(siteSpace.space.language) === normalizedLocale
);
}
/*