我正在使用具有动态路由本地化功能的新 App Router(app 目录)开发 Next.js 15 应用。我有一个 [locale] 目录,用于处理多种语言路由,并使用 params 对象来访问语言环境值。但是,当我尝试访问 params.locale 时,我不断收到以下错误:

Error: Route "/[locale]" used `params.locale`. `params` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
    at locale (webpack:///app/[locale]/layout.tsx?a262:30:34)

代码结构这是我的应用程序的结构:

app/
├── [locale]/
│   ├── layout.tsx            // Root layout for [locale] dynamic route
│   └── page.tsx              // Main page component for [locale] dynamic route
locales/
├── en/
│   └── common.json           // English translations
├── lt/
│   └── common.json           // Lithuanian translations
i18Config.js                  // i18n configuration with available locales
i18n.js                       // i18n initialization file
TranslationsProvider.js       // Translation provider component
middleware.js                 // Middleware to handle locale-based redirection

在 app/[locale]/layout.tsx 中,我想从 params 中访问语言环境值并将其传递给不同的组件。我尝试了各种方法来访问 params,但错误仍然存​​在。

以下是我的 layout.tsx 文件的样子:

import "@/styles/global.css";
import { Outfit } from "next/font/google";
import { Providers } from "./providers";
import i18nConfig from "../../i18nConfig";
import { dir } from "i18next";

const outfit = Outfit({
  subsets: ["latin"],
  weight: ["300", "400", "500", "600", "700", "800"],
  style: ["normal"],
});

export function generateStaticParams() {
  return i18nConfig.locales.map((locale) => ({ locale }));
}

export default async function RootLayout({
  children,
  params: { locale },
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  return (
    <html
      lang={locale}
      dir={dir(locale)}
      suppressHydrationWarning
      className={outfit.className}
    >
      <body className="bg-background">
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

  1. 在函数体中直接访问 params:我已将 params.locale 移至函数体中的单独常量,但仍然出现错误。
  2. 使用 generateStaticParams:我添加了 generateStaticParams 来为可用的语言环境(en 和 lt)预生成路由。这也没有解决错误。
  3. 类型调整:我为 params 创建了一个自定义类型,以确保 TypeScript 知道 params 的结构(即,params:{locale:string})。

该错误表明 params 应该“等待”,即使 params 是一个对象而不是承诺,因此 await params 在这里没有意义。我看到其他帖子提到异步函数中的解构可能会导致 Next.js 中的 params 出现问题,但直接访问 params 对我来说也不起作用。每次更改后重新启动服务器也无法解决问题。

如何在动态路由布局中正确访问 params.locale 而不出现此错误?是否有解决方法或配置我遗漏了?任何见解都将不胜感激。谢谢!

1

  • 1
    请检查此处:


    – 


最佳答案
3

您应该等待参数,例如:

export async function POST(request: Request, { params }: { params: Promise<{ unit_id: string }> }) {

进而:

const { unit_id: unitId } = await params

例如。

从 React 15 开始,你必须等待参数来解决这个问题。以下是一个例子:

export default function RootLayout({children, params }: { children: React.ReactNode; params: Promise<{ locale: string }> }) {
  const { locale } = await params;
  return()
}

如果它对你有用,请告诉我。

3

  • 它不起作用…我认为这个“使用”功能不能在服务器端组件中使用,因为我使用你的解决方案时得到了不同的错误。客户端组件可以使用你的解决方案,它工作正常,但在服务器端组件上它不起作用…在服务器组件中我使用这个 const { locale } = await params; 它对我来说工作正常。但很奇怪,为什么这个“params”是 Promise?我不明白…


    – 

  • 在最新的 Next js 版本 15 中,他们改变了我们在旧版本中使用参数的方式,并让它们改为承诺,并且您在 SSR 中是正确的,您必须使用 async await,因为“use”是一个钩子,不能在 SSR 中使用,只能在 CSR 中使用。


    – 

  • Next.js 15 官方文档 ( ) 建议使用此解决方案。但它不起作用。我尝试运行自动修复脚本,它所做的只是添加 async/await。也没有用。警告仍然出现。也许这是 v15 的一个错误


    – 


我刚刚发现了这个问题(而且它根本没有意义)。

这是layout.tsx代码,它似乎是正确的:

export default async function RootLayout({
  children,
  params,
}: RootLayoutProps) {
  const { lang } = await params

  return (
    <html lang={lang}>
      <body>{children}</body>
    </html>
  )
}

就我而言,该icon.png文件触发了警告。

警告:

/src
  /app
    /[lang]
      /layout.tsx
      /icon.png

毫无预警地:

/src
  /app
    /icon.png
    /[lang]
      /layout.tsx

就是这样:

  • /app/[lang]/icon.png– 警告
  • /app/icon.png– 没有警告