Skip to content

feat: expand SEO keyword localization to cover 50+ topic-specific terms across all 13 non-English languages#851

Merged
pethers merged 3 commits intomainfrom
copilot/localize-meta-keywords
Mar 6, 2026
Merged

feat: expand SEO keyword localization to cover 50+ topic-specific terms across all 13 non-English languages#851
pethers merged 3 commits intomainfrom
copilot/localize-meta-keywords

Conversation

Copy link
Contributor

Copilot AI commented Mar 5, 2026

The keyword localization batch script only covered ~31 basic template keywords, leaving ~50 topic-specific terms (artificial intelligence, weapons law, coalition government, social welfare, weekend analysis, etc.) in English across all non-English article pages — both in <meta name="keywords"> and JSON-LD "keywords" arrays.

Translation map expansion

  • Added 50 new entries to SEO_KEYWORD_TRANSLATIONS in both scripts/fix-keywords-localization.ts and scripts/data-transformers/metadata.ts (synced for future article generation)
  • Categories: political terms, security/defence, social/labour policy, economic, AI/technology
  • Shared-form words (e.g. reform, interpellation, surveillance in French) intentionally map to the same surface form — not bugs

JSON-LD array format support

The replaceKeywords() function only matched the string format "keywords": "...". Added support for the array format used by newer articles:

// Before: only handled
"keywords": "committee reports, ..."

// Now also handles
"keywords": ["Committee Reports", "Ukraine Aid", "Data Protection"]
//            → ["委員会報告書", "Ukraine Aid", "データ保護"]  (ja)
//            → ["تقارير اللجان", "Ukraine Aid", "حماية البيانات"]  (ar)

Proper nouns (Ukraine Aid, Riksdag, NATO, Finance Committee) are correctly preserved in English via the existing fallback.

Bug fix

Hebrew translation for legislative session contained mixed Hebrew/CJK characters (מושב立法); corrected to מושב חקיקה. The one affected published article was patched directly.

Article updates

~458 articles updated across all 13 non-English languages.

Original prompt

This section details on the original issue you should resolve

<issue_title>🌐 Localize meta keywords in all non-English news articles</issue_title>
<issue_description>## 📋 Issue Type
Bug Fix / Enhancement - SEO and Multi-Language Metadata

🎯 Objective

Translate the <meta name="keywords"> content in all non-English news articles from English to the target language, improving SEO discoverability for international audiences.

📊 Current State

All non-English news articles (~1,000+ files) have English-only keywords in their metadata:

Example (all languages show the same English keywords)

<!-- Danish article (news/2026-02-14-government-propositions-da.html) -->
<meta name="keywords" content="government, propositions, parliament, legislation, Swedish Parliament, Riksdag, politics, Sweden">

<!-- Japanese article (news/2026-02-14-government-propositions-ja.html) -->
<meta name="keywords" content="government, propositions, parliament, legislation, Swedish Parliament, Riksdag, politics, Sweden">

<!-- Korean article (news/2026-02-14-government-propositions-ko.html) -->
<meta name="keywords" content="government, propositions, parliament, legislation, Swedish Parliament, Riksdag, politics, Sweden">

Impact

  • SEO: Non-English search engines cannot match articles to queries in the user's language
  • Discoverability: Japanese/Korean/Chinese/Arabic users searching in their language won't find these articles
  • Professionalism: English metadata on non-English pages signals incomplete localization

🚀 Desired State

Each article's keywords match its language:

<!-- Danish -->
<meta name="keywords" content="regering, lovforslag, parlament, lovgivning, Sveriges Riksdag, politik, Sverige">

<!-- Japanese -->
<meta name="keywords" content="政府, 法案, 議会, 立法, スウェーデン国会, 政治, スウェーデン">

<!-- Korean -->
<meta name="keywords" content="정부, 법안, 의회, 입법, 스웨덴 의회, 정치, 스웨덴">

<!-- Arabic -->
<meta name="keywords" content="حكومة, مقترحات, برلمان, تشريع, البرلمان السويدي, سياسة, السويد">

🔧 Implementation Approach

Step 1: Create Keyword Translation Map

Add a keyword translation map to the article generation system (or as a standalone dictionary):

const KEYWORD_TRANSLATIONS: Record<Language, Record<string, string>> = {
  da: { 'government': 'regering', 'propositions': 'lovforslag', 'parliament': 'parlament', 'legislation': 'lovgivning', 'Swedish Parliament': 'Sveriges Riksdag', 'Riksdag': 'Riksdag', 'politics': 'politik', 'Sweden': 'Sverige', 'committee': 'udvalg', 'reports': 'betænkninger', 'opposition': 'opposition', 'motions': 'forslag' },
  // ... for all 12 non-EN languages
};

Step 2: Create Batch Fix Script

Create a script that:

  1. Scans all news/*-{lang}.html files where lang ≠ 'en'
  2. Extracts <meta name="keywords" content="...">
  3. Translates each keyword to the target language
  4. Rewrites the meta tag
  5. Also updates "keywords" in JSON-LD structured data if present

Step 3: Update Article Template

Update scripts/article-template/template.ts to use localized keywords during generation, preventing this issue for future articles.

Step 4: Validate

  • Verify all meta keywords are in the target language
  • Ensure JSON-LD keywords match
  • HTML validation passes

🤖 Recommended Agent

agent:news-journalist — Expert in article metadata and SEO optimization. Can create the keyword translation map and batch-process existing articles. The content-generator agent could also assist with the batch processing.

✅ Acceptance Criteria

  • Keyword translation map created for all 14 languages
  • All existing non-EN news articles have localized keywords
  • JSON-LD "keywords" array also localized where present
  • Article template updated to generate localized keywords for future articles
  • HTML validation passes for all modified files
  • SEO structured data validates (Schema.org)
  • RTL keyword ordering correct for ar/he

📚 References

  • Article template: scripts/article-template/template.ts (keyword generation)
  • Content labels for reference: scripts/data-transformers/constants/content-labels-part1.ts
  • Translation dictionary: scripts/translation-dictionary.ts
  • SEO validation: scripts/validate-translations.ts
  • Existing keyword patterns in articles: <meta name="keywords" content="...">

🏷️ Labels

type:bug, component:i18n, component:seo, component:metadata, translation, priority-medium, component:news</issue_description>

<agent_instructions>Localize meta keywords in all ~1000 non-English news articles. Create a keyword translation map for all 14 languages. Build a batch fix script that scans news/*-{lang}.html files, extracts meta keywords, translates them, and rewrites the meta tag. Also update JSON-LD keywords if present. Update scripts/article-template/template.ts to generate localized keywords for future articles. Verify with HTML validation.</agent_instructions>

Comments o...


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copilot AI changed the title [WIP] Localize meta keywords in non-English news articles 🌐 Localize meta keywords in all non-English news articles Mar 5, 2026
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copilot AI changed the title 🌐 Localize meta keywords in all non-English news articles feat: expand SEO keyword localization to cover 50+ topic-specific terms across all 13 non-English languages Mar 6, 2026
@pethers pethers marked this pull request as ready for review March 6, 2026 06:59
@pethers pethers merged commit 6cfe6fc into main Mar 6, 2026
2 checks passed
@pethers pethers deleted the copilot/localize-meta-keywords branch March 6, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🌐 Localize meta keywords in all non-English news articles

2 participants