Skip to content
Open
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
4 changes: 2 additions & 2 deletions apps/site/app/[locale]/[...path]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export const generateStaticParams = async () => {
// finally it returns (if the locale and route are valid) the React Component with the relevant context
// and attached context providers for rendering the current page
const getPage: FC<PageParams> = async props => {
const { path, locale: routeLocale } = await props.params;
const { path } = await props.params;

// Gets the current full pathname for a given path
const [locale, pathname] = basePage.getLocaleAndPath(path, routeLocale);
const [locale, pathname] = await basePage.getLocaleAndPath(path);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No need to pass the routeLocale anymore since we can read from next/root-params within getLocaleAndPath.


// Gets the Markdown content and context
const [content, context] = await basePage.getMarkdownContext({
Expand Down
4 changes: 2 additions & 2 deletions apps/site/app/[locale]/blog/[...path]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export const generateStaticParams = async () => {
// finally it returns (if the locale and route are valid) the React Component with the relevant context
// and attached context providers for rendering the current page
const getPage: FC<PageParams> = async props => {
const { path, locale: routeLocale } = await props.params;
const { path } = await props.params;

// Gets the current full pathname for a given path
const [locale, pathname] = basePage.getLocaleAndPath(path, routeLocale);
const [locale, pathname] = await basePage.getLocaleAndPath(path);

// Verifies if the current route is a dynamic route
const isDynamicRoute = BLOG_DYNAMIC_ROUTES.some(r => r.includes(pathname));
Expand Down
4 changes: 2 additions & 2 deletions apps/site/app/[locale]/download/archive/[version]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ export const generateStaticParams = async () => {
// finally it returns (if the locale and route are valid) the React Component with the relevant context
// and attached context providers for rendering the current page
const getPage: FC<PageParams> = async props => {
const { version, locale: routeLocale } = await props.params;
const { version } = await props.params;

// Gets the current full pathname for a given path
const [locale, pathname] = basePage.getLocaleAndPath(version, routeLocale);
const [locale, pathname] = await basePage.getLocaleAndPath(version);

if (version === 'current') {
const releaseData = await provideReleaseData();
Expand Down
9 changes: 3 additions & 6 deletions apps/site/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import PlatformAnalytics from '#platform/analytics';
import { availableLocales, defaultLocale } from '@node-core/website-i18n';
import classNames from 'classnames';
import { NextIntlClientProvider } from 'next-intl';
import { getLocale } from 'next-intl/server';

import BaseLayout from '#site/layouts/Base';
import { IBM_PLEX_MONO, OPEN_SANS } from '#site/next.fonts';
Expand All @@ -13,12 +14,8 @@ import '#site/styles/index.css';

const fontClasses = classNames(IBM_PLEX_MONO.variable, OPEN_SANS.variable);

type RootLayoutProps = PropsWithChildren<{
params: Promise<{ locale: string }>;
}>;

const RootLayout: FC<RootLayoutProps> = async ({ children, params }) => {
const { locale } = await params;
const RootLayout: FC<PropsWithChildren> = async ({ children }) => {
const locale = await getLocale();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Using await getLocale() returns the returned locale from i18n.tsx—including potential defaults.


const { langDir, hrefLang } =
availableLocales.find(l => l.code === locale) || defaultLocale;
Expand Down
4 changes: 2 additions & 2 deletions apps/site/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ export const generateStaticParams = async () => {
// finally it returns (if the locale and route are valid) the React Component with the relevant context
// and attached context providers for rendering the current page
const getPage: FC<PageParams> = async props => {
const { path, locale: routeLocale } = await props.params;
const { path } = await props.params;

// Gets the current full pathname for a given path
const [locale, pathname] = basePage.getLocaleAndPath(path, routeLocale);
const [locale, pathname] = await basePage.getLocaleAndPath(path);

// Gets the Markdown content and context
const [content, context] = await basePage.getMarkdownContext({
Expand Down
8 changes: 5 additions & 3 deletions apps/site/i18n.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { availableLocaleCodes, defaultLocale } from '@node-core/website-i18n';
import defaultMessages from '@node-core/website-i18n/locales/en.json';
import { locale as getRootLocale } from 'next/root-params';
import { getRequestConfig } from 'next-intl/server';

import { deepMerge } from './util/objects';
Expand All @@ -25,9 +26,10 @@ const loadLocaleDictionary = async (locale: string) => {
};

// Provides `next-intl` configuration for RSC/SSR
export default getRequestConfig(async ({ requestLocale }) => {
// This typically corresponds to the `[locale]` segment
let locale = await requestLocale;
export default getRequestConfig(async params => {
// An explicit locale passed to an awaitable API like `getTranslations({ locale })`
// wins, otherwise we read the `[locale]` segment of the root layout
let locale = params.locale ?? (await getRootLocale());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the key: requestLocale is no longer needed, but we can read from next/root-params.

I've kept the behavior to read an override from a call site though, as this can be handy for Server Actions and Route Handlers (where next/root-params is not yet supported).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

noice !


// Ensure that the incoming locale is valid
if (!locale || !availableLocaleCodes.includes(locale)) {
Expand Down
24 changes: 12 additions & 12 deletions apps/site/next.dynamic.page.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
availableLocaleCodes,
} from '@node-core/website-i18n';
import { notFound, redirect } from 'next/navigation';
import { setRequestLocale } from 'next-intl/server';
import { locale as getRootLocale } from 'next/root-params';

import { setClientContext } from '#site/client-context';
import WithLayout from '#site/components/withLayout';
Expand All @@ -28,11 +28,13 @@ export const generateViewport = () => ({ ...PAGE_VIEWPORT });
*
* @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata
*
* @param {{ params: Promise<{ path: Array<string>; locale: string }>, prefix?: string }} props
* @param {{ params: Promise<{ path: Array<string> }>, prefix?: string }} props
* @returns {Promise<import('next').Metadata>} the metadata for the page
*/
export const generateMetadata = async ({ params, prefix }) => {
const { path = [], locale = defaultLocale.code } = await params;
const { path = [] } = await params;

const locale = (await getRootLocale()) ?? defaultLocale.code;

const pathname = dynamicRouter.getPathname(path);

Expand All @@ -46,15 +48,16 @@ export const generateMetadata = async ({ params, prefix }) => {
/**
* This method is used for retrieving the current locale and pathname from the request
*
* The locale comes from the `[locale]` root param, so pages don't have to read it
* from their own `params` and hand it over.
*
* @param {string|Array<string>} path
* @param {string} locale
* @returns {[string, string]} the locale and pathname for the request
* @returns {Promise<[string, string]>} the locale and pathname for the request
*/
export const getLocaleAndPath = (path = [], locale = defaultLocale.code) => {
if (!availableLocaleCodes.includes(locale)) {
// Forces the current locale to be the Default Locale
setRequestLocale(defaultLocale.code);
export const getLocaleAndPath = async (path = []) => {
const locale = (await getRootLocale()) ?? defaultLocale.code;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've considered reading from await getLocale() here, but that would internally apply defaults. Might be safer to keep an additional call to next/root-params here so the validation below continues to work as-is.


if (!availableLocaleCodes.includes(locale)) {
if (!allLocaleCodes.includes(locale)) {
// when the locale is not listed in the locales, return NotFound
return notFound();
Expand All @@ -66,9 +69,6 @@ export const getLocaleAndPath = (path = [], locale = defaultLocale.code) => {
return redirect(`/${defaultLocale.code}/${pathname}`);
}

// Configures the current Locale to be the given Locale of the Request
setRequestLocale(locale);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No longer needed.


// Gets the current full pathname for a given path
return [locale, dynamicRouter.getPathname(path)];
};
Expand Down
Loading