Skip to content

feat(client): upgrades i18next to v25.5.2, turns on type-checking#61970

Closed
ahrjarrett wants to merge 22 commits into
freeCodeCamp:mainfrom
ahrjarrett:typesafe-i18n
Closed

feat(client): upgrades i18next to v25.5.2, turns on type-checking#61970
ahrjarrett wants to merge 22 commits into
freeCodeCamp:mainfrom
ahrjarrett:typesafe-i18n

Conversation

@ahrjarrett

@ahrjarrett ahrjarrett commented Aug 28, 2025

Copy link
Copy Markdown
Contributor

Closes #61818
Closes #60543
Closes #49621
Supersedes #61820
Fast-follow: #61969

Intro

i18next@25.4.2 has been released, and includes a new feature that allows freeCodeCamp to turn on type-checking for all translations.

This PR performs that migration.

To prevent merge conflicts and to avoid having to make decisions that I don't have the context to make on my own, I created a fast-follow ticket (#61969) as a catch-all for all the places where type-checking did not work because certain translations were missing.

Where that was necessary, I added the following comment:

// TODO: convert to selector #61969

That way whoever picks up #61969 could grep the codebase to find all the TODOs related to that piece of work.

Demo

To make the change easier to understand, I created a quick demo showing a before and after.

freeCodeCamp-4

Before

  • User needs to know where the translations are located on the file system
  • User needs to navigate to the correct translation file
  • User needs to sift through the translations to find the one they're looking for
  • User needs to write the selector key by hand, which is error prone

Impact

This makes the system more difficult to change without accidentally introducing bugs.

For example, if the path icons.avatar changes, the user needs to remember to grep icons.avatar to find all the places where its referenced, or risk breaking the translation

After

  • User does not need to know where translations are located on the file system to use a translation
  • User doesn't need to leave the call site to find the correct translation
  • User can explore the translations one-level at a time
  • User can use auto-completion to find the correct translation
  • User can jump to the translation in question, if they need to see the source

Impact

This makes the system easier to change, because if the location of a translation changes, the user will get a type error when running pnpm lint:ts.

It also reduces the ramp-up time for new users who want to contribute. They don't (necessarily) need to know where translations are located to use a translation. This makes the process of translating freeCodeCamp into different languages more accessible overall.

Let me know if I can answer any questions about the change, and of course please don't hesitate to share any feedback about the change you might have.

Checklist:

@github-actions github-actions Bot added the platform: learn UI side of the client application that needs familiarity with React, Gatsby etc. label Aug 28, 2025
@socket-security

socket-security Bot commented Aug 28, 2025

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​types/​jsonwebtoken@​9.0.51001007381100

View full report

@socket-security

socket-security Bot commented Aug 28, 2025

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

@ahrjarrett ahrjarrett marked this pull request as ready for review August 28, 2025 01:38
@ahrjarrett ahrjarrett requested a review from a team August 28, 2025 01:38
@huyenltnguyen

Copy link
Copy Markdown
Member

Hi @ahrjarrett, we appreciate your great work here ❤️

We're juggling quite a few things at the moment, so it might take us a little while to review this PR thoroughly. But really excited for this feature - it's going to be a big boost to the DX!

To prevent merge conflicts and to avoid having to make decisions that I don't have the context to make on my own, I created a fast-follow ticket

Thanks for creating the issue to track those. We will take a look and work through them.

@ahrjarrett

Copy link
Copy Markdown
Contributor Author

Hi @ahrjarrett, we appreciate your great work here ❤️

We're juggling quite a few things at the moment, so it might take us a little while to review this PR thoroughly. But really excited for this feature - it's going to be a big boost to the DX!

To prevent merge conflicts and to avoid having to make decisions that I don't have the context to make on my own, I created a fast-follow ticket

Thanks for creating the issue to track those. We will take a look and work through them.

Sounds good! Let me know when you're ready to start reviewing so I can pull, migrate the i18n work that's been done in the meantime, merge, push. That way the team only has to review it once :)

@raisedadead raisedadead added the status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. label Aug 30, 2025
@camper-chan

camper-chan Bot commented Sep 2, 2025

Copy link
Copy Markdown

We would love to be able to merge your changes but it looks like there is an error with the CI build. ⚠️

Once you resolve these issues, we will be able to review your PR and merge it. 😊


Feel free to reference the contributing guidelines for instructions on running the CI build locally. ✅

@huyenltnguyen

Copy link
Copy Markdown
Member

Hi @ahrjarrett 👋

Just a quick update: we've got a high-priority PR (#61906) coming in with a bunch of new translation strings. I think it makes sense to wait for that to be merged before bringing this one in.

Once #61906 is merged, what workflow would you recommend for handling the update? Should I merge main into this PR and manually update the places that use the new strings, or do you have a magic command for that? 😄 (Asking so we can handle the update without having to pull you back in again.)

@ahrjarrett

Copy link
Copy Markdown
Contributor Author

Hi @ahrjarrett 👋

Just a quick update: we've got a high-priority PR (#61906) coming in with a bunch of new translation strings. I think it makes sense to wait for that to be merged before bringing this one in.

Once #61906 is merged, what workflow would you recommend for handling the update? Should I merge main into this PR and manually update the places that use the new strings, or do you have a magic command for that? 😄 (Asking so we can handle the update without having to pull you back in again.)

There is a codemod, but you probably won't want to use it in this case because it will "undo" all of the places where I left the string-based selector in tact.

Probably the easiest path forward if you'd like to move forward on your own is to:

  1. pull my branch and run the tests / run the app to do a quick spot check, that way you know you're starting with a working application
  2. merge main into this branch
  3. run pnpm lint:ts to do type-checking
  4. go to each of the TypeErrors
  5. for each TypeError, either migrate to the selector API by hand, or cast the string as never and add the comment above it:
// TODO: convert to selector #61969

That way you keep the risk of making a mistake low, start enjoying the benefit of having strongly typed translations now, and handle the actual migration when it's convenient / makes sense for your roadmap.

Let me know if you need a hand while you do this! Large migrations like this can be tricky as I'm sure you're aware, so sometimes having an extra set of 👀 can be helpful :)

Excited to get this working for the team!

@ahrjarrett ahrjarrett changed the title i18n: upgrades i18next to v25.4.2, turns on type-checking i18n: upgrades i18next to v25.5.2, turns on type-checking Sep 6, 2025
@majestic-owl448 majestic-owl448 added the MERGE CONFLICT! To be applied to PR's that have a merge conflict and need updating label Sep 15, 2025
@camper-chan

This comment was marked as off-topic.

@huyenltnguyen

Copy link
Copy Markdown
Member

Let's hold off on updating this PR (because there will be more merge conflicts). We'll get the blocking PRs in first, and I'll help resolve the conflicts.

@huyenltnguyen huyenltnguyen added the status: blocked In a transient & temporary hold. label Sep 19, 2025
@raisedadead raisedadead removed the MERGE CONFLICT! To be applied to PR's that have a merge conflict and need updating label Sep 26, 2025
@raisedadead raisedadead removed the status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. label Sep 26, 2025
@majestic-owl448 majestic-owl448 added the MERGE CONFLICT! To be applied to PR's that have a merge conflict and need updating label Oct 3, 2025
@Sembauke Sembauke requested review from a team as code owners March 16, 2026 13:45
@github-actions github-actions Bot added the scope: i18n language translation/internationalization. Often combined with language type label label Mar 16, 2026
@huyenltnguyen huyenltnguyen changed the title i18n: upgrades i18next to v25.5.2, turns on type-checking feat(client): upgrades i18next to v25.5.2, turns on type-checking Mar 16, 2026
@huyenltnguyen huyenltnguyen removed status: blocked In a transient & temporary hold. MERGE CONFLICT! To be applied to PR's that have a merge conflict and need updating labels Mar 16, 2026
@huyenltnguyen huyenltnguyen requested a review from Copilot March 16, 2026 18:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Upgrades the client’s i18n setup to i18next v25.5.2 and migrates translation usage to selector-based keys to enable TypeScript type-checking/autocomplete across translations.

Changes:

  • Bump i18next and configure CustomTypeOptions resources + selector support.
  • Migrate many t('key.path') calls to t($ => $.key.path) (and add a few runtime helpers for dynamic keys).
  • Update unit tests/mocks to support selector-based translation keys.

Reviewed changes

Copilot reviewed 198 out of 200 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
client/utils/tags.tsx Use selector-based i18next.t for meta tag strings
client/tools/generate-search-placeholder.ts Use selector-based t/i18n.t for placeholders
client/src/templates/Introduction/super-block-intro.tsx Selector-based intro translations + safer structure typing
client/src/templates/Introduction/components/super-block-map.tsx Selector-based intro translations + user type narrowing
client/src/templates/Introduction/components/super-block-intro.tsx Selector-based translations and intro data access
client/src/templates/Introduction/components/super-block-accordion.tsx Use namespace resource access for intro chapter/module labels
client/src/templates/Introduction/components/legacy-links.tsx Selector-based intro + misc translations
client/src/templates/Introduction/components/help-translate.tsx Selector-based learn/links translations
client/src/templates/Introduction/components/challenges.tsx Selector-based aria/buttons/icons translations
client/src/templates/Introduction/components/cert-challenge.tsx Selector-based certification titles + safer state typing
client/src/templates/Introduction/components/block.test.tsx Update test translation mocking for selectors
client/src/templates/Introduction/components/block-label.tsx Selector-based block label translation
client/src/templates/Challenges/utils/index.ts Selector-based aria/learn strings in prism helpers
client/src/templates/Challenges/utils/frame.ts Selector-based iframe title translation
client/src/templates/Challenges/redux/execute-challenge-saga.test.js Update i18next mock to support selector keys
client/src/templates/Challenges/redux/execute-challenge-saga.js Selector-based learn strings in challenge execution
client/src/templates/Challenges/redux/create-question-epic.js Selector-based forum-help/intro translations
client/src/templates/Challenges/quiz/show.tsx Selector-based quiz/learn/buttons strings + TODO casts
client/src/templates/Challenges/quiz/finish-quiz-modal.tsx Selector-based quiz modal strings
client/src/templates/Challenges/quiz/exit-quiz-modal.tsx Selector-based quiz modal strings
client/src/templates/Challenges/projects/tool-panel.tsx Selector-based button strings
client/src/templates/Challenges/projects/solution-form.tsx Selector-based learn strings for labels/buttons
client/src/templates/Challenges/projects/frontend/show.tsx Selector-based learn title + TODO casts
client/src/templates/Challenges/projects/backend/show.tsx Selector-based learn title/test-output + TODO casts
client/src/templates/Challenges/ms-trophy/show.tsx Selector-based learn title/buttons + TODO casts
client/src/templates/Challenges/ms-trophy/link-ms-user.tsx Selector-based MS learn/buttons strings
client/src/templates/Challenges/generic/show.tsx Selector-based learn/buttons + intro object access
client/src/templates/Challenges/fill-in-the-blank/show.tsx Selector-based learn/buttons + intro title helper usage
client/src/templates/Challenges/exam/show.tsx Selector-based exam/learn/buttons + intro object access
client/src/templates/Challenges/exam/components/missing-prerequisites.tsx Selector-based caution + exam strings
client/src/templates/Challenges/exam/components/foundational-c-sharp-survey-alert.tsx Selector-based survey strings
client/src/templates/Challenges/exam/components/finish-exam-modal.tsx Selector-based exam modal strings
client/src/templates/Challenges/exam/components/exit-exam-modal.tsx Selector-based exam modal strings
client/src/templates/Challenges/exam/components/exam-results.tsx Selector-based exam results strings/interpolation
client/src/templates/Challenges/exam-download/show.tsx Selector-based exam download page strings
client/src/templates/Challenges/exam-download/exam-token-controls.tsx Selector-based exam-token strings
client/src/templates/Challenges/exam-download/attempts.tsx Selector-based exam/flash strings
client/src/templates/Challenges/components/tool-panel.tsx Selector-based buttons/aria strings
client/src/templates/Challenges/components/test-suite.tsx Selector-based learn/icons strings
client/src/templates/Challenges/components/scene/scene.tsx Selector-based a11y button labels
client/src/templates/Challenges/components/reset-modal.tsx Selector-based learn/buttons strings
client/src/templates/Challenges/components/preview.tsx Selector-based iframe title
client/src/templates/Challenges/components/preview-portal.tsx Selector-based editor tab title
client/src/templates/Challenges/components/output.tsx Selector-based aria label
client/src/templates/Challenges/components/multiple-choice-questions.tsx Selector-based learn/quiz/speaking-modal strings
client/src/templates/Challenges/components/fill-in-the-blanks.tsx Selector-based learn/aria strings
client/src/templates/Challenges/components/daily-challenge-bread-crumb.tsx Selector-based aria + intro title (daily challenge)
client/src/templates/Challenges/components/completion-modal.tsx Selector-based completion modal strings
client/src/templates/Challenges/components/challenge-transcript.tsx Selector-based learn transcript string
client/src/templates/Challenges/components/challenge-title.tsx Selector-based links/misc strings
client/src/templates/Challenges/components/challenge-heading.tsx Temporary cast to keep string-key usage compiling
client/src/templates/Challenges/components/challenge-explanation.tsx Selector-based learn explanation string
client/src/templates/Challenges/components/bread-crumb.tsx Selector-based aria + TODO casts for intro keys
client/src/templates/Challenges/components/assignments.tsx Use plural-form keys explicitly for assignments text
client/src/templates/Challenges/codeally/show.tsx Selector-based learn strings + intro object access
client/src/templates/Challenges/codeally/rdb-step-2-instructions.tsx Selector-based learn step strings
client/src/templates/Challenges/codeally/rdb-step-1-instructions.tsx Selector-based learn step strings
client/src/templates/Challenges/codeally/rdb-ona-logout-alert.tsx Selector-based caution + learn strings
client/src/templates/Challenges/codeally/rdb-ona-continue-alert.tsx Selector-based misc note label
client/src/templates/Challenges/codeally/rdb-local-logout-alert.tsx Selector-based caution + learn strings
client/src/templates/Challenges/codeally/ona-instructions.tsx Selector-based learn local/ona strings
client/src/templates/Challenges/codeally/local-instructions.tsx Selector-based learn local strings
client/src/templates/Challenges/codeally/codespaces-instructions.tsx Selector-based learn codespaces/local strings
client/src/templates/Challenges/classic/xterm.tsx Selector-based aria string
client/src/templates/Challenges/classic/show.tsx Selector-based learn/buttons strings + TODO casts
client/src/templates/Challenges/classic/mobile-layout.tsx Selector-based editor-tabs/aria strings
client/src/templates/Challenges/classic/lower-jaw.tsx Selector-based learn/buttons/aria strings + dynamic learn key
client/src/templates/Challenges/classic/editor.tsx Selector-based aria/editor-alerts/icons + TODO casts
client/src/templates/Challenges/classic/editor-tabs.tsx Selector-based editor tab sr-only text
client/src/templates/Challenges/classic/action-row.tsx Selector-based aria/editor-tabs/buttons strings
client/src/redux/donation-saga.js Selector-based donate error strings
client/src/pages/update-stripe-card.tsx Selector-based learn/buttons/misc strings
client/src/pages/supporters.tsx Selector-based learn/buttons/misc strings
client/src/pages/learn/daily-coding-challenge/archive.tsx Selector-based daily-coding-challenges title
client/src/pages/learn/archive.tsx Selector-based metaTags/learn/landing strings
client/src/pages/learn.tsx Selector-based metaTags title
client/src/pages/index.tsx Selector-based metaTags title for SEO
client/src/pages/email-sign-up.tsx Selector-based misc title
client/src/pages/donate.tsx Selector-based donate title
client/src/pages/catalog.tsx Selector-based curriculum catalog strings
client/src/i18next.d.ts Add typed resources + selector config in CustomTypeOptions
client/src/components/staging-warning-modal/index.tsx Selector-based staging warning strings
client/src/components/signout-modal/index.tsx Selector-based signout strings
client/src/components/share/use-share.tsx TODO cast for intro key string
client/src/components/share/use-share.test.tsx Adjust test expectations for selector-based translation behavior
client/src/components/share/share-template.tsx Selector-based share/aria strings
client/src/components/settings/user-token.tsx Selector-based user-token strings
client/src/components/settings/sound.tsx Selector-based settings/buttons strings
client/src/components/settings/settings-sidebar-nav.tsx Selector-based headings + helper for certification titles
client/src/components/settings/scrollbar-width.tsx Selector-based settings string
client/src/components/settings/reset-modal.tsx Selector-based settings danger-zone strings
client/src/components/settings/keyboard-shortcuts.tsx Selector-based settings/buttons strings
client/src/components/settings/honesty.tsx Selector-based settings/buttons strings
client/src/components/settings/exam-token.tsx Selector-based exam-token/buttons strings
client/src/components/settings/email.tsx Selector-based validation/settings/buttons strings
client/src/components/settings/delete-modal.tsx Selector-based settings danger-zone strings
client/src/components/settings/danger-zone.tsx Selector-based settings danger-zone strings
client/src/components/settings/account.tsx Selector-based settings strings
client/src/components/seo/index.tsx Selector-based intro object retrieval
client/src/components/search/searchBar/search-hits.tsx Selector-based search aria strings
client/src/components/search/searchBar/search-bar.tsx Selector-based search/search-bar strings + TODO cast
client/src/components/search/searchBar/search-bar-optimized.tsx Selector-based search/search-bar strings + TODO cast
client/src/components/search/searchBar/search-bar-footer.tsx Selector-based search strings with interpolation
client/src/components/profile/profile.tsx Selector-based profile/buttons/misc strings
client/src/components/profile/components/utils/utils.ts Selector-based profile joined string
client/src/components/profile/components/username.tsx Selector-based settings strings + TODO cast
client/src/components/profile/components/timeline-pagination.tsx Selector-based aria/profile strings
client/src/components/profile/components/stats.tsx Selector-based profile strings
client/src/components/profile/components/social-icons.tsx Selector-based aria social labels with interpolation
client/src/components/profile/components/profile-completeness.tsx Precompute translated labels via selectors
client/src/components/profile/components/portfolio-projects.tsx Selector-based profile/aria strings
client/src/components/profile/components/internet.tsx Selector-based validation/settings strings
client/src/components/profile/components/heat-map.tsx Selector-based profile/aria strings + plural handling
client/src/components/profile/components/experience-display.tsx Selector-based profile experience strings
client/src/components/profile/components/certifications.tsx Selector-based profile/settings strings + TODO cast
client/src/components/profile/components/camper.tsx Selector-based profile strings
client/src/components/profile/components/bio.tsx Selector-based aria/profile strings
client/src/components/profile/components/about.tsx Selector-based settings/validation/buttons strings
client/src/components/layouts/default.tsx Selector-based metaTags/learn strings + TODO cast
client/src/components/landing/components/two-button-cta.tsx Selector-based buttons/misc strings
client/src/components/landing/components/testimonials.tsx Selector-based landing strings
client/src/components/landing/components/landing-top.tsx Selector-based landing strings
client/src/components/landing/components/landing-catalog.tsx Selector-based landing catalog strings
client/src/components/landing/components/faq.tsx Selector-based landing/learn strings + object return
client/src/components/landing/components/campers-image.tsx Selector-based landing image alt/caption
client/src/components/landing/components/big-call-to-action.tsx Selector-based default CTA string
client/src/components/landing/components/benefits.tsx Selector-based landing benefits strings + object return
client/src/components/landing/components/as-seen-in.tsx Selector-based landing string
client/src/components/helpers/loader.tsx Selector-based misc slow-load string
client/src/components/helpers/form/block-save-button.tsx Selector-based default save label
client/src/components/helpers/avatar-renderer.tsx Selector-based profile sr-only label
client/src/components/growth-book/ona-note.tsx Selector-based intro/misc-text string
client/src/components/growth-book/codeally-down.tsx Selector-based misc labels + intro Trans ns usage
client/src/components/growth-book/codeally-button.tsx Selector-based buttons/aria strings (layout tweak)
client/src/components/email-options.tsx Selector-based buttons/misc strings
client/src/components/daily-coding-challenge/widget.tsx Selector-based daily-coding-challenges/buttons strings
client/src/components/daily-coding-challenge/not-found.tsx Selector-based 404/dcc/buttons strings
client/src/components/daily-coding-challenge/calendar.tsx Selector-based weekdays/aria/buttons strings
client/src/components/daily-coding-challenge/calendar-day.tsx Selector-based aria not-available string
client/src/components/catalog-item.tsx Selector-based intro/curriculum catalog strings
client/src/components/archived-warning/index.tsx Selector-based misc note label
client/src/components/SolutionViewer/project-modal.tsx Selector-based settings/buttons strings
client/src/components/SolutionViewer/exam-results-modal.tsx Selector-based exam results/buttons strings
client/src/components/Progress/progress.tsx Selector-based intro object access + learn strings
client/src/components/OfflineWarning/offline-warning.tsx Selector-based misc offline string
client/src/components/Map/index.tsx Selector-based landing headings + intro titles
client/src/components/Intro/learn-alert.tsx Selector-based learn/donate/buttons strings
client/src/components/Intro/index.tsx Selector-based welcome/heading/login strings
client/src/components/Header/components/universal-nav.tsx Selector-based aria labels
client/src/components/Header/components/menu-button.tsx Selector-based menu label
client/src/components/Header/components/login.tsx Selector-based sign-in default text
client/src/components/Header/components/language-list.tsx Selector-based change-language label
client/src/components/Header/components/exam-nav.tsx Selector-based primary nav aria label
client/src/components/Header/components/auth-or-profile.tsx Selector-based sign-in label
client/src/components/FourOhFour/index.tsx Selector-based 404/buttons strings
client/src/components/Flash/index.tsx Replace t(message, vars) with custom flash translation lookup
client/src/components/Donation/wallets-button.tsx Selector-based donate error strings
client/src/components/Donation/stripe-card-form.tsx Use TFunction and selector-based donate/buttons strings
client/src/components/Donation/multi-tier-donation-form.tsx Selector-based donate/buttons strings
client/src/components/Donation/donate-form.tsx Selector-based donate strings
client/src/components/Donation/donate-completion.tsx Selector-based donate/buttons strings
client/src/components/Donation/card-update-alert-handler.tsx Selector-based donate/buttons strings
client/src/client-only-routes/show-user.tsx Selector-based report/buttons strings
client/src/client-only-routes/show-user.test.tsx Update test translation mocking for selectors
client/src/client-only-routes/show-update-email.tsx Selector-based misc/buttons strings
client/src/client-only-routes/show-unsubscribed.tsx Selector-based metaTags/misc/buttons strings
client/src/client-only-routes/show-settings.tsx Selector-based settings/misc/buttons strings
client/src/client-only-routes/show-project-links.tsx Selector-based certification/settings strings + selector-heading helper
client/src/assets/icons/magnifier.tsx Selector-based icons sr-only label
client/src/assets/icons/lightbulb.tsx Selector-based icon title
client/src/assets/icons/input-reset.tsx Selector-based icons sr-only label
client/src/assets/icons/initial.tsx Selector-based icon title
client/src/assets/icons/green-pass.tsx Selector-based icon label/title
client/src/assets/icons/green-not-completed.tsx Selector-based icon sr-only/title
client/src/assets/icons/fail.tsx Selector-based icon title
client/src/assets/icons/default-avatar.tsx Selector-based icon title/desc
client/package.json Upgrade i18next to 25.5.2
client/i18n/locales/english/translations.json Add aria.bluesky translation
client/config/growthbook-features-default.json JSON formatting normalization
client/mocks/react-i18next.js Update react-i18next test mock to support selector keys
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

You can also share your feedback on Copilot code review. Take the survey.

Comment thread client/src/components/Flash/index.tsx Outdated
Comment thread client/src/components/profile/components/heat-map.tsx
Comment thread client/src/templates/Challenges/redux/execute-challenge-saga.js
@huyenltnguyen

Copy link
Copy Markdown
Member

Hi @ahrjarrett, thank you so much for your patience and the effort you've put into this PR.

After reviewing it more carefully, we've decided not to move forward with this migration at this time. Given our current priorities, we don't think the cost/benefit trade-off works in our favor right now.

We really appreciate your contribution and the time you invested in this. We sincerely apologize that we can't take it further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform: learn UI side of the client application that needs familiarity with React, Gatsby etc. scope: i18n language translation/internationalization. Often combined with language type label

Projects

None yet

6 participants