我目前正在利用Next.js (v13.5.4)next-intl (v3.0.0-beta.19)进行国际化.我的目标是将区域设置的URL struct 从en-GB格式修改为en/UK格式.

我已经使用应用程序路由设置了Next,并在server component guide之后初始化了Next-intl.

下面是我在next.config.js中设置URL重写的try :


/** @type {import('next').NextConfig} */
const nextConfig = {
    async rewrites() {
        return {
            beforeFiles: [
                {
                    source: "/en/uk/:path*",
                    destination: "/en-GB/:path*",
                }
            ]
        }
    },
}

module.exports = withNextIntl(nextConfig);

使用此配置,可以按预期导航到http://localhost:3000/en-GB个功能.然而,访问http://localhost:3000/en/uk会重定向到http://localhost:3000/en-GB/en/uk(其中en-GB是我最后访问的区域设置).

关于更多的背景,这是我的中间件:

import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
    locales: ['de-DE', 'en-GB'],
    defaultLocale: ''
});

export const config = {
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};

Attempts at Resolving:

  • 从重写配置中删除了beforeFiles段.
  • 在我的配置中包含了locale: false.
  • 将中间件中的匹配器调整为matcher: ['/((?!api|en/uk|_next|_vercel|.*\\..*).*)'],导致错误:Error: Unable to find next-intl locale, have you configured the middleware.

任何见解、替代解决方案或建议都将不胜感激.

推荐答案

我前面的回答只适用于客户端组件.要让它与服务器组件一起工作,您需要在中间件中进行URL重写.这是因为next.js优先考虑中间件中的重定向和重写,而不是配置中的重写.下面是我最后的中间件:

import createIntlMiddleware from 'next-intl/middleware';
import { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
    const localeMapping = {
        'en/uk': 'en-GB',
        'de/de': 'de-DE',
    };
    let modifiedRequest = request;

    // URL Rewrites
    for (const [srcPath, targetPath] of Object.entries(localeMapping)) {
        if (request.nextUrl.pathname.startsWith(`/${srcPath}`)) {
            const remainingPath = request.nextUrl.pathname.replace(`/${srcPath}`, '');
            const newUrl = new URL(`/${targetPath}${remainingPath}`, request.url);
            modifiedRequest = new NextRequest(newUrl, request);
            break;
        }
    }

    const locales = Object.values(localeMapping);

    // Translations middleware logic
    const defaultLocale = modifiedRequest.headers.get('x-default-locale') || 'en-GB';
    const handleI18nRouting = createIntlMiddleware({
        locales,
        defaultLocale
    });

    const response = handleI18nRouting(modifiedRequest);
    response.headers.set('x-default-locale', defaultLocale);

    return response;
}

export const config = {
    // Skip all paths that should not be internationalized.
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};

Reactjs相关问答推荐

可选链和useState挂钩

如何通过浏览器路由在单独的.jsx文件中使用MUI抽屉?

如何用Reaction做交互式的MathML?

无法使用Reaction日期选取器和Next.js设置初始日期

根据用户 Select 的注册类型更改表单字段

状态更改是否卸载功能组件

在迭代状态时无法读取未定义的属性(读取 map )

获取类别和页面的参数

无法通过 fetch 获取数据到上下文中

如何根据ReactJS中元素列表中的布尔值仅显示一次值

Syncfusion:带有 TabItemsDirective 的选项卡组件不显示任何内容

Firebase查询返回随机用户数据,而不是过滤后的用户数据

根据其中的值不同地react setState 更新状态

Github 页面无法正确呈现 CSS,因为它是本地的

下一次导出:未捕获的语法错误:标识符注册表已被声明

如何通过单击多个选项中的特定项目在模态上呈现不同的标题?

在 redux 工具包中使用 dispatch 发送多个操作

为什么 React 会多次调用我的应用程序的某些函数?

Axios 删除在带有授权令牌的react js 中不起作用

根据计算 ReactJs 更新输入字段