Files
maternal-app/docs/LOCALIZATION_IMPLEMENTATION_PLAN.md
Andrei c1e37d30b0
Some checks failed
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled
feat: Implement frontend localization with i18n and measurement units
Implemented comprehensive frontend localization infrastructure supporting
5 languages (English, Spanish, French, Portuguese, Chinese) with measurement
unit preferences (Metric/Imperial). This lays the foundation for international
user support.

**Core Infrastructure:**
- Installed i18next, react-i18next, i18next-browser-languagedetector
- Created I18nProvider component integrated into app layout
- Configured i18next with language detection and localStorage persistence
- Created 35 translation files (5 languages × 7 namespaces)

**Translation Namespaces:**
- common: App-wide UI elements, navigation, actions
- tracking: Activity tracking (feeding, sleep, diaper, milestones)
- ai: AI assistant chat interface
- auth: Authentication flows (login, signup, password reset)
- settings: Settings and preferences
- onboarding: Onboarding flow
- errors: Error messages and validation

**Custom Hooks:**
- useTranslation: Type-safe translation wrapper
- useLocale: Language and measurement system management
- useFormatting: Date, time, number, and unit formatting

**Measurement Unit Support:**
- Created unit conversion utilities (weight, height, temperature, volume)
- Metric: kg, cm, °C, ml
- Imperial: lb, in, °F, oz
- Bidirectional conversion functions

**UI Components:**
- LanguageSelector: Dropdown to change app language
- MeasurementUnitSelector: Toggle between Metric/Imperial
- Integrated both into Settings page Preferences section

**Next Steps (Remaining):**
- Add measurement preferences to backend user schema
- Create onboarding flow with language/measurement selection
- Apply translations to existing components (dashboard, tracking forms)
- Implement multi-language AI responses
- Add professional translations (currently using basic translations)

**File Highlights:**
- lib/i18n/config.ts: i18next configuration
- hooks/useFormatting.ts: Formatting utilities with locale support
- lib/utils/unitConversion.ts: Unit conversion logic
- components/settings/*Selector.tsx: Language and measurement selectors
- locales/*/: Translation files for 5 languages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 10:52:38 +00:00

16 KiB

Localization Implementation Plan

Created: October 3, 2025 Priority: HIGH (Pre-Launch) Estimated Duration: 2-3 days

Overview

Implement comprehensive internationalization (i18n) support for the Maternal App with 5 languages and measurement unit preferences.

Supported Languages

  1. English (en-US) - Primary/Default
  2. Spanish (es-ES)
  3. French (fr-FR)
  4. Portuguese (pt-BR)
  5. Simplified Chinese (zh-CN)

Current Status

Already Completed

  • Backend multilanguage support for AI responses
  • AI safety responses in 5 languages
  • MultiLanguageService with language detection

To Be Implemented

  • Frontend i18next framework
  • Translation files for all UI strings
  • Language selector in onboarding
  • Language selector in settings
  • Date/time localization
  • Measurement unit preferences (Metric/Imperial)
  • Number formatting per locale

Phase 1: Framework Setup

1.1 Install Dependencies - latest versions only!

Files: package.json

npm install i18next react-i18next i18next-browser-languagedetector
npm install date-fns # Already installed, confirm locales

Packages:

  • i18next - Core i18n framework
  • react-i18next - React bindings
  • i18next-browser-languagedetector - Auto-detect user language

1.2 Create i18n Configuration

File: lib/i18n/config.ts (NEW)

  • Initialize i18next
  • Configure language detector
  • Set up fallback language (en-US)
  • Configure interpolation
  • Load translation resources

1.3 Create i18n Provider

File: components/providers/I18nProvider.tsx (NEW)

  • Wrap app with I18nextProvider
  • Initialize i18n on mount
  • Handle language loading states

1.4 Update Root Layout

File: app/layout.tsx (MODIFY)

  • Add I18nProvider to provider stack
  • Set html lang attribute dynamically

Phase 2: Translation Files Structure

2.1 Directory Structure

locales/
├── en/
│   ├── common.json          # Common UI strings (buttons, labels, etc.)
│   ├── auth.json            # Authentication pages
│   ├── dashboard.json       # Dashboard/home page
│   ├── tracking.json        # Activity tracking
│   ├── children.json        # Child management
│   ├── family.json          # Family management
│   ├── ai.json              # AI assistant
│   ├── analytics.json       # Analytics/insights
│   ├── settings.json        # Settings page
│   ├── onboarding.json      # Onboarding flow
│   ├── errors.json          # Error messages
│   └── validation.json      # Form validation messages
├── es/
│   └── [same structure]
├── fr/
│   └── [same structure]
├── pt/
│   └── [same structure]
└── zh/
    └── [same structure]

2.2 Translation Keys Structure

Example - common.json:

{
  "nav": {
    "dashboard": "Dashboard",
    "track": "Track",
    "children": "Children",
    "family": "Family",
    "ai": "AI Assistant",
    "analytics": "Analytics",
    "settings": "Settings"
  },
  "buttons": {
    "save": "Save",
    "cancel": "Cancel",
    "delete": "Delete",
    "edit": "Edit",
    "add": "Add",
    "submit": "Submit",
    "back": "Back",
    "next": "Next",
    "confirm": "Confirm"
  },
  "units": {
    "metric": "Metric",
    "imperial": "Imperial",
    "ml": "ml",
    "oz": "oz",
    "cm": "cm",
    "in": "in",
    "kg": "kg",
    "lb": "lb"
  }
}

Phase 3: Custom Hooks

3.1 useTranslation Hook

File: hooks/useTranslation.ts (NEW)

  • Re-export from react-i18next with type safety
  • Custom hook for easier usage

3.2 useLocale Hook

File: hooks/useLocale.ts (NEW)

  • Get current locale
  • Change locale
  • Get available locales
  • Get locale display name

3.3 useFormatting Hook

File: hooks/useFormatting.ts (NEW)

  • Format dates based on locale
  • Format numbers based on locale
  • Format currency based on locale
  • Format units based on preference

Phase 4: Measurement Unit Preference

4.1 Backend Schema Update

File: src/database/migrations/V0XX_add_measurement_preference.sql (NEW)

ALTER TABLE users ADD COLUMN measurement_unit VARCHAR(10) DEFAULT 'metric';
-- Values: 'metric' or 'imperial'

4.2 Update User Entity

File: src/database/entities/user.entity.ts (MODIFY)

Add field:

@Column({ name: 'measurement_unit', default: 'metric' })
measurementUnit: 'metric' | 'imperial';

4.3 Update User DTOs

Files:

  • src/modules/auth/dto/register.dto.ts (MODIFY)
  • src/modules/auth/dto/update-profile.dto.ts (MODIFY)

Add optional measurementUnit field.

4.4 API Endpoints

File: src/modules/auth/auth.controller.ts (MODIFY)

  • PATCH /api/v1/auth/profile - Include measurementUnit in update

Phase 5: Frontend User Preferences

5.1 Redux State

File: store/slices/userSlice.ts (MODIFY)

Add to user state:

interface UserState {
  // ... existing fields
  language: string;
  measurementUnit: 'metric' | 'imperial';
}

5.2 Language Selector Component

File: components/settings/LanguageSelector.tsx (NEW)

Features:

  • Dropdown with 5 language options
  • Flag icons for each language
  • Updates user preference on change
  • Persists to backend
  • Updates i18n instance

5.3 Measurement Unit Selector Component

File: components/settings/MeasurementUnitSelector.tsx (NEW)

Features:

  • Toggle or dropdown (Metric/Imperial)
  • Updates user preference on change
  • Persists to backend
  • Shows example conversions

Phase 6: Onboarding Flow Integration

6.1 Update Onboarding Page

File: app/(auth)/onboarding/page.tsx (MODIFY)

Add new steps:

  1. Language selection (Step 2)
  2. Measurement unit selection (Step 3)

6.2 Onboarding Language Step Component

File: components/onboarding/LanguageStep.tsx (NEW)

  • Large, visual language selector
  • Show language names in native script
  • Save to Redux state
  • Update i18n immediately

6.3 Onboarding Measurement Step Component

File: components/onboarding/MeasurementStep.tsx (NEW)

  • Visual metric/imperial selector
  • Show examples (ml vs oz, cm vs in)
  • Save to Redux state

6.4 Update Onboarding API Call

File: app/(auth)/onboarding/page.tsx (MODIFY)

Include language and measurementUnit in profile update call.


Phase 7: Settings Page Integration

7.1 Update Settings Page

File: app/settings/page.tsx (MODIFY)

Add new sections:

  • Language & Region section
    • Language selector
    • Measurement unit selector

7.2 Settings UI Components

Files:

  • components/settings/LanguageSettings.tsx (NEW)
  • components/settings/MeasurementSettings.tsx (NEW)

Phase 8: Unit Conversion Utilities

8.1 Conversion Utility

File: lib/units/conversions.ts (NEW)

Functions:

  • mlToOz(ml: number): number
  • ozToMl(oz: number): number
  • kgToLb(kg: number): number
  • lbToKg(lb: number): number
  • cmToIn(cm: number): number
  • inToCm(in: number): number

8.2 Format Unit Hook

File: hooks/useUnitFormat.ts (NEW)

  • Get user's measurement preference
  • Format value with correct unit
  • Convert between units
  • Display with locale-specific formatting

Phase 9: Apply Localization Throughout App

9.1 Update All Pages

Replace hardcoded strings with translation keys:

Priority Pages:

  1. Dashboard (app/page.tsx)

    • Nav items, headings, button labels
    • Activity type labels
    • Summary labels
  2. Authentication (app/(auth)/)

    • Login, Register, Forgot Password
    • Form labels, placeholders, errors
  3. Tracking (app/track/)

    • Feeding, Sleep, Diaper pages
    • Form labels, unit labels
    • Apply unit conversions
  4. Children (app/children/page.tsx)

    • Child management labels
    • Form fields
  5. Family (app/family/page.tsx)

    • Family management labels
  6. AI Assistant (app/ai-assistant/page.tsx)

    • Chat interface labels
    • Placeholder text
  7. Analytics (app/analytics/page.tsx)

    • Chart labels, insights
  8. Settings (app/settings/page.tsx)

    • All settings labels

9.2 Update Components

Replace hardcoded strings in shared components:

  • components/layouts/AppShell/ (navigation)
  • components/common/ (buttons, dialogs)
  • components/features/ (activity cards, etc.)

Phase 10: Date/Time Localization

10.1 Date Formatting Utility

File: lib/i18n/date-formats.ts (NEW)

Using date-fns with locales:

import { format } from 'date-fns';
import { enUS, es, fr, ptBR, zhCN } from 'date-fns/locale';

const locales = { en: enUS, es, fr, pt: ptBR, zh: zhCN };

export function formatDate(date: Date, formatStr: string, locale: string) {
  return format(date, formatStr, { locale: locales[locale] });
}

10.2 Update Date Displays

Apply locale-aware date formatting:

  • Activity timestamps
  • Child birth dates
  • Analytics date ranges

Phase 11: Number Localization

11.1 Number Formatting Utility

File: lib/i18n/number-formats.ts (NEW)

Using Intl.NumberFormat:

export function formatNumber(value: number, locale: string) {
  return new Intl.NumberFormat(locale).format(value);
}

export function formatDecimal(value: number, locale: string, decimals = 1) {
  return new Intl.NumberFormat(locale, {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(value);
}

11.2 Apply Number Formatting

  • Activity amounts (ml/oz)
  • Sleep duration (hours)
  • Weight/height measurements

Phase 12: Tracking Forms with Unit Preferences

12.1 Update Feeding Form

File: app/track/feeding/page.tsx (MODIFY)

  • Show ml or oz input based on preference
  • Convert to metric for API storage
  • Display in user's preferred unit

12.2 Update Child Profile Form

File: app/children/page.tsx (MODIFY)

  • Weight input (kg/lb)
  • Height input (cm/in)
  • Convert for API storage

12.3 Universal Input Component

File: components/forms/UnitInput.tsx (NEW)

Props:

  • type: 'volume' | 'weight' | 'height'
  • value: number
  • onChange: (value: number) => void
  • Auto-convert based on user preference

Phase 13: Translation Files Content

13.1 English Translations (Base)

Estimate: ~500-800 translation keys across all files

Create complete English translations for:

  • All UI strings
  • All form labels/placeholders
  • All error messages
  • All validation messages

13.2 Professional Translation

Recommendation: Use professional translation service for:

  • Spanish (es-ES)
  • French (fr-FR)
  • Portuguese (pt-BR)
  • Simplified Chinese (zh-CN)

Alternative: Use AI-assisted translation + native speaker review


Phase 14: Testing

14.1 Translation Coverage Test

  • Verify all strings are externalized
  • No hardcoded English strings remain
  • All translation keys exist in all languages

14.2 Language Switching Test

  • Switch between all 5 languages
  • Verify UI updates correctly
  • Verify no layout breaks

14.3 Unit Conversion Test

  • Test all conversions (ml↔oz, kg↔lb, cm↔in)
  • Verify correct rounding
  • Verify storage in consistent units (metric)

14.4 Date/Time Test

  • Verify dates display correctly per locale
  • Test all date formats (short, long, relative)

14.5 RTL Support (Future)

Note: Chinese doesn't require RTL, but document for future Arabic support


Phase 15: Documentation

15.1 Update Implementation Gaps

File: docs/implementation-gaps.md (MODIFY)

Mark localization as COMPLETED

15.2 Developer Guide

File: docs/LOCALIZATION_GUIDE.md (NEW)

Document:

  • How to add new translation keys
  • How to add new languages
  • Translation file structure
  • Best practices

15.3 Update User Documentation

Document language and measurement preferences in user guide


Implementation Order

Day 1: Framework & Structure

  1. Install dependencies
  2. Create i18n configuration
  3. Create i18n provider
  4. Create hooks (useTranslation, useLocale, useFormatting)
  5. Set up translation file structure
  6. Create English base translations (common, auth, dashboard)

Day 2: Preferences & Components

  1. Backend schema update for measurementUnit
  2. Update User entity and DTOs
  3. Create LanguageSelector component
  4. Create MeasurementUnitSelector component
  5. Update onboarding flow
  6. Update settings page
  7. Create unit conversion utilities

Day 3: Apply Throughout App

  1. Update all pages with translations
  2. Apply unit conversions to tracking forms
  3. Apply date/time localization
  4. Complete all English translations
  5. Test language switching
  6. Test unit conversions

Post-Implementation (Optional)

  1. Professional translation for other 4 languages
  2. Native speaker review
  3. Documentation updates

Key Files Checklist

New Files (27 total)

  • lib/i18n/config.ts
  • components/providers/I18nProvider.tsx
  • hooks/useLocale.ts
  • hooks/useFormatting.ts
  • hooks/useUnitFormat.ts
  • lib/units/conversions.ts
  • lib/i18n/date-formats.ts
  • lib/i18n/number-formats.ts
  • components/settings/LanguageSelector.tsx
  • components/settings/MeasurementUnitSelector.tsx
  • components/settings/LanguageSettings.tsx
  • components/settings/MeasurementSettings.tsx
  • components/onboarding/LanguageStep.tsx
  • components/onboarding/MeasurementStep.tsx
  • components/forms/UnitInput.tsx
  • locales/en/*.json (11 files)
  • locales/es/*.json (11 files - future)
  • locales/fr/*.json (11 files - future)
  • locales/pt/*.json (11 files - future)
  • locales/zh/*.json (11 files - future)
  • src/database/migrations/V0XX_add_measurement_preference.sql
  • docs/LOCALIZATION_GUIDE.md

Modified Files (15 total)

  • package.json
  • app/layout.tsx
  • store/slices/userSlice.ts
  • src/database/entities/user.entity.ts
  • src/modules/auth/dto/register.dto.ts
  • src/modules/auth/dto/update-profile.dto.ts
  • app/(auth)/onboarding/page.tsx
  • app/settings/page.tsx
  • app/page.tsx (dashboard)
  • app/track/feeding/page.tsx
  • app/track/sleep/page.tsx
  • app/track/diaper/page.tsx
  • app/children/page.tsx
  • app/family/page.tsx
  • docs/implementation-gaps.md

Success Criteria

Functionality

  • All 5 languages selectable and functional
  • Language preference persists across sessions
  • Measurement unit preference persists across sessions
  • All UI strings externalized (no hardcoded English)
  • Unit conversions work correctly (ml↔oz, kg↔lb, cm↔in)
  • Dates display correctly per locale
  • Numbers format correctly per locale

User Experience

  • Language can be selected in onboarding
  • Language can be changed in settings
  • Measurement unit can be selected in onboarding
  • Measurement unit can be changed in settings
  • UI updates immediately when language changes
  • No layout breaks when changing languages
  • Form inputs show correct units based on preference

Technical

  • All translation keys defined
  • No missing translation warnings
  • Type-safe translation usage (TypeScript)
  • Backend stores preferences correctly
  • Redux state syncs with backend

Notes

Translation Best Practices

  1. Use namespaces to organize translations
  2. Use interpolation for dynamic values: t('welcome', { name })
  3. Use pluralization: t('items', { count })
  4. Keep keys descriptive: auth.login.emailLabel not auth.e1
  5. Avoid concatenation, use complete sentences

Unit Conversion Strategy

  • Storage: Always store in metric (ml, kg, cm) in database
  • Display: Convert to user's preferred unit for display
  • Input: Accept user's preferred unit, convert to metric before API call
  • Consistency: Ensure all measurements use the same preference

Performance Considerations

  • Lazy load translation files per namespace
  • Cache translations in browser
  • Preload critical translations (common, errors)

Future Enhancements

  • Add more languages (Arabic, German, Hindi, etc.)
  • Add more units (temperature: °C/°F)
  • Add regional date formats (MM/DD vs DD/MM)
  • Add time format preferences (12h vs 24h)

Total Estimated Effort: 2-3 days Complexity: Medium Priority: HIGH (Pre-Launch) Dependencies: None (can start immediately)