Skip to content

[Docs]: App Router Setup from docs doesn't work #1881

Closed
@dnistreanu1

Description

@dnistreanu1

Link to page

App Router setup from docs doesn't work

Describe the problem

Not sure is this a problem in docs or a bug but here we go.

In Next.js 15 App Router, in request.ts, requestLocale and locale are always undefined for me. I reproduced the docs exactly:

request:ts

import { getRequestConfig } from 'next-intl/server';
import { routing } from './routing';
import { hasLocale } from 'next-intl';

export const locales = ['en', 'ro', 'it'];
export type LanguageLocale = (typeof routing.locales)[number];

export default getRequestConfig(async ({ requestLocale }) => {
  const requestlocaleAwaited = await requestLocale;
  const selectedLocale = hasLocale(routing.locales, requestlocaleAwaited) ? requestlocaleAwaited : routing.defaultLocale;
  return {
    locale: selectedLocale,
    messages: (await import(`../../messages/${selectedLocale}.json`)).default,
  };
});

routing.ts:

import { defineRouting } from 'next-intl/routing';

export const routing = defineRouting({
  // A list of all locales that are supported
  locales: ['en', 'ro', 'it'],

  // Used when no locale matches
  defaultLocale: 'it',
});

middleware.ts:

import createMiddleware from 'next-intl/middleware';
import { routing } from './src/i18n/routing';

export default createMiddleware(routing);

export const config = {
  // Match all pathnames except for
  matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
};

RootLayout.ts:

export default async function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;
  if (!hasLocale(routing.locales, locale)) {
    return notFound();
  }
  const messages = await getMessages(); // If not specifying here `locale` as param, the client components always default to default language (`it`)

  return (
    <ClientSideProviders>
      <html lang={locale}>
        <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
          <NextIntlClientProvider messages={messages}>
            <NavigationBar>
              <PageContainer>
                <BreadcrumbNavigation />
                {children}
              </PageContainer>
              <Separator orientation="horizontal" variant="primary" />
              <Footer text="© 2025 Acasuca, BIT ROCKET" imageSrc="/content/images/logo.svg" imageAlt="logo" />
            </NavigationBar>
          </NextIntlClientProvider>
        </body>
      </html>
    </ClientSideProviders>
  );
}

If not specifying here locale as param, the client components always default to default language (it), while server components

page.ts (Home):

import { getTranslations } from 'next-intl/server';

export default async function Home() {
  const t = await getTranslations('homePage');
  console.info('HOME', t('title'));
  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <h1 className="text-3xl">{t('title')}</h1>
    </div>
  );
}

Translation is always in default language, even if my URL is localhost:3000/ro . It doesn't matter if in a server component I remove async to be able to use useTranslation or not, the issue is the same.

Note: My browser's default language is set to Romanian (RO)

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationunconfirmedNeeds triage.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions