-
Notifications
You must be signed in to change notification settings - Fork 1
Description
📋 Issue Type
Feature / Translation / Multi-Language
🎯 Objective
Ensure all 9 dashboard sections are correctly replicated and translated across all 14 language variants (index_??.html) and separate dashboard directory (dashboard/index_??.html), with full i18n support, proper hreflang tags, and cultural formatting for dates/numbers.
📊 Current State
Language Coverage Analysis
Measured: 2026-02-18
Supported Languages (14 total):
- English (en) - index.html ✅
- Swedish (sv) - index_sv.html
⚠️ - Danish (da) - index_da.html
⚠️ - Norwegian (no) - index_no.html
⚠️ - Finnish (fi) - index_fi.html
⚠️ - German (de) - index_de.html
⚠️ - French (fr) - index_fr.html
⚠️ - Spanish (es) - index_es.html
⚠️ - Dutch (nl) - index_nl.html
⚠️ - Arabic (ar) - index_ar.html
⚠️ (RTL) - Hebrew (he) - index_he.html
⚠️ (RTL) - Japanese (ja) - index_ja.html
⚠️ - Korean (ko) - index_ko.html
⚠️ - Chinese (zh) - index_zh.html
⚠️
Dashboard Directory Structure:
/dashboard/
├── index.html (en) ✅
├── index_sv.html (sv) ⚠️
├── index_da.html (da) ⚠️
├── index_no.html (no) ⚠️
├── index_fi.html (fi) ⚠️
├── index_de.html (de) ⚠️
├── index_fr.html (fr) ⚠️
├── index_es.html (es) ⚠️
├── index_nl.html (nl) ⚠️
├── index_ar.html (ar) ⚠️ (RTL)
├── index_he.html (he) ⚠️ (RTL)
├── index_ja.html (ja) ⚠️
├── index_ko.html (ko) ⚠️
└── index_zh.html (zh) ⚠️
Issues Identified:
1. Missing Dashboard Sections (13 language variants):
- Only English (index.html) has complete 9 dashboards
- Other languages missing or have outdated dashboard HTML
- Dashboard JavaScript files not language-aware
2. Translation Gaps:
- Dashboard headings not translated
- Chart labels in English only (party names, risk levels, etc.)
- Tooltip content not localized
- Error messages hardcoded in English
- "Loading..." indicators not translated
3. Cultural Formatting Issues:
- Date format: US format (MM/DD/YYYY) instead of local (DD.MM.YYYY, YYYY-MM-DD)
- Number format: English separators (1,234.56) instead of local (1 234,56 or 1.234,56)
- Party abbreviations not localized (e.g., "C" vs "Centerpartiet")
- Time format: 12-hour instead of 24-hour for some locales
4. RTL Layout Issues (Arabic, Hebrew):
- Dashboard grid not flipped for RTL
- Chart legends positioned incorrectly
- Text alignment not reversed
- Navigation breadcrumbs wrong direction
5. Hreflang Missing:
- Many language pages missing hreflang tags
- SEO impact: Search engines can't identify language variants
- Duplicate content penalties risk
6. Font Support:
- Missing CJK fonts for Japanese, Korean, Chinese
- Arabic/Hebrew require proper font with ligature support
- Font fallback chain incomplete
🚀 Desired State
Complete Language Coverage:
- ✅ All 14 languages have identical dashboard structure
- ✅ All 9 dashboards present in every language variant
- ✅ Dashboard JavaScript files detect language and adjust content
- ✅ All text translated (headings, labels, tooltips, errors)
Cultural Localization:
- ✅ Date formatting per locale (ISO 8601 fallback)
- ✅ Number formatting with correct separators
- ✅ Party names localized or explained in native language
- ✅ Time zones respected (CET for Swedish data)
RTL Support (Arabic, Hebrew):
- ✅
dir="rtl"on<html>tag - ✅ Dashboard grid mirrored
- ✅ Chart legends positioned correctly
- ✅ Text alignment reversed
- ✅ Navigation breadcrumbs flow right-to-left
SEO Optimization:
- ✅ Hreflang tags on all pages (14 languages + x-default)
- ✅ Correct lang attribute on
<html>tag - ✅ Canonical URLs pointing to language-specific pages
- ✅ Open Graph locale tags
Font Coverage:
- ✅ Noto Sans CJK for Japanese, Korean, Chinese
- ✅ Noto Sans Arabic for Arabic
- ✅ Noto Sans Hebrew for Hebrew
- ✅ Proper font-family fallback chains
🌐 Translation & Content Alignment
Translation Guide(s):
- Swedish: https://github.com/Hack23/homepage/blob/main/Swedish-Translation-Guide.md
- Finnish: https://github.com/Hack23/homepage/blob/main/Finnish-Translation-Guide.md
- Korean: https://github.com/Hack23/homepage/blob/main/Korean-Translation-Guide.md
- Spanish: https://github.com/Hack23/homepage/blob/main/Spanish-Translation-Guide.md
Related Homepage Page(s):
- CIA Features: cia-features.html (14 languages)
- CIA Documentation: cia-docs.html (14 languages)
- CIA Architecture: blog-cia-architecture.html (14 languages)
Multi-Language Scope: All 14 languages
Implementation Notes:
- Review terminology: CIA Triad (Confidentiality, Integrity, Availability)
- Political terms: Riksdag, MP (ledamot), party names
- Align messaging with homepage CIA pages
- ISMS terminology consistency
🔧 Implementation Approach
Phase 1: Dashboard HTML Replication (12 hours)
1.1 Template Dashboard Structure
# Create template from English version
node scripts/generate-language-variants.js --source index.html --template
# Output: dashboard-template.html with {{TRANSLATION_KEY}} markers1.2 Replicate for All Languages
# For each language
for LANG in sv da no fi de fr es nl ar he ja ko zh; do
node scripts/generate-language-variants.js \
--template dashboard-template.html \
--language $LANG \
--output index_${LANG}.html
done1.3 Verify Structure Consistency
# Ensure all languages have same dashboard sections
node scripts/validate-dashboard-structure.js
# Check:
# - All 9 dashboard IDs present
# - Chart canvas elements exist
# - Filter controls present
# - ARIA attributes includedPhase 2: JavaScript i18n (16 hours)
2.1 Create Translation Dictionary
// js/i18n/dashboard-translations.js
const DASHBOARD_TRANSLATIONS = {
en: {
loadingData: 'Loading data...',
noDataAvailable: 'No data available',
errorLoadingData: 'Error loading data. Please try again.',
partyEffectiveness: 'Party Effectiveness',
riskLevel: {
HIGH: 'High Risk',
MEDIUM: 'Medium Risk',
LOW: 'Low Risk',
CRITICAL: 'Critical Risk'
},
parties: {
M: 'Moderate Party',
S: 'Social Democrats',
SD: 'Sweden Democrats',
C: 'Centre Party',
V: 'Left Party',
MP: 'Green Party',
KD: 'Christian Democrats',
L: 'Liberals'
}
},
sv: {
loadingData: 'Laddar data...',
noDataAvailable: 'Ingen data tillgänglig',
errorLoadingData: 'Fel vid laddning av data. Försök igen.',
partyEffectiveness: 'Partieffektivitet',
riskLevel: {
HIGH: 'Hög risk',
MEDIUM: 'Medel risk',
LOW: 'Låg risk',
CRITICAL: 'Kritisk risk'
},
parties: {
M: 'Moderaterna',
S: 'Socialdemokraterna',
SD: 'Sverigedemokraterna',
C: 'Centerpartiet',
V: 'Vänsterpartiet',
MP: 'Miljöpartiet',
KD: 'Kristdemokraterna',
L: 'Liberalerna'
}
},
// ... all 14 languages
};
function getTranslation(key, lang = detectLanguage()) {
return DASHBOARD_TRANSLATIONS[lang]?.[key] ||
DASHBOARD_TRANSLATIONS['en'][key];
}2.2 Language Detection
// js/i18n/language-detector.js
function detectLanguage() {
// Method 1: Check HTML lang attribute
const htmlLang = document.documentElement.lang;
if (htmlLang) return htmlLang.substring(0, 2);
// Method 2: Check URL (index_sv.html → sv)
const urlMatch = window.location.pathname.match(/index_([a-z]{2})\.html/);
if (urlMatch) return urlMatch[1];
// Method 3: Check localStorage
const storedLang = localStorage.getItem('preferredLanguage');
if (storedLang) return storedLang;
// Method 4: Browser language
const browserLang = navigator.language.substring(0, 2);
// Default to English
return ['en', 'sv', 'da', 'no', 'fi', 'de', 'fr', 'es',
'nl', 'ar', 'he', 'ja', 'ko', 'zh'].includes(browserLang)
? browserLang : 'en';
}2.3 Localize Chart Labels
// js/party-dashboard.js
function renderPartyEffectivenessChart(data) {
const lang = detectLanguage();
const t = (key) => getTranslation(key, lang);
const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: data.map(d => t(`parties.${d.party}`)), // Translate party names
datasets: [{
label: t('partyEffectiveness'), // Translate dataset label
data: data.map(d => d.effectiveness)
}]
},
options: {
plugins: {
tooltip: {
callbacks: {
label: (context) => {
// Localized tooltip
return `${context.dataset.label}: ${formatNumber(context.parsed.y, lang)}`;
}
}
}
}
}
});
}Phase 3: Cultural Formatting (8 hours)
3.1 Date/Number Formatting
// js/i18n/formatters.js
function formatDate(date, lang) {
const locales = {
en: 'en-US',
sv: 'sv-SE',
da: 'da-DK',
no: 'nb-NO',
fi: 'fi-FI',
de: 'de-DE',
fr: 'fr-FR',
es: 'es-ES',
nl: 'nl-NL',
ar: 'ar-SA',
he: 'he-IL',
ja: 'ja-JP',
ko: 'ko-KR',
zh: 'zh-CN'
};
return new Date(date).toLocaleDateString(locales[lang], {
year: 'numeric',
month: 'long',
day: 'numeric'
});
}
function formatNumber(num, lang) {
const locales = {
en: 'en-US',
sv: 'sv-SE',
// ... all locales
};
return num.toLocaleString(locales[lang], {
minimumFractionDigits: 0,
maximumFractionDigits: 2
});
}Phase 4: RTL Support (6 hours)
4.1 HTML RTL Attributes
<!-- index_ar.html -->
<html lang="ar" dir="rtl">
<head>
<style>
/* RTL-specific overrides */
[dir="rtl"] .dashboard-grid {
direction: rtl;
}
[dir="rtl"] .breadcrumb {
flex-direction: row-reverse;
}
[dir="rtl"] .chart-legend {
text-align: right;
}
</style>
</head>4.2 CSS RTL Adjustments
/* styles.css - Add RTL support */
[dir="rtl"] {
text-align: right;
}
[dir="rtl"] .dashboard-container {
direction: rtl;
}
[dir="rtl"] .breadcrumb-item::after {
content: "←"; /* Reverse arrow */
margin: 0 0.5rem 0 0;
}
/* Flip chart positioning for RTL */
[dir="rtl"] canvas {
transform: scaleX(-1);
}
[dir="rtl"] .chart-legend {
transform: scaleX(-1); /* Flip back legend text */
}Phase 5: Hreflang & SEO (4 hours)
5.1 Generate Hreflang Tags
// scripts/generate-hreflang.js
const languages = [
{ code: 'en', file: 'index.html' },
{ code: 'sv', file: 'index_sv.html' },
// ... all 14 languages
];
languages.forEach(lang => {
const hreflangTags = languages.map(targetLang =>
`<link rel="alternate" hreflang="${targetLang.code}" href="https://riksdagsmonitor.com/${targetLang.file}">`
).join('\n');
// Also add x-default
hreflangTags += '\n<link rel="alternate" hreflang="x-default" href="https://riksdagsmonitor.com/index.html">';
// Insert into HTML
insertHreflangTags(lang.file, hreflangTags);
});Phase 6: Font Support (3 hours)
6.1 Add CJK and RTL Fonts
<!-- Add to <head> -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" rel="stylesheet">/* styles.css - Language-specific fonts */
:lang(ja) {
font-family: 'Noto Sans JP', 'Inter', sans-serif;
}
:lang(ko) {
font-family: 'Noto Sans KR', 'Inter', sans-serif;
}
:lang(zh) {
font-family: 'Noto Sans SC', 'Inter', sans-serif;
}
:lang(ar) {
font-family: 'Noto Sans Arabic', 'Inter', sans-serif;
}
:lang(he) {
font-family: 'Noto Sans Hebrew', 'Inter', sans-serif;
}🤖 Recommended Agent
Agent: frontend-specialist
Rationale:
- Expert in multi-language static websites
- Knows i18n/l10n best practices
- Understands RTL layout requirements
- Familiar with cultural formatting (dates, numbers)
- Can implement hreflang SEO optimization
Custom Instructions:
1. Replicate all 9 dashboard sections for 14 languages
2. Implement JavaScript i18n with translation dictionary
3. Add cultural formatting (dates, numbers per locale)
4. Fix RTL layout for Arabic and Hebrew (dir="rtl")
5. Add hreflang tags for all languages
6. Include proper fonts (Noto Sans CJK, Arabic, Hebrew)
7. Validate structure consistency across all variants
8. Test on actual devices with different language settings
9. Document i18n patterns in frontend-specialist skill
✅ Acceptance Criteria
Language Coverage:
- All 14 languages have complete dashboard HTML
- All 9 dashboard sections present in every language
- Dashboard structure identical across all languages
- /dashboard/ directory has all 14 language variants
Translation Quality:
- All headings translated
- All chart labels localized
- All tooltips in native language
- All error messages translated
- Party names localized or explained
Cultural Formatting:
- Dates formatted per locale (not hardcoded)
- Numbers formatted with correct separators
- Time zones respected (CET for Sweden)
- Currency symbols correct (SEK)
RTL Support (Arabic, Hebrew):
-
dir="rtl"on<html>tag - Dashboard grid mirrored correctly
- Text alignment reversed
- Navigation breadcrumbs flow right-to-left
- Charts render correctly in RTL
SEO & Metadata:
- Hreflang tags on all pages (15 tags: 14 + x-default)
- Correct lang attribute on
<html>tag - Canonical URLs correct
- Open Graph locale tags present
Font Coverage:
- CJK fonts load for ja, ko, zh
- Arabic font loads for ar
- Hebrew font loads for he
- Font fallback chain complete
- No missing glyphs or �� characters
Validation:
- HTML validation passes for all 14 languages
- Link checker passes for all variants
- Translation validation script passes
- Structure consistency check passes
📚 References
Repository:
- Main: https://github.com/Hack23/riksdagsmonitor
- Language files: /index_??.html, /dashboard/index_??.html
- Translation scripts: /scripts/generate-language-variants.js
Translation Guides:
- Swedish: https://github.com/Hack23/homepage/blob/main/Swedish-Translation-Guide.md
- Finnish: https://github.com/Hack23/homepage/blob/main/Finnish-Translation-Guide.md
- Korean: https://github.com/Hack23/homepage/blob/main/Korean-Translation-Guide.md
- Spanish: https://github.com/Hack23/homepage/blob/main/Spanish-Translation-Guide.md
Homepage Alignment:
- CIA Features: https://hack23.com/cia-features.html
- CIA Docs: https://hack23.com/cia-docs.html
- All 14 languages available on homepage
Standards:
- i18n Best Practices: https://www.w3.org/International/
- Hreflang Guide: https://developers.google.com/search/docs/specialty/international/localized-versions
- RTL Design: https://rtlstyling.com/
ISMS Policy:
- Secure Development: https://github.com/Hack23/ISMS-PUBLIC/blob/main/Secure_Development_Policy.md
- Multi-Language Support: Required per accessibility policy
Architecture:
- Multi-Language: ARCHITECTURE.md § Internationalization
- Translation Status: MULTI_LANGUAGE_STATUS.md
🏷️ Labels
type:feature, priority:high, component:i18n, component:multi-language, component:ui-ux, agent:frontend-specialist, status:ready, dashboard-quality, seo
🔗 Related Issues
- Issue Dashboard Data Quality: Download and Integrate Missing CIA CSV Files #286: Dashboard Data Quality (CSV files) - parallel work
- Issue Dashboard Visualization: Fix Chart Rendering, Responsive Design, and Accessibility #287: Dashboard Visualization - DEPENDENCY (need working dashboards first)
- Translation validation issues (if any exist)
📈 Success Metrics
Before:
- Only English dashboards complete
- 13 languages missing or outdated
- No RTL support
- Missing hreflang tags
- Hardcoded English strings
After:
- 14/14 languages with complete dashboards
- Full RTL support for Arabic & Hebrew
- Complete hreflang SEO
- All text localized and culturally appropriate
- Proper font support for all scripts
Estimated Effort: 49 hours
Complexity: High
Priority: High (14-language support is core feature)
Dependencies: Issue #287 (visualization fixes should be done first)