feat(locale): bootstrap Serbian (sr) locale with i18n + news sources#3889
feat(locale): bootstrap Serbian (sr) locale with i18n + news sources#3889zionappp-ui wants to merge 2 commits into
Conversation
- Register sr in SUPPORTED_LANGUAGES, LANGUAGES, map-locale.ts, offline.html - Register sr in scripts/translate-locales.mjs and sync-offline-translations.mjs - Add 6 verified Serbian feeds: N1 Serbia (CNN affiliate, tier 2), Nova.rs (independent, tier 2), Danas.rs (independent daily, tier 2), KRIK (investigative/intel), CINS (investigative/intel), Balkan Insight (already allowlisted, tier 1 intel — no lang tag, English-language) - Wire feeds in src/config/feeds.ts + server/worldmonitor/news/v1/_feeds.ts - Add 5 new domains to all 4 allowlist mirrors; balkaninsight.com already present - Add source-tiers entries for all 5 new outlets (both copies) - Seed sr.json locale file from en.json base with Serbian Latin-script overlay for countryBrief, header, and offline strings; remaining strings fall back to English. Serbian online media predominantly uses Latin script. Curation note: RTS (state broadcaster) omitted — under significant political pressure and not independent by IPI/RSF standards. Beta wire agency feed unavailable (no public RSS). Coverage: N1/Nova.rs/Danas.rs provide full mainstream + 2 investigative (KRIK/CINS) + 1 regional OSINT (Balkan Insight).
|
@zionappp-ui is attempting to deploy a commit to the World Monitor Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR bootstraps the Serbian (
Confidence Score: 2/5Not safe to merge — the missing comma in api/_rss-allowed-domains.js makes the Edge Function unparseable and breaks RSS fetching for every locale. The missing comma in api/_rss-allowed-domains.js produces a SyntaxError at module load time, taking down the RSS allowlist Edge Function globally. The double comma in scripts/translate-locales.mjs also crashes the translation toolchain. Both must be fixed before this ships. api/_rss-allowed-domains.js (missing comma — unparseable) and scripts/translate-locales.mjs (double comma in LANG_NAMES object). Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Browser detects 'sr' locale] --> B[i18n.ts: SUPPORTED_LANGUAGES includes 'sr']
B --> C[Lazy-load src/locales/sr.json]
C --> D[map-locale.ts: sr → name:sr tile field]
E[User visits Serbian-locale page] --> F[RSS feeds requested]
F --> G[api/_rss-allowed-domains.js\n⚠ Missing comma — SyntaxError]
G -->|Module fails to load| H[All RSS blocked]
F --> I[server/_feeds.ts: 6 Serbian feeds]
I --> J[shared/rss-allowed-domains.json\n5 new domains]
K[scripts/translate-locales.mjs\n⚠ Double comma — SyntaxError] -->|Crashes| L[Locale regeneration blocked]
Reviews (1): Last reviewed commit: "feat(locale): bootstrap Serbian (sr) loc..." | Re-trigger Greptile |
| "idp.nature.com" | ||
| "n1info.rs", |
There was a problem hiding this comment.
Missing comma causes SyntaxError in Edge Function
"idp.nature.com" on line 326 has no trailing comma before the new Serbian entries. In a JavaScript array literal, adjacent string literals without a comma separator produce a SyntaxError: Unexpected string at module parse time, which means the entire Edge Function will fail to load and the RSS allowlist will be broken for all locales — not just Serbian.
| es: 'Spanish', fr: 'French', hu: 'Hungarian', it: 'Italian', ja: 'Japanese', | ||
| ko: 'Korean', nl: 'Dutch', pl: 'Polish', pt: 'Portuguese (Brazil)', | ||
| ro: 'Romanian', ru: 'Russian', sv: 'Swedish', th: 'Thai', tr: 'Turkish', | ||
| ro: 'Romanian', ru: 'Russian', sv: 'Swedish', sr: 'Serbian (Latin)',, th: 'Thai', tr: 'Turkish', |
There was a problem hiding this comment.
Double comma is a SyntaxError in an object literal
The ,, after 'Serbian (Latin)' is a SyntaxError — object literals (unlike arrays) do not allow elision commas. This crashes the translate-locales.mjs script on every run, blocking any locale regeneration.
| ro: 'Romanian', ru: 'Russian', sv: 'Swedish', sr: 'Serbian (Latin)',, th: 'Thai', tr: 'Turkish', | |
| ro: 'Romanian', ru: 'Russian', sv: 'Swedish', sr: 'Serbian (Latin)', th: 'Thai', tr: 'Turkish', |
| "instabilityIndex": "Instability Index", | ||
| "notTracked": "Nije praćeno — {{country}} nije na CII tier-1 listi", | ||
| "intelBrief": "Intelligence Brief", | ||
| "generatingBrief": "Generiram obaveštajni pregled...", |
There was a problem hiding this comment.
Croatian verb form in a Serbian locale file
"Generiram" is the first-person singular present of Croatian; the Serbian equivalent is "Generišem". The PR description explicitly states "No Cyrillic contamination" but this is a Croatian lexical/conjugation leak — the word form is simply wrong for Serbian Latin.
| "generatingBrief": "Generiram obaveštajni pregled...", | |
| "generatingBrief": "Generišem obaveštajni pregled...", |
| pl: { title: "Jesteś offline", msg: "World Monitor wymaga połączenia internetowego do otrzymywania danych wywiadowczych w czasie rzeczywistym.", retry: "Ponów próbę" }, | ||
| pt: { title: "Você está offline", msg: "World Monitor requer uma conexão com a internet para dados de inteligência em tempo real.", retry: "Tentar novamente" }, | ||
| ro: { title: "Sunteți Offline", msg: "World Monitor necesită o conexiune la internet pentru date de informații în timp real.", retry: "Încercați din nou" }, | ||
| sr: { title: "Ste offline", msg: "World Monitor zahteva internet konekciju za podatke o obaveštavanju u realnom vremenu.", retry: "Pokušaj ponovo" }, |
There was a problem hiding this comment.
Incomplete Serbian offline title
"Ste offline" is missing the subject pronoun. While Serbian is a pro-drop language, dropping the pronoun in this short standalone label sounds incomplete — "Niste na mreži" is more natural and consistent with the fully expressed titles in other Slavic locales.
| sr: { title: "Ste offline", msg: "World Monitor zahteva internet konekciju za podatke o obaveštavanju u realnom vremenu.", retry: "Pokušaj ponovo" }, | |
| sr: { title: "Niste na mreži", msg: "World Monitor zahteva internet konekciju za podatke o obaveštavanju u realnom vremenu.", retry: "Pokušaj ponovo" }, |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…e title - api/_rss-allowed-domains.js: add missing comma after "idp.nature.com" - scripts/translate-locales.mjs: remove duplicate comma after sr entry - src/locales/sr.json: generatingBrief → "Generišem" (was Croatian "Generiram") - public/offline.html: offline title → "Niste na mreži" (more natural Serbian)
Summary
Bootstraps the Serbian (
sr) locale end-to-end.Feeds added (6 verified)
Curation note: RTS (state broadcaster) omitted — under political pressure, not independent per IPI/RSF. Beta wire agency excluded — no public RSS. balkaninsight.com already in allowlist and source-tiers from the Croatian PR.
Script note: Serbian online media uses Latin script predominantly; sr.json seeded accordingly. No Cyrillic contamination.
Files changed
src/services/i18n.ts— addsrto SUPPORTED_LANGUAGES + LANGUAGESsrc/utils/map-locale.ts— addsr: 'name:sr'public/offline.html— Serbian offline strings (Latin script)scripts/translate-locales.mjs— addsrto LOCALES + LANG_NAMESscripts/sync-offline-translations.mjs— addsrto LOCALESsrc/config/feeds.ts— SOURCE_TYPES (KRIK/CINS → 'intel') + 6 feedsserver/worldmonitor/news/v1/_feeds.ts— server mirror for all 6 feedsshared/rss-allowed-domains.json+scripts/shared/(byte-identical) — 5 new domainsapi/_rss-allowed-domains.js+vite.config.ts— all 4 mirrors updatedshared/source-tiers.json+scripts/shared/(byte-identical)src/locales/sr.json— seeded from en.json with Serbian Latin overlay for countryBrief, header, offline stringsTest plan
'intel'in SOURCE_TYPES (not mainstream)shared/ == scripts/shared/byte-identical🤖 Generated with Claude Code