Skip to content

Add sitewide header language selector with route-preserving locale switching - #236

Open
mimiflynn with Copilot wants to merge 30 commits into
mainfrom
copilot/create-implementation-plan-for-translation
Open

Add sitewide header language selector with route-preserving locale switching#236
mimiflynn with Copilot wants to merge 30 commits into
mainfrom
copilot/create-implementation-plan-for-translation

Conversation

Copilot AI commented May 22, 2026

Copy link
Copy Markdown
Contributor

This PR adds a sitewide language selector to the top navigation so users can switch locale from any page. Locale changes now keep users on the equivalent route instead of sending them to locale roots.

  • Header navigation: language selector

    • Adds a locale dropdown in header.jsx powered by SUPPORTED_LOCALES / LOCALE_NAMES.
    • Uses current locale from LocaleContext.
    • On selection change, navigates to a locale-adjusted path rather than a fixed landing page.
  • Locale routing: path rewrite helpers

    • Adds getLocaleSwitchPath(pathname, locale) in i18n/index.js for bidirectional locale switching across:
      • non-exercise routes (/about/fr-CA/about)
      • exercise routes (/exercises/en-US/python/E1//exercises/fr-CA/python/E1/)
      • exercise root behavior (/exercises//exercises/<locale>/)
    • Refines getLocalePath to preserve exercise subpaths when localizing paths.
  • Localization strings + UI styling

    • Adds nav.language label translations in strings.js for en-US, fr-CA, and pt-BR.
    • Adds header/mobile styles for selector layout and spacing in style.css and mobile.css.
  • Coverage updates

    • Extends i18n/index.spec.js with route-switching expectations for exercise and non-exercise paths, including default-locale edge behavior.
export function getLocaleSwitchPath(pathname, locale) {
  // preserves route structure while rewriting locale segment
  // e.g. /exercises/en-US/python/E1/ -> /exercises/fr-CA/python/E1/
}

Copilot AI changed the title feat: full site i18n for en-US, fr-CA, pt-BR Fix exercise template SSR locale resolution to unblock Gatsby static builds May 22, 2026
Copilot AI requested a review from mimiflynn May 22, 2026 19:43
Copilot AI changed the title Fix exercise template SSR locale resolution to unblock Gatsby static builds Add sitewide header language selector with route-preserving locale switching May 22, 2026
@mimiflynn
mimiflynn marked this pull request as ready for review May 22, 2026 20:33
@mimiflynn
mimiflynn requested review from Copilot and rmoriarty May 22, 2026 20:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a locale-aware i18n layer and exposes it via a sitewide header language selector that preserves the current route when switching languages.

Changes:

  • Introduces site/src/i18n helpers (getLocaleFromPath, getLocalePath, getLocaleSwitchPath) plus a LocaleContext provider/hook to supply locale + translated UI strings.
  • Updates header/nav and multiple components to use localized labels (exercise UI strings, footer message, summary card terms).
  • Adds locale-specific content pages (fr-CA, pt-BR), plus styling updates for the new selector and related layout.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
site/src/utils/language.js Defaults getCurrentLanguage locales from i18n constants.
site/src/templates/page.jsx Passes heroId from frontmatter into Hero.
site/src/templates/index.jsx Passes heroId from frontmatter into Hero.
site/src/templates/exercise.jsx Uses i18n strings for “Exercise” navigation labels.
site/src/styles/style.css Adds header layout styles for nav + language selector.
site/src/styles/mobile.css Adjusts header controls layout on mobile.
site/src/styles/global.css Reformatting + global style adjustments (also touches link selectors).
site/src/i18n/strings.spec.js Adds tests to validate per-locale string key consistency + fallback behavior.
site/src/i18n/strings.js Adds translated UI strings for nav/footer/exercise/summary cards.
site/src/i18n/LocaleContext.jsx Adds LocaleProvider/useLocale to expose locale + strings.
site/src/i18n/index.spec.js Adds tests for locale detection/path rewriting helpers.
site/src/i18n/index.js Implements locale constants, string lookup, and route rewrite helpers.
site/src/components/translations.jsx Displays human-friendly locale names in translations list.
site/src/components/summary-card.jsx Localizes SummaryCard term labels via LocaleContext.
site/src/components/site-map.jsx Localizes “Level” headings via LocaleContext.
site/src/components/layout.jsx Wraps app layout in LocaleProvider.
site/src/components/hero.jsx Supports stable heroId-based hero class naming.
site/src/components/header.jsx Adds locale dropdown and localized nav labels with route-preserving switching.
site/src/components/footer.jsx Localizes footer text via LocaleContext.
site/src/components/exercises.jsx Localizes exercise list labels via LocaleContext.
site/src/components/exercise-nav.jsx Localizes “Level” headings via LocaleContext.
site/content/pt-BR/teach.mdx Adds pt-BR localized Teach page content + heroId.
site/content/pt-BR/makerspace.mdx Adds pt-BR localized Makerspace page content + heroId.
site/content/pt-BR/continue.mdx Adds pt-BR localized Continue page content.
site/content/pt-BR/about.mdx Adds pt-BR localized About page content + heroId.
site/content/fr-CA/teach.mdx Adds fr-CA localized Teach page content + heroId.
site/content/fr-CA/makerspace.mdx Adds fr-CA localized Makerspace page content + heroId.
site/content/fr-CA/continue.mdx Adds fr-CA localized Continue page content.
site/content/fr-CA/about.mdx Adds fr-CA localized About page content + heroId.
site/content/exercises/pt-BR/index.mdx Adds heroId for pt-BR Learn index page.
site/content/exercises/fr-CA/index.mdx Adds heroId for fr-CA Learn index page.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread site/src/styles/global.css Outdated
Comment thread site/src/components/header.jsx
Comment thread site/src/components/header.jsx
Comment thread site/src/i18n/strings.js
Comment thread site/src/i18n/strings.js
Comment thread site/src/i18n/strings.js
Comment thread site/src/i18n/strings.spec.js Outdated
Comment thread site/src/i18n/strings.spec.js Outdated
mimiflynn and others added 2 commits June 12, 2026 13:50
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
mimiflynn and others added 17 commits August 5, 2026 11:16
… adjust package.json and package-lock.json accordingly
- Enhanced Translations component to navigate to the current page in different languages instead of always jumping to the top-level exercises page
- Added getTranslationPath utility to build translated URLs from the current pathname
- Integrated translation navigation into page templates (page.jsx, index.jsx) so it displays on all base-level pages
- Updated language utility tests to cover the new path-building logic
- Removed inline shortcode usage from exercises index page to use template-based rendering

This allows users to switch languages while staying on the same exercise category or base-level page.
- Add fr-CA/microbit/index.mdx with French translation of Micro:bit workshop
- Add pt-BR/microbit/index.mdx with Portuguese translation of Micro:bit workshop
- Add fr-CA/python/index.mdx with French translation of Python introduction page

These base-level category pages now support language switching via the Translations component.
- Updated /exercises/index.mdx to English-only content with consistent structure
- Updated /exercises/fr-CA/index.mdx with full French translations and localized links
- Updated /exercises/pt-BR/index.mdx with full Portuguese translations and localized links
- All three language versions now have complete curriculum listings with proper navigation links in their respective languages

This completes the translation work for all base-level pages including the main site index.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Created language-specific homepage content files (home.mdx) for en-US, fr-CA, and pt-BR
- Created new home.jsx template to render translated homepage with language-switching UI
- Updated gatsby-node.js to handle homepage page creation with proper language-based routing
- Updated language utility functions to handle homepage paths (/, /fr-CA/, /pt-BR/)
- Enhanced Translations component to work on all pages including homepage
- Added unit tests for homepage translation path logic
- Updated index.js homepage to include Translations component for language switching
- Homepage now accessible at:
  - / for English (default)
  - /fr-CA/ for French
  - /pt-BR/ for Portuguese

All changes tested and build verified successfully.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reorganized content directory for better clarity and consistency:

Before:
- Mixed language folders at different levels
- /content/home.mdx, /content/teach.mdx (English defaults at root)
- /content/exercises/en-US/, /exercises/fr-CA/, /exercises/pt-BR/
- /content/fr-CA/, /content/pt-BR/ (for non-exercise pages)

After:
- Consistent hierarchical structure with language as top-level folder
- /content/en-US/ (English: home.mdx, teach.mdx, makerspace.mdx, about.mdx, continue.mdx, exercises/)
- /content/fr-CA/ (French: home.mdx, teach.mdx, makerspace.mdx, about.mdx, continue.mdx, exercises/)
- /content/pt-BR/ (Portuguese: home.mdx, teach.mdx, makerspace.mdx, about.mdx, continue.mdx, exercises/)

Updated gatsby-node.js to:
- Extract language from file path during node creation
- Store language field for later use in page creation
- Normalize slugs: strip 'en-US/' prefix for English, keep language prefix for other languages
- Maintain correct page routing (/ for English, /fr-CA/ and /pt-BR/ for other languages)

All pages generated correctly with proper language routing. Build tested and verified.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- render Translations in base-level page and index templates
- update translation links to resolve from current pathname
- extend language path utility and tests for base-level routes
- remove inline translations markup from exercises index content

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- replace gatsby clean script with rimraf-based cache cleanup to avoid ENOTEMPTY failures
- override whatwg-url to 14.2.0 and tr46 to 5.1.1 to eliminate Node DEP0040 punycode warnings from node-fetch dependency chain
- update lockfile for dependency resolution changes

Verified:
- npm run build succeeds
- no DEP0040 warnings under NODE_OPTIONS=--trace-deprecation
- language utility tests pass

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- persist selected locale in localStorage via LocaleContext
- expose setLocalePreference in locale context and update it from top-nav selector
- make header logo locale-aware so home navigation stays in current language
- make home page and localized home template card links locale-aware
- add locale storage key and stored-locale helper in i18n utilities

Validated with:
- npm test -- --testPathPatterns='i18n|language'
- npm run build

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- remove top navigation language selector dropdown
- disable page-level translation links by rendering Translations component as null

Verified:
- npm test -- --testPathPatterns='i18n|language'
- npm run build

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep only the header language selector while other translation link UIs remain removed.

Verified:
- npm test -- --testPathPatterns='i18n|language'
- npm run build

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- delete Translations component
- remove Translations shortcode from MDX shortcode registry
- remove Translations imports/usages from page, index, and home templates and homepage

Verified:
- npm test -- --testPathPatterns='i18n|language'
- npm run build

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- add tests for getLocaleSegmentFromPath and getStoredLocale fallback/persistence
- add regression test ensuring Translations shortcode remains removed
- keep locale utility behavior and shortcode registry explicitly covered

Validation:
- npm test -- --testPathPatterns='i18n|language|mdx-shortcodes'
- npm test -- --coverage --collectCoverageFrom='src/i18n/index.js' --collectCoverageFrom='src/constants/mdx-shortcodes.js' --testPathPatterns='i18n|mdx-shortcodes'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- update locale path builders to target /{locale}/exercises/... for non-English locales
- handle both /exercises/... and /{locale}/exercises/... inputs when switching locale
- preserve exercise subpaths and trailing slash behavior
- update i18n tests to match current routed URL structure

Verified:
- npm test -- --testPathPatterns='i18n|language|mdx-shortcodes'
- npm run build

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- add README section covering supported locales and URL scheme
- document top-nav dropdown as the only language selector
- describe locale persistence key and per-locale content folder layout

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants