@autobusal/providers 1.3.9 → 1.4.1

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/CHANGELOG.md CHANGED
@@ -4,6 +4,44 @@ All notable changes to `@autobusal/providers` are documented here. This project
4
4
  adheres to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.4.1] - 2026-07-30
8
+
9
+ ### Fixed
10
+
11
+ - **`<html lang>` never reflected the active language (`Setup/languages.ts`).**
12
+ `index.html` hardcodes `lang="en"` at build time and nothing updated it
13
+ afterward - every one of the 15 supported languages rendered under the same
14
+ `lang` attribute, a signal both search engines and screen readers rely on.
15
+ `languages()` now sets `document.documentElement.lang` immediately on init
16
+ (using the same `localStorage`-or-default resolution as the i18next `lng`
17
+ option) and keeps it in sync via `i18next.on('languageChanged', ...)`, so it
18
+ tracks every future change regardless of what triggers it.
19
+
20
+ ## [1.4.0] - 2026-07-30
21
+
22
+ ### Added
23
+
24
+ - **Cache-busting on language file requests (`Setup/languages.ts`).** A
25
+ production report showed the admin panel still displaying raw i18n keys
26
+ after obtapi's translation JSON was fixed and confirmed correct
27
+ server-side - even after multiple manual hard-reloads. `Cache-Control:
28
+ no-cache` on obtapi's side only asks caches to revalidate before reuse,
29
+ which was not reliable enough against whatever was actually caching
30
+ (browser and/or an intermediate proxy) in the real deployment. The
31
+ `loadPath` now appends `?v={{VITE_BUILD_ID}}`, a fresh value baked in at
32
+ build time by the consuming app's `vite.config.ts` `define` - every
33
+ rebuild produces a URL nothing in the chain has ever cached, independent
34
+ of whether that cache actually honors Cache-Control. Falls back to a
35
+ fixed `'dev'` string if the consumer hasn't defined `VITE_BUILD_ID` yet
36
+ (no worse than before). **Requires consuming apps to add a
37
+ `VITE_BUILD_ID` define to `vite.config.ts`** (done for magus and
38
+ alvavel alongside this release) for the cache-busting to take effect -
39
+ without it, this version behaves identically to 1.3.9.
40
+ - Companion fix in obtapi: `public/.htaccess` strengthened from
41
+ `Cache-Control: no-cache` to `no-store, no-cache, must-revalidate,
42
+ max-age=0` plus `Pragma`/`Expires`, so language JSON is never stored by
43
+ a compliant cache at all, not just revalidated.
44
+
7
45
  ## [1.3.9] - 2026-07-30
8
46
 
9
47
  ### Fixed
@@ -6,6 +6,18 @@ export const getLanguage = (defaultLanguage: string): string => (
6
6
  localStorage.getItem('language') ?? defaultLanguage
7
7
  );
8
8
 
9
+ // Cache-busting query param for the language files. `Cache-Control: no-cache`
10
+ // on the obtapi side only asks caches to revalidate before reuse - in
11
+ // practice that was not enough (some browser/proxy along the way kept
12
+ // serving a stale translation file across manual hard-reloads after a
13
+ // deploy). VITE_BUILD_ID is a fresh value baked in at build time by each
14
+ // consuming app's vite.config.ts (`define`), so every rebuild produces a
15
+ // URL that has never been requested before - nothing anywhere in the chain
16
+ // can have a stale cache entry for it, independent of whether that cache
17
+ // respects Cache-Control at all. Falls back to a fixed string for any
18
+ // consumer that hasn't set VITE_BUILD_ID yet (no worse than before).
19
+ const buildId = import.meta.env.VITE_BUILD_ID ?? 'dev';
20
+
9
21
  const languages = (type: string, defaultLanguage: string): void => {
10
22
  if (i18next.isInitialized) {
11
23
  return;
@@ -22,10 +34,21 @@ const languages = (type: string, defaultLanguage: string): void => {
22
34
  fallbackLng: defaultLanguage,
23
35
  debug: import.meta.env.DEV,
24
36
  backend: {
25
- loadPath: `${ import.meta.env.VITE_API_OBT }/languages/{{lng}}/{{ns}}.json`
37
+ loadPath: `${ import.meta.env.VITE_API_OBT }/languages/{{lng}}/{{ns}}.json?v=${ buildId }`
26
38
  },
27
39
  ns: type
28
40
  });
41
+
42
+ // <html lang> was otherwise hardcoded at build time (index.html) and never
43
+ // updated again - every locale of every page shared one lang attribute, a
44
+ // basic a11y/SEO signal search engines and screen readers rely on. Set it
45
+ // immediately (don't wait for the async backend fetch) and keep it in sync
46
+ // on every future change, whether triggered by ChangeLanguage or anything
47
+ // else that calls i18next.changeLanguage().
48
+ document.documentElement.lang = getLanguage(defaultLanguage);
49
+ i18next.on('languageChanged', (lng) => {
50
+ document.documentElement.lang = lng;
51
+ });
29
52
  };
30
53
 
31
54
  export default languages;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/providers",
3
- "version": "1.3.9",
3
+ "version": "1.4.1",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts"