@autobusal/providers 1.14.0 → 1.15.0

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
@@ -7,6 +7,18 @@ adheres to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
7
7
  > Note: 1.8.0 through 1.11.0 were published without changelog entries. The
8
8
  > gap is left as-is rather than reconstructed after the fact.
9
9
 
10
+ ## [1.15.0] - 2026-08-02
11
+
12
+ ### Changed
13
+
14
+ - **The URL decides the language.** `getLanguage()` now reads a locale prefix
15
+ off the path before falling back to the stored preference and then the
16
+ brand default, and takes the brand's `available` list so an unrecognised
17
+ first segment (`/city/tirana`) is never mistaken for a language. This is
18
+ the point of localised URLs: a link has to decide what its recipient sees,
19
+ so someone whose last visit was in Albanian still gets Italian from a
20
+ shared `/it/...` link. Unprefixed URLs are unaffected.
21
+
10
22
  ## [1.14.0] - 2026-08-02
11
23
 
12
24
  ### Changed
package/Setup/Setup.tsx CHANGED
@@ -15,7 +15,7 @@ const Setup = ({ type, children }: Props): JSX.Element => {
15
15
  useGetMenu();
16
16
  useUserBootstrap();
17
17
 
18
- languages(type, data.preferences.languages.default);
18
+ languages(type, data.preferences.languages.default, data.preferences.languages.available);
19
19
 
20
20
  // Edited: Ferjolt Ozuni - Date: 2026-08-01
21
21
  // The brand's GTM container, from labels_settings via the admin GUI.
@@ -2,9 +2,34 @@ import i18next from 'i18next';
2
2
  import Backend from 'i18next-http-backend';
3
3
  import { initReactI18next } from 'react-i18next';
4
4
 
5
- export const getLanguage = (defaultLanguage: string): string => (
6
- localStorage.getItem('language') ?? defaultLanguage
7
- );
5
+ /**
6
+ * The language to start in.
7
+ *
8
+ * Edited: Ferjolt Ozuni - Date: 2026-08-02
9
+ * A locale-prefixed URL now wins over the stored preference. That ordering
10
+ * is the whole point of localised URLs: a link has to decide what its
11
+ * recipient sees, so somebody whose last visit was in Albanian must still
12
+ * get Italian when they open a shared /it/... link. The stored preference
13
+ * still covers every unprefixed URL - the homepage a returning visitor
14
+ * types in, and the whole account area, which is not localised.
15
+ *
16
+ * `available` is passed in rather than read from anywhere global so this
17
+ * stays a pure function of its inputs, and so an unrecognised first segment
18
+ * (/city/tirana) is never mistaken for a language.
19
+ */
20
+ export const getLanguage = (defaultLanguage: string, available: string[] = []): string => {
21
+ const [ , first ] = window.location.pathname.split('/');
22
+
23
+ if (first && available.includes(first)) {
24
+ return first;
25
+ }
26
+
27
+ const stored = localStorage.getItem('language');
28
+
29
+ return (stored && (available.length === 0 || available.includes(stored)))
30
+ ? stored
31
+ : defaultLanguage;
32
+ };
8
33
 
9
34
  // Cache-busting query param for the language files. `Cache-Control: no-cache`
10
35
  // on the obtapi side only asks caches to revalidate before reuse - in
@@ -18,7 +43,7 @@ export const getLanguage = (defaultLanguage: string): string => (
18
43
  // consumer that hasn't set VITE_BUILD_ID yet (no worse than before).
19
44
  const buildId = import.meta.env.VITE_BUILD_ID ?? 'dev';
20
45
 
21
- const languages = (type: string, defaultLanguage: string): void => {
46
+ const languages = (type: string, defaultLanguage: string, available: string[] = []): void => {
22
47
  if (i18next.isInitialized) {
23
48
  return;
24
49
  }
@@ -30,7 +55,7 @@ const languages = (type: string, defaultLanguage: string): void => {
30
55
  interpolation: {
31
56
  escapeValue: false
32
57
  },
33
- lng: getLanguage(defaultLanguage),
58
+ lng: getLanguage(defaultLanguage, available),
34
59
  fallbackLng: defaultLanguage,
35
60
  debug: import.meta.env.DEV,
36
61
  backend: {
@@ -45,7 +70,7 @@ const languages = (type: string, defaultLanguage: string): void => {
45
70
  // immediately (don't wait for the async backend fetch) and keep it in sync
46
71
  // on every future change, whether triggered by ChangeLanguage or anything
47
72
  // else that calls i18next.changeLanguage().
48
- document.documentElement.lang = getLanguage(defaultLanguage);
73
+ document.documentElement.lang = getLanguage(defaultLanguage, available);
49
74
  i18next.on('languageChanged', (lng) => {
50
75
  document.documentElement.lang = lng;
51
76
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/providers",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts"