Skip to content

feat(locale): bootstrap Serbian (sr) locale with i18n + news sources#3889

Open
zionappp-ui wants to merge 2 commits into
koala73:mainfrom
zionappp-ui:feat/sr-locale
Open

feat(locale): bootstrap Serbian (sr) locale with i18n + news sources#3889
zionappp-ui wants to merge 2 commits into
koala73:mainfrom
zionappp-ui:feat/sr-locale

Conversation

@zionappp-ui
Copy link
Copy Markdown
Contributor

Summary

Bootstraps the Serbian (sr) locale end-to-end.

Feeds added (6 verified)

Outlet Domain Type Tier Items Lang tag
N1 Serbia n1info.rs Independent TV (CNN affiliate) 2 50 sr
Nova.rs nova.rs Independent news portal 2 50 sr
Danas.rs www.danas.rs Independent daily 2 50 sr
KRIK www.krik.rs Investigative journalism intel 10 sr
CINS www.cins.rs Investigative journalism intel 10 sr
Balkan Insight balkaninsight.com Regional OSINT/investigative 1 (existing) 90 none (English)

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 — add sr to SUPPORTED_LANGUAGES + LANGUAGES
  • src/utils/map-locale.ts — add sr: 'name:sr'
  • public/offline.html — Serbian offline strings (Latin script)
  • scripts/translate-locales.mjs — add sr to LOCALES + LANG_NAMES
  • scripts/sync-offline-translations.mjs — add sr to LOCALES
  • src/config/feeds.ts — SOURCE_TYPES (KRIK/CINS → 'intel') + 6 feeds
  • server/worldmonitor/news/v1/_feeds.ts — server mirror for all 6 feeds
  • shared/rss-allowed-domains.json + scripts/shared/ (byte-identical) — 5 new domains
  • api/_rss-allowed-domains.js + vite.config.ts — all 4 mirrors updated
  • shared/source-tiers.json + scripts/shared/ (byte-identical)
  • src/locales/sr.json — seeded from en.json with Serbian Latin overlay for countryBrief, header, offline strings

Test plan

  • Feed probe: all 6 URLs return ≥10 items
  • Switch UI to Serbian — no Czech/Slovenian/Croatian strings visible
  • KRIK + CINS typed as 'intel' in SOURCE_TYPES (not mainstream)
  • Balkan Insight has no lang tag (English-language outlet)
  • All 4 allowlist mirrors consistent for the 5 new domains
  • source-tiers parity: shared/ == scripts/shared/ byte-identical

🤖 Generated with Claude Code

- 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).
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

@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.

@github-actions github-actions Bot added the trust:caution Brin: contributor trust score caution label May 24, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 24, 2026

Greptile Summary

This PR bootstraps the Serbian (sr) locale end-to-end: i18n registration, map tile field, offline strings, translation scripts, a seeded sr.json, six RSS feeds (N1 Serbia, Nova.rs, Danas.rs, KRIK, CINS, Balkan Insight), and all four allowlist/source-tier mirrors. Two syntax errors were introduced alongside the otherwise well-structured changes.

  • api/_rss-allowed-domains.js is missing a comma after \"idp.nature.com\", making the JS module unparseable and breaking the RSS allowlist Edge Function for all locales until fixed.
  • scripts/translate-locales.mjs has a double comma (,,) in the LANG_NAMES object literal \u2014 a SyntaxError that crashes the translation script on every run.
  • src/locales/sr.json contains one Croatian verb form and the offline title in public/offline.html omits the subject pronoun compared to peer Slavic locale entries.

Confidence Score: 2/5

Not 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

Filename Overview
api/_rss-allowed-domains.js Missing comma after "idp.nature.com" causes a SyntaxError — the Edge Function module will not load, breaking the RSS allowlist entirely.
scripts/translate-locales.mjs Double comma in LANG_NAMES object literal is a SyntaxError that crashes the translation script on every invocation.
src/locales/sr.json New Serbian locale file; bulk of strings are English stubs with partial Serbian overlay. One Croatian verb form ("Generiram" → "Generišem") slipped through.
public/offline.html Serbian entry inserted in correct locale order; title string "Ste offline" is grammatically thin compared to peer locales.
src/config/feeds.ts Six feeds added correctly; KRIK and CINS typed as 'intel', Balkan Insight has no lang tag as intended.
server/worldmonitor/news/v1/_feeds.ts Server mirror of the six feeds added; consistent with client-side config.
shared/source-tiers.json Five new entries added; KRIK and CINS assigned tier 2 matching the other Serbian mainstream sources.
src/services/i18n.ts "sr" added to SUPPORTED_LANGUAGES; lazy-loading via import.meta.glob will pick up sr.json automatically.

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]
Loading

Reviews (1): Last reviewed commit: "feat(locale): bootstrap Serbian (sr) loc..." | Re-trigger Greptile

Comment thread api/_rss-allowed-domains.js Outdated
Comment on lines +326 to +327
"idp.nature.com"
"n1info.rs",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 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.

Comment thread scripts/translate-locales.mjs Outdated
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',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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.

Suggested change
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',

Comment thread src/locales/sr.json Outdated
"instabilityIndex": "Instability Index",
"notTracked": "Nije praćeno — {{country}} nije na CII tier-1 listi",
"intelBrief": "Intelligence Brief",
"generatingBrief": "Generiram obaveštajni pregled...",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Suggested change
"generatingBrief": "Generiram obaveštajni pregled...",
"generatingBrief": "Generišem obaveštajni pregled...",

Comment thread public/offline.html Outdated
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" },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Suggested change
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)
@koala73 koala73 added the area: i18n Internationalization, translations label May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: i18n Internationalization, translations trust:caution Brin: contributor trust score caution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants