Skip to main content
Glama
northernvariables

FedMCP - Federal Parliamentary Information

BILINGUAL_IMPLEMENTATION_STATUS.mdβ€’10.2 kB
# Bilingual Implementation Status (English/Quebec French) **Last Updated:** 2025-11-07 **Progress:** ~60% Complete ## Overview Comprehensive bilingualization of FedMCP frontend using `next-intl` with `/en/` and `/fr/` URL structure, browser auto-detection, and AI-generated Quebec French translations. --- ## βœ… COMPLETED (Phases 1-3) ### Phase 1: Core Infrastructure βœ… **1. Dependencies & Configuration** - βœ… Installed `next-intl` (v4.4.0) and `date-fns` (v3.6.0) - βœ… Created i18n config (`src/i18n/config.ts`) with EN/FR locales - βœ… Created request handler (`src/i18n/request.ts`) - βœ… Updated `next.config.mjs` with next-intl plugin **2. Middleware & Routing** - βœ… Updated middleware to combine i18n + authentication - βœ… Configured locale detection from Accept-Language header - βœ… Set up `/en/` and `/fr/` URL prefixes with `localePrefix: 'always'` - βœ… Created locale-aware navigation utilities (`src/i18n/navigation.ts`) **3. App Directory Restructuring** - βœ… Created `[locale]` folder structure - βœ… Moved all routes under `/app/[locale]/` - βœ… Updated root layout to handle locale parameter - βœ… Implemented `generateStaticParams()` for both locales ### Phase 2: Translation System βœ… **4. Translation Files** - βœ… Created `messages/en.json` (555+ strings organized by namespace) - βœ… Created `messages/fr.json` (complete Quebec French translations) - βœ… Organized by namespaces: `metadata`, `common`, `nav`, `footer`, `home`, `mps`, `bills`, `bill`, `hansard`, `chamber`, `committees`, `lobbying`, `spending`, `chat`, `parties`, `provinces`, `errors` **5. Core Components** - βœ… Created `LanguageSwitcher` component (EN/FR toggle in header) - βœ… Translated `Header` component with i18n navigation - βœ… Translated `Footer` component with bilingual links - βœ… Updated locale-specific layout with metadata generation ### Phase 3: GraphQL & Data Layer βœ… **6. GraphQL Query Updates** - βœ… Updated `BILL_BASIC_FRAGMENT` to fetch all `_fr` fields: - `title_fr`, `summary_fr`, `status_fr`, `bill_type_fr`, `originating_chamber_fr` - βœ… Updated `STATEMENT_FRAGMENT` to fetch all `_fr` fields: - `who_fr`, `content_fr`, `h1_fr`, `h2_fr`, `h3_fr` - βœ… Both fragments now return bilingual data for automatic selection **7. Bilingual Hooks** Created comprehensive hooks in `src/hooks/useBilingual.ts`: - βœ… `useBilingualField(enField, frField)` - Select field based on locale - βœ… `useBilingualContent(content)` - Transform objects with `_en/_fr` suffixes - βœ… `useLocaleSuffix()` - Get `_en` or `_fr` for dynamic queries - βœ… `usePartyName(partyCode)` - Localized party name mapping - βœ… `useChamberName(chamber)` - Localized chamber names **8. Pages Translated** - βœ… **Landing Page** (`app/[locale]/page.tsx`): - Hero section, features, stats, CTA - all fully bilingual - Uses `useTranslations('home')` hook - Locale-aware Link components --- ## 🚧 IN PROGRESS / REMAINING WORK ### Phase 4-6: Page & Component Translation (50% Remaining) **Pages to Translate:** - πŸ”² MPs page (`app/[locale]/mps/page.tsx`) - πŸ”² Bills page (`app/[locale]/bills/page.tsx`) - πŸ”² Bill detail page (`app/[locale]/bills/[session]/[number]/page.tsx`) - πŸ”² Hansard search page (`app/[locale]/hansard/page.tsx`) - πŸ”² Chamber page (`app/[locale]/chamber/page.tsx`) - πŸ”² Committees page (`app/[locale]/committees/page.tsx`) - πŸ”² Dashboard page - πŸ”² MP profile pages - πŸ”² Lobbying page - πŸ”² Spending page - πŸ”² About page - πŸ”² Forum pages (if applicable) **Shared Components to Translate:** - πŸ”² `MPCard` component - πŸ”² `BillCard` component - πŸ”² `SearchBar` component - πŸ”² Filter components (party, province, status dropdowns) - πŸ”² `ChatWidget` component - πŸ”² Modal components (MPModal, etc.) - πŸ”² Empty state components - πŸ”² Error boundary components - πŸ”² Loading components ### Phase 7: Data Display Logic - πŸ”² Update all components using bills to use `useBilingualContent()` - πŸ”² Update all components using Hansard to use bilingual fields - πŸ”² Update date formatting with French locale from `date-fns` - πŸ”² Update number formatting (Quebec uses space as thousands separator) - πŸ”² Ensure party names use `usePartyName()` hook - πŸ”² Ensure chamber names use `useChamberName()` hook ### Phase 8: Hansard Search Language Parameter - πŸ”² Update Hansard search page to pass `language` param based on current locale - πŸ”² Currently hardcoded to `'en'` in `hansard/page.tsx:72` - πŸ”² Should use: `const locale = useLocale(); language: locale` ### Phase 9: SEO & Metadata - πŸ”² Add `<link rel="alternate" hreflang="en" />` and `hreflang="fr"` tags - πŸ”² Generate bilingual sitemap with /en/ and /fr/ URLs - πŸ”² Add Open Graph locale tags (`og:locale`, `og:locale:alternate`) - πŸ”² Test locale detection across browsers - πŸ”² Verify metadata is correctly set per locale ### Phase 10: Testing & QA - πŸ”² Test all routes in both /en/ and /fr/ - πŸ”² Test language switcher preserves current page/filters - πŸ”² Verify bilingual data displays correctly (bills, Hansard) - πŸ”² Test fallback behavior (French data missing β†’ shows English) - πŸ”² Cross-browser testing for locale detection - πŸ”² Performance check (ensure translation files don't bloat bundle) - πŸ”² Accessibility testing (lang attribute updates, screen readers) --- ## πŸ“ Key Files Modified/Created ### Created Files: - `/src/i18n/config.ts` - Locale configuration - `/src/i18n/request.ts` - Request handler for next-intl - `/src/i18n/navigation.ts` - Locale-aware navigation utilities - `/src/hooks/useBilingual.ts` - Bilingual data selection hooks - `/src/components/LanguageSwitcher.tsx` - Language toggle component - `/messages/en.json` - English translations (555+ strings) - `/messages/fr.json` - Quebec French translations (555+ strings) - `/migrate-to-locale.sh` - Migration script (can be deleted) ### Modified Files: - `/src/middleware.ts` - Combined i18n + auth middleware - `/next.config.mjs` - Added next-intl plugin - `/src/app/[locale]/layout.tsx` - Locale-aware layout - `/src/components/Header.tsx` - Translated with i18n - `/src/components/Footer.tsx` - Translated with i18n - `/src/lib/queries.ts` - Updated fragments for bilingual fields - `/src/app/[locale]/page.tsx` - Translated landing page ### App Directory Structure: ``` src/app/ β”œβ”€β”€ api/ (unchanged, not localized) └── [locale]/ β”œβ”€β”€ layout.tsx (locale-aware) β”œβ”€β”€ page.tsx (landing page - βœ… translated) β”œβ”€β”€ mps/ β”œβ”€β”€ bills/ β”œβ”€β”€ hansard/ β”œβ”€β”€ chamber/ β”œβ”€β”€ committees/ β”œβ”€β”€ dashboard/ β”œβ”€β”€ lobbying/ β”œβ”€β”€ spending/ β”œβ”€β”€ about/ β”œβ”€β”€ profile/ β”œβ”€β”€ account/ β”œβ”€β”€ auth/ └── forum/ ``` --- ## πŸ” How to Use Bilingual Features ### For Developers: **1. Using translations in components:** ```tsx 'use client'; import { useTranslations } from 'next-intl'; export function MyComponent() { const t = useTranslations('namespace'); return <h1>{t('key')}</h1>; } ``` **2. Using bilingual data from GraphQL:** ```tsx import { useBilingualContent } from '@/hooks/useBilingual'; const bill = { title_en: "Act", title_fr: "Loi", ... }; const { title } = useBilingualContent(bill); // Auto-selects based on current locale ``` **3. Using locale-aware navigation:** ```tsx import { Link } from '@/i18n/navigation'; <Link href="/bills">Bills</Link> // Automatically generates /en/bills or /fr/bills ``` **4. Party name localization:** ```tsx import { usePartyName } from '@/hooks/useBilingual'; const partyName = usePartyName('Conservative'); // Returns "Conservative" in EN, "Conservateur" in FR ``` ### For Users: - Visit `/en/` for English or `/fr/` for French - Use the **EN / FR** toggle in the header to switch languages - Browser language auto-detection on first visit - Language preference persists across pages --- ## 🎯 Estimated Remaining Work **Time Estimate:** 10-15 hours **Breakdown:** - Pages translation: 5-7 hours (10 pages Γ— 30-40 min each) - Component translation: 3-4 hours (20+ components) - Data display logic: 1-2 hours - SEO & metadata: 1 hour - Testing & QA: 2-3 hours **Priority Order:** 1. **High Priority:** MPs page, Bills page, Hansard page (most-used features) 2. **Medium Priority:** Bill detail page, Chamber page, shared components 3. **Low Priority:** Lobbying, Spending, Forum pages, SEO optimization --- ## ✨ Key Features Implemented βœ… **Full URL Localization:** `/en/bills` and `/fr/bills` βœ… **Auto-Detection:** Uses Accept-Language header βœ… **Language Switcher:** Prominent EN/FR toggle in header βœ… **Bilingual Data:** GraphQL queries fetch both _en and _fr fields βœ… **Smart Fallbacks:** Falls back to English if French missing βœ… **Party Translation:** Automatic party name localization βœ… **Type-Safe Routing:** Locale-aware Link and useRouter βœ… **SSR Compatible:** Works with Next.js 15 server components --- ## πŸ› Known Issues / Notes 1. **Hansard Language Parameter:** Currently hardcoded to 'en' - needs to be dynamic 2. **MP/Committee Names:** Not bilingual in data (only in Canada's official records) 3. **Date Formatting:** Need to add French locale support from date-fns 4. **Number Formatting:** Quebec uses spaces (e.g., "1 000 000" not "1,000,000") --- ## πŸ“š Resources - [next-intl Documentation](https://next-intl-docs.vercel.app/) - [Quebec French Translation Guidelines](https://www.oqlf.gouv.qc.ca/) - [Federal Government Bilingual Guidelines](https://www.noslangues-ourlanguages.gc.ca/) --- ## πŸš€ Next Steps To continue implementation, the recommended order is: 1. **Translate MPs page** - High traffic, straightforward 2. **Translate Bills page** - Core functionality 3. **Translate shared components** (MPCard, BillCard) - Used everywhere 4. **Translate Hansard search** - Critical feature 5. **Update data display logic** - Apply bilingual hooks 6. **Test and QA** - Ensure everything works 7. **SEO optimization** - hreflang tags and sitemaps Run `pnpm dev` and visit `http://localhost:3000/en` or `http://localhost:3000/fr` to see the bilingual site!

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/northernvariables/FedMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server