Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from nodejs:main #317

Merged
merged 2 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions TRANSLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

Node.js is a global platform and so this site has many translations. We use [Crowdin](https://crowdin.com) to translate the Node.js Website

The translation of the site into languages other than English is handled by [Crowdin translators](https://support.crowdin.com/translation-process-overview/).
The site's translation into languages other than English is handled by [Crowdin translators](https://support.crowdin.com/translation-process-overview/).

We use [`next-intl`](https://next-intl-docs.vercel.app/) as our Internationalization Library. We recommend reading its documentation for API usage.

## How to translate

Expand Down Expand Up @@ -55,11 +57,29 @@ If you're making a new Component and adding Translation Keys for your Component,
- The values of each Translation Key should follow the [ICU Message Syntax](https://formatjs.io/docs/core-concepts/icu-syntax/)
- All new Translation keys should be added at the bottom of the `i18n/locales/en.json` file. Since this makes it easier for Translators to notice that there are new Translation keys to be translated.

#### Notes about Translation Keys

It's important to mention that we use nested translation keys within the Locale files. This means that if your translation key is `components.common.myComponent.something`, you should actually define the key and value within:

```json
{
"components": {
...,
"common": {
...,
"myComponent": {
"something": "value of translation key"
}
}
}
}
```

### Translations and Unit Testing

Translation Keys should not be translated during Unit Testing. If your Component uses, for example `FormattedMessage`, you should provide the `<IntlProvider>` surrounding your `testing-library` render logic, or you can create a wrapper for your test. Note that you should not import the English messages to your Unit Test as:
Translation Keys should not be translated during Unit Testing. If your Component uses, for example `usTranslations`, you should provide the `<NextIntlProvider>` surrounding your `testing-library` render logic, or you can create a wrapper for your test. Note that you should not import the English messages to your Unit Test as:

- Unit Testing should test a Component functionality.
- Unit Tests should not rely on text, titles, or string bags, as these texts will change arbitrarily and make the test suite fail.
- In this case, you should test your component by aria-text, or other `aria-*` attributes or even by class names or other artifacts.
- If you want to test how different languages and text appear within a Component, Visual Regression Testing is recommended.
- Visual Regression Testing is recommended to test how different languages and text appear within a Component.
29 changes: 27 additions & 2 deletions i18n.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
import type { RichTranslationValues } from 'next-intl';
import { getRequestConfig } from 'next-intl/server';

export const defaultRichTextValues: RichTranslationValues = {
import { availableLocaleCodes } from './next.locales.mjs';

// Loads the Application Locales/Translations Dynamically
const loadLocaleDictionary = async (locale: string) => {
if (locale === 'en') {
// This enables HMR on the English Locale, so that instant refresh
// happens while we add/change texts on the source locale
return import('./i18n/locales/en.json').then(f => f.default);
}

if (locale in availableLocaleCodes) {
// Other languages don't really require HMR as they will never be development languages
// so we can load them dynamically
return import(`./i18n/locales/${locale}.json`).then(f => f.default);
}

throw new Error(`Unsupported locale: ${locale}`);
};

// Defines default Rich Text Components
const defaultRichTextValues: RichTranslationValues = {
graySpan: c => <span className="small color-lightgray">{c}</span>,
};

// Provides `next-intl` configuration for RSC/SSR
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`./i18n/locales/${locale}.json`)).default,
// This is the dictionary of messages to be loaded
messages: await loadLocaleDictionary(locale),
// Default Rich Text Translations
defaultTranslationValues: defaultRichTextValues,
// We always define the App timezone as UTC
timeZone: 'Etc/UTC',
}));
4 changes: 0 additions & 4 deletions layouts/DocsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@ const DocsLayout: FC<PropsWithChildren> = ({ children }) => {
apiLts: {
ltsNodeVersion: lts ? `v${lts.major}.x` : undefined,
fullLtsNodeVersion: lts ? lts.versionWithPrefix : undefined,
graySpan: c => <span className="small color-lightgray">{c}</span>,
},
apiCurrent: {
fullCurrentNodeVersion: current ? current.versionWithPrefix : undefined,
currentNodeVersion: current ? `v${current.major}.x` : undefined,
},
guides: {
graySpan: c => <span className="small color-lightgray">{c}</span>,
},
};

return (
Expand Down
Loading
Loading