itube-specs 0.0.1044 → 0.0.1045
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SITE_UPDATES.md
CHANGED
|
@@ -11,6 +11,23 @@
|
|
|
11
11
|
коммиты до бампа); `npm run patch` сам проставит ей номер версии. Формат пункта: что сделать и где,
|
|
12
12
|
кому именно (всем / сайтам с N), что будет, если не сделать.
|
|
13
13
|
|
|
14
|
+
## 0.0.1045 — 2026-10-20
|
|
15
|
+
|
|
16
|
+
- **Сайтам, у которых бэк включает хинди (`/v1/site/languages` отдаёт `name: "in"`, `iso: "hi"` — сейчас
|
|
17
|
+
videosection, hdsex):** слой хинди уже знает — `X-Language: in` для бэка (с `hi` бэк отдаёт английский контент),
|
|
18
|
+
общие переводы `i18n/locales/hi-IN.json` (пока пустые, заполняются через CSV слоя), `lib/countries/hi.json`
|
|
19
|
+
для `{secondText}` главной. Чтобы включить хинди на сайте: в `config/locales.config.ts` добавить
|
|
20
|
+
`{ code: 'hi', sub: 'in', file: 'hi-IN.json', language: 'hi-IN', iso: 'hi-IN', name: 'हिन्दी', value: 'hi' }`,
|
|
21
|
+
свой `i18n/locales/hi-IN.json` (мету старого сайта переносят `import-old-meta.mjs` / `import-old-h1.mjs` —
|
|
22
|
+
образец коммит videosection-redesign с хинди), `hi` в `nicheAdjectives` (если есть `%niche%`). В шаблоне
|
|
23
|
+
`meta.index.trending.h1` у хинди `{secondText}` уже несёт послелог (`भारत में`) — «में» не дописывать.
|
|
24
|
+
Не сделать — хинди на сайте нет, хотя бэк его включает.
|
|
25
|
+
- **Всем — ничего делать не надо, к сведению:** переключатель языков и hreflang (`useEnabledLocales`,
|
|
26
|
+
`useSeoLinks`) показывают только локали, объявленные сайтом в `runtimeConfig.public.locales.codes`, и
|
|
27
|
+
включённые бэком. Раньше при пустом ответе бэка показывались все локали i18n — включая приехавшие файлом из
|
|
28
|
+
слоя, без домена у сайта, а у сайта с меньшим набором, чем файлов в слое, лишние локали от бэка проходили и
|
|
29
|
+
при нормальном ответе.
|
|
30
|
+
|
|
14
31
|
## 0.0.1041 — 2026-10-19
|
|
15
32
|
|
|
16
33
|
- **Сайтам со своим `composables/use-meta.ts` или форком `pages/videos/[slug].vue` ради меты (videosection-redesign):**
|
|
@@ -97,6 +97,36 @@ describe('useSeoLinks', () => {
|
|
|
97
97
|
expect(hreflangs).not.toContain('zh-CN');
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
+
it('alternate links только для объявленных сайтом локалей, даже без ответа бэка', () => {
|
|
101
|
+
const locales = useRuntimeConfig().public.locales;
|
|
102
|
+
locales.codes = ['en', 'fr', 'ja'];
|
|
103
|
+
try {
|
|
104
|
+
const { alternateLinks } = useSeoLinks('https://example.com', mockI18n, mockLocalePath);
|
|
105
|
+
const hreflangs = alternateLinks.value.map(l => l.hreflang);
|
|
106
|
+
expect(hreflangs).toContain('fr');
|
|
107
|
+
expect(hreflangs).toContain('ja-JP');
|
|
108
|
+
expect(hreflangs).not.toContain('de');
|
|
109
|
+
expect(hreflangs).not.toContain('zh-CN');
|
|
110
|
+
} finally {
|
|
111
|
+
locales.codes = [];
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('локаль нужна и сайту, и бэку', () => {
|
|
116
|
+
const locales = useRuntimeConfig().public.locales;
|
|
117
|
+
locales.codes = ['en', 'fr', 'ja'];
|
|
118
|
+
useEnabledLanguageCodes().value = ['en', 'fr', 'de'];
|
|
119
|
+
try {
|
|
120
|
+
const { alternateLinks } = useSeoLinks('https://example.com', mockI18n, mockLocalePath);
|
|
121
|
+
const hreflangs = alternateLinks.value.map(l => l.hreflang);
|
|
122
|
+
expect(hreflangs).toContain('fr');
|
|
123
|
+
expect(hreflangs).not.toContain('de');
|
|
124
|
+
expect(hreflangs).not.toContain('ja-JP');
|
|
125
|
+
} finally {
|
|
126
|
+
locales.codes = [];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
100
130
|
it('текущая локаль остаётся в alternate, даже если её нет в списке включённых', () => {
|
|
101
131
|
mockRoute = { path: '/ja/videos', query: {} };
|
|
102
132
|
mockI18n.locale.value = 'ja';
|
|
@@ -4,14 +4,25 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export const useEnabledLanguageCodes = () => useState<string[]>('enabledLanguageCodes', () => []);
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Предикат «локаль показывается на сайте»: она объявлена сайтом (`runtimeConfig.public.locales.codes`)
|
|
9
|
+
* и включена бэком. Локаль, приехавшая только файлом из слоя, не проходит даже при пустом ответе бэка.
|
|
10
|
+
* Пустой список кодов сайта (слой без приложения) или бэка — это измерение не ограничивает.
|
|
11
|
+
*/
|
|
12
|
+
export const useIsLocaleShown = () => {
|
|
13
|
+
const enabledCodes = useEnabledLanguageCodes();
|
|
14
|
+
const siteCodes: string[] = useRuntimeConfig().public.locales?.codes || [];
|
|
15
|
+
|
|
16
|
+
return (code: string) => (!siteCodes.length || siteCodes.includes(code))
|
|
17
|
+
&& (!enabledCodes.value.length || enabledCodes.value.includes(code));
|
|
18
|
+
};
|
|
19
|
+
|
|
7
20
|
/**
|
|
8
21
|
* Локали i18n, отфильтрованные по включённым на сайте — для переключателей языка и hreflang.
|
|
9
22
|
*/
|
|
10
23
|
export const useEnabledLocales = () => {
|
|
11
24
|
const { locales } = useI18n();
|
|
12
|
-
const
|
|
25
|
+
const isShown = useIsLocaleShown();
|
|
13
26
|
|
|
14
|
-
return computed(() =>
|
|
15
|
-
? locales.value.filter(item => codes.value.includes(item.code))
|
|
16
|
-
: locales.value);
|
|
27
|
+
return computed(() => locales.value.filter(item => isShown(item.code)));
|
|
17
28
|
};
|
|
@@ -24,7 +24,7 @@ type LocalePathMock = (path: string, localeCode: string) => string;
|
|
|
24
24
|
export const useSeoLinks = (baseDomain: string, i18n: I18nMock, localePath: LocalePathMock) => {
|
|
25
25
|
const route = useRoute();
|
|
26
26
|
const overrides = useSeoOverrides();
|
|
27
|
-
const
|
|
27
|
+
const isShown = useIsLocaleShown();
|
|
28
28
|
|
|
29
29
|
const { locales, seo } = useRuntimeConfig().public;
|
|
30
30
|
const defaultCode: string = locales.default;
|
|
@@ -116,14 +116,13 @@ export const useSeoLinks = (baseDomain: string, i18n: I18nMock, localePath: Loca
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
// локаль, выключенная на сайте, отдаёт 404 (server/middleware/locale-guard.ts)
|
|
120
|
-
// такие hreflang вели бы на несуществующие страницы
|
|
121
|
-
const isEnabled = (code: string) => !enabledCodes.value.length || enabledCodes.value.includes(code);
|
|
119
|
+
// локаль, выключенная на сайте, отдаёт 404 (server/middleware/locale-guard.ts), а не объявленная
|
|
120
|
+
// сайтом не имеет домена — такие hreflang вели бы на несуществующие страницы
|
|
122
121
|
|
|
123
122
|
const otherLocales = i18n.locales.value.filter(
|
|
124
123
|
(locale) => {
|
|
125
124
|
const localeCode = typeof locale === 'string' ? locale : locale.code;
|
|
126
|
-
return localeCode !== currentLocaleCode && localeCode !== defaultCode &&
|
|
125
|
+
return localeCode !== currentLocaleCode && localeCode !== defaultCode && isShown(localeCode);
|
|
127
126
|
}
|
|
128
127
|
);
|
|
129
128
|
|