Fab*_*tis 8 internationalization reactjs next.js next-i18next next.js13
我正在努力让本地化not-found页面与 NextJS 13 (app-dir) 一起使用。我正在遵循国际化的官方指南以及我在 GitHub 上找到的解决方案。
[locale]
-- [...not-found]
- page.tsx <- empty page, just calls notFound() (catch-all segment)
-- (browse)
- someFolder1 <- may multiple pages and maybe nested layouts
- layout.tsx
-- (public)
- someFolder2
- layout.tsx
-- (private)
- someFolder3
- layout.tsx
-- layout.tsx
-- not-found.tsx <- should be served for all notFound() errors (including catch-all segment)
Run Code Online (Sandbox Code Playgroud)
当我notFound从任何路由组调用该方法或访问不匹配的路由时;我收到一条错误消息:Unsupported Server Component type: Null。这看起来很奇怪,因为这两个文件肯定都有一个反应组件作为默认导出。
import { notFound } from "next/navigation";
export default function CatchAllUnmatched(): JSX.Element {
notFound();
return <></>;
}
Run Code Online (Sandbox Code Playgroud)
我还尝试通过X-Language-Preference在中间件文件中添加的自定义属性向每个响应附加标头。在此过程中,我已将根布局移动为应用程序文件夹的直接后代,并检索区域设置,如下所示:
[locale]
-- [...not-found]
- page.tsx <- empty page, just calls notFound() (catch-all segment)
-- (browse)
- someFolder1 <- may multiple pages and maybe nested layouts
- layout.tsx
-- (public)
- someFolder2
- layout.tsx
-- (private)
- someFolder3
- layout.tsx
-- layout.tsx
-- not-found.tsx <- should be served for all notFound() errors (including catch-all segment)
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是,例如lang,主 html 标签上的属性不会在客户端导航上重置。而且404页面只有在访问不匹配的路由时才会显示,调用该方法仍然会导致相同的错误。所以这个解决方案也是不可行的。/de/frnotFound
显示工作国际化示例的真实世界示例的任何资源,包括多语言未找到页面,最好还使用具有嵌套布局的路由组。
Unsupported Server Component type: Null当两个文件肯定都有一个反应组件作为默认导出时,我遇到错误的可能原因。
如果您需要更多上下文、代码或任何关于一般设置不清楚的内容,只需发表评论,我将更新原始问题以满足要求。
如果有人在类似的高级用例中遇到这个问题,我现在终于有了解决方案。使用第二种方法是解决这个问题的正确方法。
将根布局移出文件夹并定义一个包含所有 UI 的[locale]全局文件。not-found.tsx然后,您可以在布局内调用以下函数来检索区域设置:
export const getLocale = cache((): Language => {
const preference = headers().get("X-Language-Preference");
return (preference ?? fallbackLanguage) as Language;
});
Run Code Online (Sandbox Code Playgroud)
向通过中间件传递的每个响应添加X-Language-Preference标头(或您想要的名称),在这里您可以定义自己的解析策略来检索应保存的区域设置。
const headerName = "X-Language-Preference";
function getRequestLocale(request: NextRequest) {
// ...
}
export default async function middleware(request: NextRequest) {
const locale = getRequestLocale(request);
const response = NextResponse.next();
response.headers.set(headerName, locale);
return response;
}
Run Code Online (Sandbox Code Playgroud)
lang根布局组件中的标签例如,在从 /de 到 /fr 的客户端导航上,主 html 标签上的 lang 属性不会重置
正如我在最初的问题中提到的。更新后此问题仍然存在,但我创建了一个名为的客户端组件,HTML该组件将从 URL 解析区域设置,或回退到 HTML 标记的方向和语言属性的默认区域设置。
interface Props extends React.HTMLAttributes<HTMLHtmlElement> {}
const HTML = memo(function HTML(props: Props): JSX.Element {
const locale = useLocale();
return <html lang={locale} dir={dir(locale)} {...props} />;
});
export default HTML;
export type { Props as HTMLProps };
Run Code Online (Sandbox Code Playgroud)
该useLanguage钩子尝试从 useParams 钩子、usePathname 钩子解析区域设置,最后回退到默认区域设置。这是我使用过的实现:
export default function useLocale(): Language {
const params = useParams();
const pathname = usePathname();
const localeFromParams = useMemo(() => {
return params?.locale as Language | undefined;
}, [params.locale]);
const localeFromPathname = useMemo(() => {
return pathname?.split?.("/")?.[1] as Language | undefined;
}, [pathname]);
const finalLocale = useMemo(() => {
const decision = localeFromParams ?? localeFromPathname;
if (!!decision && languages.includes(decision)) return decision;
return fallbackLanguage;
}, [localeFromParams, localeFromPathname]);
return finalLocale;
}
Run Code Online (Sandbox Code Playgroud)
更新到包含此 PR 的版本 v13.4.12 后,第二个解决方案突然开始工作,可能与错误或不需要的行为有关。
| 归档时间: |
|
| 查看次数: |
1741 次 |
| 最近记录: |