# Footer i18n Translation Failure - Technical Diagnostic Brief

**Date**: 2025-10-22
**Issue**: Footer displays raw translation keys instead of translated text on /researcher.html and /leader.html
**Status**: BLOCKING - Prevents deployment
**Affected Pages**: /researcher.html, /leader.html
**Working Pages**: /index.html, /implementer.html

---

## Problem Statement

Footer component renders correctly but translations fail to apply. Elements display raw keys like `footer.about_heading` instead of "Tractatus Framework".

**Console Output Shows:**
```
[Footer] Applying translations...
[Footer] Footer exists: true
[Footer] Elements with data-i18n: 20
[Footer] Translations applied
[Footer] about_heading element text: footer.about_heading  ← PROBLEM
```

**Expected**: `about_heading element text: Tractatus Framework`

---

## System Architecture

### Translation System
- **Library**: Custom i18n implementation (`/public/js/i18n-simple.js`)
- **Translation files**: `/public/locales/en/common.json`, `/public/locales/en/researcher.json`
- **Loading strategy**: Async fetch → shallow merge
- **Application method**: `window.I18n.applyTranslations()` replaces `innerHTML` of `[data-i18n]` elements

### Footer Component
- **File**: `/public/js/components/footer.js`
- **Type**: Dynamically inserted component (not in static HTML)
- **Initialization**: Event-based (waits for `i18nInitialized` event)
- **Cache version**: `?v=1761129862`

---

## Diagnostic Evidence

### 1. Translation Data Verified on Server
```bash
$ curl -s http://localhost:9000/locales/en/common.json | jq '.footer.about_heading'
"Tractatus Framework"  ✓ CORRECT

$ curl -s http://localhost:9000/locales/en/researcher.json | jq 'has("footer")'
false  ✓ CORRECT (footer removed to prevent overwrite)
```

### 2. Footer Rendering Confirmed
```javascript
[Footer] Footer exists: true
[Footer] Elements with data-i18n: 20
```
Footer HTML is in DOM with proper `data-i18n` attributes.

### 3. Translation Application Called
```javascript
[Footer] Translations applied
```
`window.I18n.applyTranslations()` executes without errors.

### 4. Translation Fails
```javascript
[Footer] about_heading element text: footer.about_heading
```
After `applyTranslations()`, element still contains raw key.

---

## Root Cause Hypothesis

**`window.I18n.t('footer.about_heading')` is returning the key instead of the translation.**

### i18n.t() Implementation
```javascript
// /public/js/i18n-simple.js:123-136
t(key) {
  const keys = key.split('.');
  let value = this.translations;

  for (const k of keys) {
    if (value && typeof value === 'object') {
      value = value[k];
    } else {
      return key; // Return key if translation not found
    }
  }

  return value || key;
}
```

**Possible failures:**
1. `this.translations` doesn't have `footer` key
2. `this.translations.footer` doesn't have `about_heading` key
3. Value is not a string (e.g., still an object)
4. Timing issue - translations not yet loaded when `applyTranslations()` called

---

## Critical Question

**What does `window.I18n.translations` contain when footer renders?**

### Diagnostic Step Required

**In browser console, run:**
```javascript
console.log('Full translations:', window.I18n.translations);
console.log('Footer object:', window.I18n.translations.footer);
console.log('about_heading:', window.I18n.translations.footer?.about_heading);
console.log('Test t():', window.I18n.t('footer.about_heading'));
```

**Expected output:**
```javascript
Full translations: {footer: {...}, page: {...}, header: {...}, sections: {...}}
Footer object: {about_heading: "Tractatus Framework", ...}
about_heading: "Tractatus Framework"
Test t(): "Tractatus Framework"
```

**If output differs**, this reveals where the data structure breaks.

---

## Working vs Broken Comparison

### Working Pages (index.html, implementer.html)
- **Script order**: `i18n-simple.js` → `language-selector.js` → `scroll-animations.js` → `page-transitions.js` → `footer.js`
- **Footer in page-specific JSON**: NO
- **Result**: Footer displays correctly

### Broken Pages (researcher.html, leader.html)
- **Script order**: `i18n-simple.js` → `language-selector.js` → `scroll-animations.js` → `page-transitions.js` → `version-manager.js` → `researcher-page.js` → `footer.js`
- **Footer in page-specific JSON**: Removed (was causing shallow merge issue)
- **Result**: Footer displays raw keys

**Key difference**: Extra scripts (`version-manager.js`, `researcher-page.js`) load between i18n and footer.

---

## Previous Fixes Attempted

### Fix 1: Consolidated footer translations (v1.1.8)
**Problem**: researcher.json and leader.json had partial `footer` objects that overwrote common.json footer during shallow merge.
**Action**: Moved all footer keys to common.json, removed from page-specific files.
**Result**: Data structure fixed on server, but translations still not applied.

### Fix 2: Event-based initialization (v1.1.9)
**Problem**: Race condition - footer rendering before i18n loaded.
**Action**: Wait for `i18nInitialized` event before rendering.
**Result**: Timing fixed (console confirms footer waits for i18n), but translations still fail.

### Fix 3: Removed polling (v1.2.0)
**Problem**: Polling logic triggered rate limiting (100 req/15min).
**Action**: Simplified to single event-based check.
**Result**: Rate limiting resolved, but core translation issue persists.

---

## Next Debugging Steps

### Step 1: Inspect Browser Runtime State
```javascript
// In browser console on /researcher.html after page load:
window.I18n.translations
window.I18n.t('footer.about_heading')
document.querySelector('footer [data-i18n="footer.about_heading"]').innerHTML
```

### Step 2: Compare Working Page
```javascript
// In browser console on /index.html after page load:
window.I18n.translations
window.I18n.t('footer.about_heading')
document.querySelector('footer [data-i18n="footer.about_heading"]').innerHTML
```

### Step 3: Check Translation Merge
```javascript
// Does researcher.json override common.json at runtime?
// Expected: common.json footer + researcher.json sections
// Actual: ???
```

---

## Potential Solutions

### Solution A: Deep Merge Instead of Shallow Merge
**Current code** (`i18n-simple.js:111`):
```javascript
this.translations = { ...commonTranslations, ...pageTranslations };
```

**Problem**: Shallow merge overwrites entire top-level objects.

**Fix**: Deep merge utility
```javascript
this.translations = deepMerge(commonTranslations, pageTranslations);

function deepMerge(target, source) {
  const output = { ...target };
  for (const key in source) {
    if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
      output[key] = deepMerge(target[key] || {}, source[key]);
    } else {
      output[key] = source[key];
    }
  }
  return output;
}
```

### Solution B: Namespace Separation
**Keep footer translations ONLY in common.json**
**Never put footer keys in page-specific files**
**Status**: Already implemented, but verify runtime state

### Solution C: Manual Footer Translation
**Instead of relying on global `applyTranslations()`:**
```javascript
applyFooterTranslations() {
  const footerElements = document.querySelectorAll('footer [data-i18n]');
  footerElements.forEach(el => {
    const key = el.dataset.i18n;
    const translation = window.I18n.t(key);
    console.log(`Translating ${key} -> ${translation}`);
    el.innerHTML = translation;
  });
}
```

---

## File Locations

### Translation Files
- `/public/locales/en/common.json` - Contains full footer object
- `/public/locales/en/researcher.json` - No footer object (removed)
- `/public/locales/en/leader.json` - No footer object (removed)

### JavaScript Files
- `/public/js/i18n-simple.js` - Translation system core
- `/public/js/components/footer.js` - Footer component
- `/public/researcher.html:627` - Footer script tag with cache version
- `/public/leader.html:611` - Footer script tag with cache version

### Server Configuration
- `/src/server.js:77` - Rate limiting middleware (100 req/15min)
- `/src/middleware/rate-limit.middleware.js` - Rate limiter implementation

---

## Success Criteria

**Footer displays:**
```
Tractatus Framework  (not footer.about_heading)
Documentation  (not footer.documentation_heading)
Framework Docs  (not footer.documentation_links.framework_docs)
...etc
```

**Console shows:**
```
[Footer] about_heading element text: Tractatus Framework
```

---

## Contact for Clarification

**Project Owner**: Review console output from browser
**Required**: Share `window.I18n.translations` object from browser console
**This will immediately reveal** if the problem is:
- Data not loaded (translations object missing footer)
- Data structure wrong (footer exists but wrong shape)
- Translation function broken (t() not navigating object correctly)
- Application timing (translations loaded but not applied)

---

**Priority**: HIGH - Blocking deployment
**Estimated Debug Time**: 15-30 minutes with browser console access
**Complexity**: LOW - Simple data flow issue, just need to see runtime state
