From 07fd2d9e1c99749d80a99f8cf89698e1d3df3595 Mon Sep 17 00:00:00 2001 From: stromek Date: Fri, 14 Aug 2026 22:11:34 +0200 Subject: [PATCH 1/2] Do not document language as a fixed set of codes The widget resolves the language against the translations it actually ships and uses English for anything else, so no code is invalid. Naming en/cs/sk in the docs implied a whitelist and would go stale with every language added. --- CHANGELOG.md | 4 ++++ README.md | 6 +++--- src/Options/ConfOptions.php | 2 +- src/SnippetClient.php | 5 +++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 171622a..2540bcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [Unreleased] +### Changed +- Documentation of `language` (on `ConfOptions` and `snippet()`) no longer names a fixed set of codes. Any language code is accepted and one without a translation falls back to English, so the list would only go stale as languages are added + ## [0.5.0] - 2026-08-14 ### Added - `language` option on `ConfOptions` — sets the widget UI language through `conf()`, mirroring `theme`. Values: `null` (follows the browser, falling back to English), `en`, `cs`, `sk`. Unlike the `snippet()` parameter it can be changed at runtime; when both are given, the conf value wins diff --git a/README.md b/README.md index 08f598b..d1c522c 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ $client = new SnippetClient('key', 'secret', codeHasher: new MyCustomHasher()); ## Methods | Method | Description | |---|---| -| `snippet(?string $language = null)` | Async loader script. Place once per page. Optional UI language (`cs`, `en`, `sk`…), otherwise auto-detected from the browser. | +| `snippet(?string $language = null)` | Async loader script. Place once per page. Optional initial UI language (any code; unknown falls back to English), otherwise auto-detected from the browser. | | `conf(ConfOptions)` | SDK configuration (notification renderer, CSS, callbacks…). | | `user(UserOptions)` | Identifies the current user. | | `thread(string $selector, ThreadOptions)` | Embeds a thread into a DOM element. | @@ -284,12 +284,12 @@ See the full list of parameters in [`src/Options/ConfOptions.php`](src/Options/C | `pageCSSPath` | `?string` | CSS file URL injected into the snippet iframe. | | `notificationElementTargetElement` | `?string` | JS expression returning the target DOM element. | | `notificationElementPosition` | `?int` | Icon position: 1=top-left, 2=top-right, 3=bottom-right, 4=bottom-left. | -| `language` | `?string` | UI language of the app. Values: `null` (follows the browser, falling back to English), `en`, `cs`, `sk`. | +| `language` | `?string` | UI language of the app. Any language code is accepted; one without a translation falls back to English. `null` follows the browser. | | `theme` | `?string` | Light/dark mode for the app. Values: `null` (follows browser preference), `stromcom-light`, `stromcom-dark`. | | `entityResolve` | `?string` | JS callback resolving business-entity detail (order, ticket…) for the message editor's chip hover-card. Receives `{type, id}`, returns (or resolves to) `{title, url?, fields: [{label, value}]}`. | ### UI language -Set the language on `ConfOptions`, the same way as the theme. When omitted, the widget detects it from the browser, falling back to English. +Set the language on `ConfOptions`, the same way as the theme. Any language code is accepted — the widget uses English for a language it has no translation for, so passing one is never an error. When omitted, the language is detected from the browser. ```php echo $client->conf(new ConfOptions(language: 'cs'))->getHTML(); ``` diff --git a/src/Options/ConfOptions.php b/src/Options/ConfOptions.php index 0ecdb54..f260166 100644 --- a/src/Options/ConfOptions.php +++ b/src/Options/ConfOptions.php @@ -45,7 +45,7 @@ class ConfOptions extends SnippetOptions { #[Docs('Callback invoked after the notification element is rendered', null, true, 'Function|null')] private ?string $notificationElementAfterRender = null; - #[Docs('UI language of the app. Null follows the browser, falling back to English. Available: en, cs, sk', 'cs', true)] + #[Docs('UI language of the app. Any language code is accepted; one without a translation falls back to English. Null follows the browser.', 'cs', true)] private ?string $language = null; #[Docs('Theme name applied to the host page via data-theme on . Available: stromcom-default, stromcom-dark', 'stromcom-dark', true)] diff --git a/src/SnippetClient.php b/src/SnippetClient.php index a8af7d1..afdbe42 100644 --- a/src/SnippetClient.php +++ b/src/SnippetClient.php @@ -59,8 +59,9 @@ public function csp(): CspPolicy { * Generates the async loader snippet that bootstraps the SDK. * Place this once on every page where you want the widget to appear. * - * @param string|null $language UI language (e.g. "cs", "en", "sk"). Null (default) lets the - * widget detect it from the browser, falling back to English. + * @param string|null $language UI language (e.g. "cs", "en", "sk"). Any code is accepted; + * one without a translation falls back to English. Null (default) + * lets the widget detect it from the browser. * This is the initial value only — `ConfOptions::$language` * overrides it and can be changed later at runtime. * From d951548d1692142ced126cbbedbd0d68e4bd6676 Mon Sep 17 00:00:00 2001 From: stromek Date: Fri, 14 Aug 2026 22:19:49 +0200 Subject: [PATCH 2/2] Spell out the language fallback chain Unknown language falls back to the browser language first, then English -- not straight to English. --- CHANGELOG.md | 2 +- README.md | 4 ++-- src/Options/ConfOptions.php | 2 +- src/SnippetClient.php | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2540bcf..9bfec0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## [Unreleased] ### Changed -- Documentation of `language` (on `ConfOptions` and `snippet()`) no longer names a fixed set of codes. Any language code is accepted and one without a translation falls back to English, so the list would only go stale as languages are added +- Documentation of `language` (on `ConfOptions` and `snippet()`) no longer names a fixed set of codes. Any language code is accepted and one without a translation falls back to the browser language, then English, so the list would only go stale as languages are added ## [0.5.0] - 2026-08-14 ### Added diff --git a/README.md b/README.md index d1c522c..bfda623 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ $client = new SnippetClient('key', 'secret', codeHasher: new MyCustomHasher()); ## Methods | Method | Description | |---|---| -| `snippet(?string $language = null)` | Async loader script. Place once per page. Optional initial UI language (any code; unknown falls back to English), otherwise auto-detected from the browser. | +| `snippet(?string $language = null)` | Async loader script. Place once per page. Optional initial UI language (any code; one without a translation falls back to the browser language, then English). | | `conf(ConfOptions)` | SDK configuration (notification renderer, CSS, callbacks…). | | `user(UserOptions)` | Identifies the current user. | | `thread(string $selector, ThreadOptions)` | Embeds a thread into a DOM element. | @@ -284,7 +284,7 @@ See the full list of parameters in [`src/Options/ConfOptions.php`](src/Options/C | `pageCSSPath` | `?string` | CSS file URL injected into the snippet iframe. | | `notificationElementTargetElement` | `?string` | JS expression returning the target DOM element. | | `notificationElementPosition` | `?int` | Icon position: 1=top-left, 2=top-right, 3=bottom-right, 4=bottom-left. | -| `language` | `?string` | UI language of the app. Any language code is accepted; one without a translation falls back to English. `null` follows the browser. | +| `language` | `?string` | UI language of the app. Any language code is accepted; one without a translation falls back to the browser language, then English. `null` follows the browser. | | `theme` | `?string` | Light/dark mode for the app. Values: `null` (follows browser preference), `stromcom-light`, `stromcom-dark`. | | `entityResolve` | `?string` | JS callback resolving business-entity detail (order, ticket…) for the message editor's chip hover-card. Receives `{type, id}`, returns (or resolves to) `{title, url?, fields: [{label, value}]}`. | diff --git a/src/Options/ConfOptions.php b/src/Options/ConfOptions.php index f260166..2ed378d 100644 --- a/src/Options/ConfOptions.php +++ b/src/Options/ConfOptions.php @@ -45,7 +45,7 @@ class ConfOptions extends SnippetOptions { #[Docs('Callback invoked after the notification element is rendered', null, true, 'Function|null')] private ?string $notificationElementAfterRender = null; - #[Docs('UI language of the app. Any language code is accepted; one without a translation falls back to English. Null follows the browser.', 'cs', true)] + #[Docs('UI language of the app. Any language code is accepted; one without a translation falls back to the browser language, then English. Null follows the browser.', 'cs', true)] private ?string $language = null; #[Docs('Theme name applied to the host page via data-theme on . Available: stromcom-default, stromcom-dark', 'stromcom-dark', true)] diff --git a/src/SnippetClient.php b/src/SnippetClient.php index afdbe42..8775120 100644 --- a/src/SnippetClient.php +++ b/src/SnippetClient.php @@ -60,8 +60,8 @@ public function csp(): CspPolicy { * Place this once on every page where you want the widget to appear. * * @param string|null $language UI language (e.g. "cs", "en", "sk"). Any code is accepted; - * one without a translation falls back to English. Null (default) - * lets the widget detect it from the browser. + * one without a translation falls back to the browser language, + * then English. Null (default) lets the widget detect it from the browser. * This is the initial value only — `ConfOptions::$language` * overrides it and can be changed later at runtime. *