Text Localization #30

Merged
an.di merged 4 commits from adilallo/feature/TextLocalization into main 2026-01-31 01:42:21 +00:00
Owner

Implement Page-Specific Localization with Hybrid Content Management

Overview

This PR implements a comprehensive text localization and content management system that extracts all hardcoded UI strings into maintainable JSON files. The implementation follows a hybrid approach combining globalized, shared UI elements with context-aware, localized content pages—a recognized best practice for scalable i18n architectures.

Background: Previously, all UI text was hardcoded directly in components, making it difficult for content creators to update text without modifying code. This PR establishes a foundation for content management that allows non-technical contributors to edit UI text through JSON files.

Key Achievement: All user-facing text is now externalized and editable, with clear separation between page-specific content and reusable component defaults.

Changes

Core Infrastructure

  • Custom React Context Solution: Created MessagesContext with MessagesProvider and useTranslation() hook to replace next-intl (which had persistent configuration issues)
  • Server Component Support: Added getTranslation() helper for server-side message access
  • Type-Safe Translation Keys: Maintained TypeScript type safety throughout the translation system

Translation File Structure

  • Page-Specific Content (messages/en/pages/):
    • home.json - Home page content (heroBanner, numberedCards, featureGrid, askOrganizer, ruleStack)
    • learn.json - Learn page content (contentLockup, askOrganizer)
  • Component Defaults (messages/en/components/):
    • Updated to contain only shared defaults (aria-labels, alt texts, shared behavior text)
    • Files updated: heroBanner.json, askOrganizer.json, numberedCards.json, featureGrid.json, ruleStack.json
  • Message Index: Updated messages/en/index.ts to export page translations under pages namespace

Component Migrations

  • Home Page (app/page.tsx): Updated to use pages.home.* translation keys
  • Learn Page (app/learn/page.tsx): Migrated hardcoded strings to pages.learn.* keys
  • Client Components: Updated to use useTranslation() hook:
    • HeroBanner, NumberedCards, FeatureGrid, AskOrganizer, Footer
    • RuleStack, QuoteBlock, Header, HomeHeader, MenuBar, RuleCard
  • Component Updates: Components now source page-specific content from translation files while maintaining flexibility through props

Test Infrastructure

  • Test Utilities: Created tests/utils/test-utils.tsx with renderWithProviders() function
  • Test Suite Updates: Updated componentTestSuite to use custom render function
  • Test File Updates: Fixed all failing tests by wrapping components with MessagesProvider:
    • Component tests: Footer, Header, HeroBanner, FeatureGrid, AskOrganizer
    • Unit tests: NumberedCards, RuleStack, QuoteBlock, RuleCard
    • Page tests: home, page-flow, user-journey
  • All Tests Passing: 305 tests passed, 4 skipped (39 test files)

Documentation

  • Translation Workflow Guide: Updated docs/guides/i18n-translation-workflow.md with:
    • Hybrid approach architecture explanation
    • When to use pages/ vs components/ guidelines
    • Examples for adding new pages
    • Best practices for content creators and developers

Bug Fixes

  • Fixed TypeScript export error in app/components/Header/index.tsx (removed non-existent navigationItems export)

Screenshots

How to Test

  1. Run the development server:
    npm run dev
# Implement Page-Specific Localization with Hybrid Content Management ## Overview This PR implements a comprehensive text localization and content management system that extracts all hardcoded UI strings into maintainable JSON files. The implementation follows a hybrid approach combining globalized, shared UI elements with context-aware, localized content pages—a recognized best practice for scalable i18n architectures. **Background**: Previously, all UI text was hardcoded directly in components, making it difficult for content creators to update text without modifying code. This PR establishes a foundation for content management that allows non-technical contributors to edit UI text through JSON files. **Key Achievement**: All user-facing text is now externalized and editable, with clear separation between page-specific content and reusable component defaults. ## Changes ### Core Infrastructure - **Custom React Context Solution**: Created `MessagesContext` with `MessagesProvider` and `useTranslation()` hook to replace `next-intl` (which had persistent configuration issues) - **Server Component Support**: Added `getTranslation()` helper for server-side message access - **Type-Safe Translation Keys**: Maintained TypeScript type safety throughout the translation system ### Translation File Structure - **Page-Specific Content** (`messages/en/pages/`): - `home.json` - Home page content (heroBanner, numberedCards, featureGrid, askOrganizer, ruleStack) - `learn.json` - Learn page content (contentLockup, askOrganizer) - **Component Defaults** (`messages/en/components/`): - Updated to contain only shared defaults (aria-labels, alt texts, shared behavior text) - Files updated: `heroBanner.json`, `askOrganizer.json`, `numberedCards.json`, `featureGrid.json`, `ruleStack.json` - **Message Index**: Updated `messages/en/index.ts` to export page translations under `pages` namespace ### Component Migrations - **Home Page** (`app/page.tsx`): Updated to use `pages.home.*` translation keys - **Learn Page** (`app/learn/page.tsx`): Migrated hardcoded strings to `pages.learn.*` keys - **Client Components**: Updated to use `useTranslation()` hook: - `HeroBanner`, `NumberedCards`, `FeatureGrid`, `AskOrganizer`, `Footer` - `RuleStack`, `QuoteBlock`, `Header`, `HomeHeader`, `MenuBar`, `RuleCard` - **Component Updates**: Components now source page-specific content from translation files while maintaining flexibility through props ### Test Infrastructure - **Test Utilities**: Created `tests/utils/test-utils.tsx` with `renderWithProviders()` function - **Test Suite Updates**: Updated `componentTestSuite` to use custom render function - **Test File Updates**: Fixed all failing tests by wrapping components with `MessagesProvider`: - Component tests: Footer, Header, HeroBanner, FeatureGrid, AskOrganizer - Unit tests: NumberedCards, RuleStack, QuoteBlock, RuleCard - Page tests: home, page-flow, user-journey - **All Tests Passing**: 305 tests passed, 4 skipped (39 test files) ### Documentation - **Translation Workflow Guide**: Updated `docs/guides/i18n-translation-workflow.md` with: - Hybrid approach architecture explanation - When to use `pages/` vs `components/` guidelines - Examples for adding new pages - Best practices for content creators and developers ### Bug Fixes - Fixed TypeScript export error in `app/components/Header/index.tsx` (removed non-existent `navigationItems` export) ## Screenshots <!-- No visual changes - this is a content management infrastructure change --> ## How to Test 1. **Run the development server**: npm run dev
an.di self-assigned this 2026-01-31 01:42:07 +00:00
an.di added 4 commits 2026-01-31 01:42:08 +00:00
an.di merged commit 3fb5a389c7 into main 2026-01-31 01:42:21 +00:00
an.di deleted branch adilallo/feature/TextLocalization 2026-01-31 01:42:22 +00:00
an.di changed title from adilallo/feature/TextLocalization to Text Localization 2026-02-02 18:47:03 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: CommunityRule/community-rule#30