Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion apps/site/app/[locale]/[...path]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
* dynamic params, which will lead on static export errors and other sort of issues.
*/

import { availableLocaleCodes, defaultLocale } from '@node-core/website-i18n';
import { notFound } from 'next/navigation';

import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
import { ENABLE_STATIC_EXPORT_LOCALE } from '#site/next.constants.mjs';
import { dynamicRouter } from '#site/next.dynamic.mjs';
import * as basePage from '#site/next.dynamic.page.mjs';
import { availableLocaleCodes, defaultLocale } from '#site/next.locales.mjs';

import type { DynamicParams } from '#site/types';
import type { FC } from 'react';
Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/[locale]/blog/[...path]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { defaultLocale } from '@node-core/website-i18n';
import { notFound } from 'next/navigation';

import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
import { BLOG_DYNAMIC_ROUTES } from '#site/next.dynamic.constants.mjs';
import * as basePage from '#site/next.dynamic.page.mjs';
import { defaultLocale } from '#site/next.locales.mjs';

import type { DynamicParams } from '#site/types';
import type { FC } from 'react';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { defaultLocale } from '@node-core/website-i18n';
import { notFound, redirect } from 'next/navigation';

import provideReleaseData from '#site/next-data/providers/releaseData';
import provideReleaseVersions from '#site/next-data/providers/releaseVersions';
import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
import * as basePage from '#site/next.dynamic.page.mjs';
import { defaultLocale } from '#site/next.locales.mjs';

import type { DynamicParams } from '#site/types';
import type { FC } from 'react';
Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/[locale]/feed/[feed]/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defaultLocale } from '@node-core/website-i18n';
import { NextResponse } from 'next/server';

import { siteConfig } from '#site/next.json.mjs';
import { defaultLocale } from '#site/next.locales.mjs';
import { getFeeds } from '#site/util/feeds';

type DynamicStaticPaths = { locale: string; feed: string };
Expand Down
5 changes: 3 additions & 2 deletions apps/site/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { availableLocales, defaultLocale } from '@node-core/website-i18n';
import { Analytics } from '@vercel/analytics/react';
import { SpeedInsights } from '@vercel/speed-insights/next';
import classNames from 'classnames';
Expand All @@ -6,7 +7,6 @@ import { NextIntlClientProvider } from 'next-intl';
import BaseLayout from '#site/layouts/Base';
import { VERCEL_ENV } from '#site/next.constants.mjs';
import { IBM_PLEX_MONO, OPEN_SANS } from '#site/next.fonts';
import { availableLocalesMap, defaultLocale } from '#site/next.locales.mjs';
import { ThemeProvider } from '#site/providers/themeProvider';

import type { FC, PropsWithChildren } from 'react';
Expand All @@ -22,7 +22,8 @@ type RootLayoutProps = PropsWithChildren<{
const RootLayout: FC<RootLayoutProps> = async ({ children, params }) => {
const { locale } = await params;

const { langDir, hrefLang } = availableLocalesMap[locale] || defaultLocale;
const { langDir, hrefLang } =
availableLocales.find(l => l.code === locale) || defaultLocale;

return (
<html
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import HexagonGrid from '@node-core/ui-components/Icons/HexagonGrid';
import JsWhiteIcon from '@node-core/ui-components/Icons/Logos/JsWhite';
import { defaultLocale } from '@node-core/website-i18n';
import { ImageResponse } from 'next/og';

import { DEFAULT_CATEGORY_OG_TYPE } from '#site/next.constants.mjs';
import { defaultLocale } from '#site/next.locales.mjs';

// TODO: use CSS variables instead of absolute values
const CATEGORY_TO_THEME_COLOUR_MAP = {
Expand Down
3 changes: 1 addition & 2 deletions apps/site/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { defaultLocale, availableLocaleCodes } from '@node-core/website-i18n';
import { notFound } from 'next/navigation';

import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
import { ENABLE_STATIC_EXPORT_LOCALE } from '#site/next.constants.mjs';
import * as basePage from '#site/next.dynamic.page.mjs';
import { availableLocaleCodes } from '#site/next.locales.mjs';
import { defaultLocale } from '#site/next.locales.mjs';

import type { DynamicParams } from '#site/types';
import type { FC } from 'react';
Expand Down
3 changes: 2 additions & 1 deletion apps/site/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { availableLocaleCodes, defaultLocale } from '@node-core/website-i18n';

import { BASE_PATH } from '#site/next.constants.mjs';
import { BASE_URL } from '#site/next.constants.mjs';
import { EXTERNAL_LINKS_SITEMAP } from '#site/next.constants.mjs';
import { BLOG_DYNAMIC_ROUTES } from '#site/next.dynamic.constants.mjs';
import { dynamicRouter } from '#site/next.dynamic.mjs';
import { availableLocaleCodes, defaultLocale } from '#site/next.locales.mjs';

import type { MetadataRoute } from 'next';

Expand Down
2 changes: 1 addition & 1 deletion apps/site/components/withDownloadSection.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { defaultLocale } from '@node-core/website-i18n';
import { getLocale } from 'next-intl/server';

import { getClientContext } from '#site/client-context';
import WithNodeRelease from '#site/components/withNodeRelease';
import provideDownloadSnippets from '#site/next-data/providers/downloadSnippets';
import { defaultLocale } from '#site/next.locales.mjs';
import {
ReleaseProvider,
ReleasesProvider,
Expand Down
2 changes: 1 addition & 1 deletion apps/site/components/withMetaBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import MetaBar from '@node-core/ui-components/Containers/MetaBar';
import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub';
import { defaultLocale } from '@node-core/website-i18n';
import { useFormatter, useLocale, useTranslations } from 'next-intl';

import Link from '#site/components/Link';
Expand All @@ -10,7 +11,6 @@ import { useClientContext } from '#site/hooks/react-client';
import useMediaQuery from '#site/hooks/react-client/useMediaQuery';
import { DEFAULT_DATE_FORMAT } from '#site/next.calendar.constants.mjs';
import { TRANSLATION_URL } from '#site/next.constants.mjs';
import { defaultLocale } from '#site/next.locales.mjs';
import { getGitHubBlobUrl } from '#site/util/github';

import type { FC } from 'react';
Expand Down
2 changes: 1 addition & 1 deletion apps/site/components/withNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import NavBar from '@node-core/ui-components/Containers/NavBar';
// TODO(@AvivKeller): I don't like that we are importing styles from another module
import styles from '@node-core/ui-components/Containers/NavBar/index.module.css';
import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub';
import { availableLocales } from '@node-core/website-i18n';
import dynamic from 'next/dynamic';
import { useLocale, useTranslations } from 'next-intl';
import { useTheme } from 'next-themes';
Expand All @@ -16,7 +17,6 @@ import WithBanner from '#site/components/withBanner';
import WithNodejsLogo from '#site/components/withNodejsLogo';
import { useSiteNavigation } from '#site/hooks';
import { useRouter, usePathname } from '#site/navigation.mjs';
import { availableLocales } from '#site/next.locales.mjs';

import type { SimpleLocaleConfig } from '@node-core/ui-components/types';
import type { FC } from 'react';
Expand Down
8 changes: 4 additions & 4 deletions apps/site/i18n.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { importLocale } from '@node-core/website-i18n';
import { availableLocaleCodes, defaultLocale } from '@node-core/website-i18n';
import defaultMessages from '@node-core/website-i18n/locales/en.json';
import { getRequestConfig } from 'next-intl/server';

import { availableLocaleCodes, defaultLocale } from '#site/next.locales.mjs';

import { deepMerge } from './util/objects';

// Loads the Application Locales/Translations Dynamically
Expand All @@ -15,7 +13,9 @@ const loadLocaleDictionary = async (locale: string) => {
if (availableLocaleCodes.includes(locale)) {
// Other languages don't really require HMR as they
// will never be development languages so we can load them dynamically
const messages = await importLocale(locale);
const { default: messages } = await import(
`@node-core/website-i18n/locales/${locale}.json`
);

// Use default messages as fallback
return deepMerge(defaultMessages, messages);
Expand Down
3 changes: 1 addition & 2 deletions apps/site/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { availableLocaleCodes, defaultLocale } from '@node-core/website-i18n';
import createMiddleware from 'next-intl/middleware';

import { availableLocaleCodes, defaultLocale } from '#site/next.locales.mjs';

export default createMiddleware({
// A list of all locales that are supported
locales: availableLocaleCodes,
Expand Down
3 changes: 1 addition & 2 deletions apps/site/navigation.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';

import { availableLocaleCodes } from '@node-core/website-i18n';
import { createNavigation } from 'next-intl/navigation';

import { availableLocaleCodes } from './next.locales.mjs';

export const { Link, redirect, usePathname, useRouter } = createNavigation({
locales: availableLocaleCodes,
});
2 changes: 1 addition & 1 deletion apps/site/next-data/generators/downloadSnippets.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { readFile, glob } from 'node:fs/promises';
import { basename, extname, join } from 'node:path';

import { availableLocaleCodes } from '../../next.locales.mjs';
import { availableLocaleCodes } from '@node-core/website-i18n';

/**
* This method is used to generate the Node.js Website Download Snippets
Expand Down
2 changes: 1 addition & 1 deletion apps/site/next.dynamic.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { readFile } from 'node:fs/promises';
import { join, normalize, sep } from 'node:path';

import { availableLocaleCodes, defaultLocale } from '@node-core/website-i18n';
import matter from 'gray-matter';
import { cache } from 'react';
import { VFile } from 'vfile';
Expand All @@ -17,7 +18,6 @@ import { IS_DEV_ENV } from './next.constants.mjs';
import { PAGE_METADATA } from './next.dynamic.constants.mjs';
import { getMarkdownFiles } from './next.helpers.mjs';
import { siteConfig } from './next.json.mjs';
import { availableLocaleCodes, defaultLocale } from './next.locales.mjs';

// This is the combination of the Application Base URL and Base PATH
const baseUrlAndPath = `${BASE_URL}${BASE_PATH}`;
Expand Down
4 changes: 2 additions & 2 deletions apps/site/next.dynamic.page.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { join } from 'node:path';

import { allLocaleCodes, availableLocaleCodes } from '@node-core/website-i18n';
import { defaultLocale } from '@node-core/website-i18n';
Comment thread
avivkeller marked this conversation as resolved.
Outdated
import { notFound, redirect } from 'next/navigation';
import { setRequestLocale } from 'next-intl/server';

import { setClientContext } from '#site/client-context';
import WithLayout from '#site/components/withLayout';
import { PAGE_VIEWPORT } from '#site/next.dynamic.constants.mjs';
import { dynamicRouter } from '#site/next.dynamic.mjs';
import { allLocaleCodes, availableLocaleCodes } from '#site/next.locales.mjs';
import { defaultLocale } from '#site/next.locales.mjs';
import { MatterProvider } from '#site/providers/matterProvider';

/**
Expand Down
36 changes: 0 additions & 36 deletions apps/site/next.locales.mjs

This file was deleted.

3 changes: 2 additions & 1 deletion apps/site/next.rewrites.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

import { availableLocaleCodes } from '@node-core/website-i18n';

import { siteRedirects } from './next.json.mjs';
import { availableLocaleCodes } from './next.locales.mjs';

// This allows us to prefix redirects with all available locale codes so that redirects are not bound to a single locale
// This also transforms the locale itself as a matching group that can be used for rewrites
Expand Down
10 changes: 5 additions & 5 deletions apps/site/tests/e2e/general-behavior.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { importLocale } from '@node-core/website-i18n';
import englishLocale from '@node-core/website-i18n/locales/en.json' with { type: 'json' };
import { test, expect, type Page } from '@playwright/test';

import type { Locale } from '@node-core/website-i18n/types';

const englishLocale = await importLocale('en');

// TODO(@avivkeller): It would be ideal for all the Test IDs to not exist in the
// ui-components package, and instead be passed as props.
const locators = {
Expand Down Expand Up @@ -37,14 +35,16 @@
const selector = `[aria-labelledby=${await button.getAttribute('id')}]`;
await button.click();

await page.waitForSelector(selector);

Check failure on line 38 in apps/site/tests/e2e/general-behavior.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright Tests

[firefox] › tests/e2e/general-behavior.spec.ts:90:5 › Node.js Website › Language › should correctly translate UI elements according to language files

2) [firefox] › tests/e2e/general-behavior.spec.ts:90:5 › Node.js Website › Language › should correctly translate UI elements according to language files Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── Error: page.waitForSelector: Test timeout of 30000ms exceeded. Call log: - waiting for locator('[aria-labelledby=radix-_R_tpaupivb_]') to be visible 36 | await button.click(); 37 | > 38 | await page.waitForSelector(selector); | ^ 39 | return page.locator(selector); 40 | }; 41 | at openLanguageMenu (/home/runner/work/nodejs.org/nodejs.org/apps/site/tests/e2e/general-behavior.spec.ts:38:14) at /home/runner/work/nodejs.org/nodejs.org/apps/site/tests/e2e/general-behavior.spec.ts:121:20
return page.locator(selector);
};

const verifyTranslation = async (page: Page, locale: Locale | string) => {
// Load locale data if string code provided (e.g., 'es', 'fr')
const localeData =
typeof locale === 'string' ? await importLocale(locale) : locale;
const localeData: Locale =
typeof locale === 'string'
? await import(`@node-core/website-i18n/locales/${locale}.json`)
Comment thread
avivkeller marked this conversation as resolved.
Outdated
: locale;

// Get navigation links and expected translations
const links = await page
Expand Down
9 changes: 0 additions & 9 deletions docs/technologies.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ This document provides an overview of the technologies used in the Node.js websi
- [`redirects.json`](#redirectsjson)
- [Configuration Files](#configuration-files)
- [`site.json`](#sitejson)
- [`next.locales.mjs`](#nextlocalesmjs)
- [Development Environment](#development-environment)
- [VSCode Configuration](#vscode-configuration)
- [Build and Deployment](#build-and-deployment)
Expand Down Expand Up @@ -267,14 +266,6 @@ Website metadata configuration:
- Build-time metadata
- Uses JSON format for easy collaboration

### `next.locales.mjs`

Locale configuration and management:

- Supported locale definitions
- Locale-specific settings
- Page availability per locale

## Development Environment

### VSCode Configuration
Expand Down
28 changes: 5 additions & 23 deletions packages/i18n/src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,22 @@

import localeConfig from './config.json' with { type: 'json' };

/**
Comment thread
avivkeller marked this conversation as resolved.
* Imports a locale when exists from the locales directory
*
* @param {string} locale The locale code to import
* @returns {Promise<import('./types').Locale>} The imported locale
*/
export const importLocale = async locale => {
return import(`./locales/${locale}.json`, { with: { type: 'json' } }).then(
f => f.default
);
};

/**
* A set of available and enabled locales for the website
* This is used for allowing us to redirect the user to any
* of the available locales that we have enabled on the website
*
* @returns {Array<import('./types').LocaleConfig>}
Comment thread
avivkeller marked this conversation as resolved.
Outdated
*/
export const getAvailableLocales = () =>
localeConfig.filter(locale => locale.enabled);
export const availableLocales = localeConfig.filter(locale => locale.enabled);

// This gives an easy way of accessing all available locale codes
export const getAvailableLocaleCodes = () =>
getAvailableLocales().map(locale => locale.code);
export const availableLocaleCodes = availableLocales.map(locale => locale.code);

// This provides the default locale information for the Next.js Application
// This is marked by the unique `locale.default` property on the `en` locale
export const getDefaultLocale = () =>
getAvailableLocales().find(locale => locale.default);

// Creates a Map of available locales for easy access
export const getAvailableLocalesMap = () =>
Object.fromEntries(localeConfig.map(locale => [locale.code, locale]));
/** @type {import('./types').LocaleConfig} */
export const defaultLocale = availableLocales.find(locale => locale.default);
Comment thread
avivkeller marked this conversation as resolved.

// Creates all supported locales
export const getAllLocaleCodes = () => localeConfig.map(locale => locale.code);
export const allLocaleCodes = localeConfig.map(locale => locale.code);
Loading