我在我的项目中使用
Next.js 14
和 next-intl
。我可以在不同语言之间切换,但问题是每次我更改语言时,next-intl 都会将我导航到主页。
假设我在个人资料页面(www.mydomain.com/ru/profile),当我切换语言时,它会将我导航到主页(www.mydomain.com/en),但它应该只是改变区域设置 (www.mydomain.com/en/profile) 不是整个路径。这是我的代码
"use client";
import { useRouter } from "next/navigation";
import { useTransition } from "react";
import type { MenuProps } from "antd";
import { Dropdown, Space } from "antd";
import {
GlobeAltIcon} from "@heroicons/react/24/outline";
export default function LocalSwitcher() {
const items: MenuProps["items"] = [
{
label: "🇺🇸 English",
key: "en",
},
{
label: "🇷🇺 Русский",
key: "ru",
},
{
label: "🇺🇿 O`zbek",
key: "uz",
},
];
const router = useRouter();
console.log(router);
const [isPending, startTransition] = useTransition();
const onClick: MenuProps['onClick'] = ({ key }) => {
const nextLocale = key;
startTransition(() => {
router.replace(`/${nextLocale}`);
});
};
return (
<>
<span>
<Dropdown
menu={{
items,
onClick,
}}
trigger={["click"]}
>
<Space>
<GlobeAltIcon className="h-6 w-6 cursor-pointer globe-icon"/>
</Space>
</Dropdown>
</span>
</>
);
}
这里是 next-itnl 中间件
import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
// A list of all locales that are supported
locales: ['en', 'ru', 'uz'],
// Used when no locale matches
defaultLocale: 'en'
});
export const config = {
// Match only internationalized pathnames
matcher: [
'/((?!api|_next|_vercel|.*\\..*).*)',
'/([\\w-]+)?/users/(.+)',
'/([\\w-]+)?(/beverage/.*)'
]
};
附注这里提供的解决方案对我不起作用
您面临的问题可能是由于您的
LocalSwitcher
组件中如何实现语言切换造成的。
router.replace(/${nextLocale});
函数中的 onClick
调用可以有效地将用户导航到所选语言环境的站点根目录(主页),但除了更改语言环境之外,它不会保留当前 URL 路径的其余部分。要解决此问题,您应该修改此逻辑以仅动态替换 URL 的区域设置部分,保持路径的其余部分不变。
我更新了你的
onClick
功能。
const onClick: MenuProps['onClick'] = ({ key }) => {
const nextLocale = key;
// Build the new path by replacing the current locale with the nextLocale
// while keeping the rest of the path unchanged.
const newPath = router.asPath.replace(/^\/[a-z]{2}(\/|$)/, `/${nextLocale}/`);
startTransition(() => {
// Use the newPath for navigation instead of just `/${nextLocale}`
router.replace(newPath, newPath, { locale: nextLocale });
});
};