Best Practice: Mapping dynamic runtime locales to a fixed set of UI languages #2082
-
|
Hi everyone First off, thank you for your incredible work on this library. I'm looking for the recommended "best practice" for a specific use case involving dynamic "content markets" that map to a fixed set of "UI languages." My Requirements
My Proposed SolutionBased on the documentation for async middleware, my plan is to fetch the dynamic list of markets on every request (with caching). Here is my intended setup:
import { hasLocale, IntlErrorCode, type Locale } from "next-intl";
import { getRequestConfig } from "next-intl/server";
import { DEFAULT_LOCALE, getAllLocales } from "@/shared/api/get-all-locales";
export default getRequestConfig(async ({ requestLocale }) => {
const requested = await requestLocale;
const supportedLocales = await getAllLocales();
let locale: Locale = DEFAULT_LOCALE;
if (supportedLocales?.length && hasLocale(supportedLocales, requested)) {
locale = requested as Locale;
}
const uiLocale = locale === DEFAULT_LOCALE ? DEFAULT_LOCALE : "en";
return {
locale,
messages: (await import(`../../messages/${uiLocale}.json`)).default
});
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
import createMiddleware from "next-intl/middleware";
import { DEFAULT_LOCALE, getAllLocales } from "./shared/api/get-all-locales";
export default async function proxy(request: NextRequest) {
try {
const locales = await getAllLocales();
if (!locales?.length) return new NextResponse(null, { status: 404 });
const handleI18nRouting = createMiddleware({
locales,
defaultLocale: DEFAULT_LOCALE,
localePrefix: "as-needed",
});
return handleI18nRouting(request);
} catch (error) {
console.error("Error in proxy middleware:", error);
return new NextResponse(null, { status: 500 });
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - robots.txt (robots file)
* - sitemap.xml (sitemap file)
* - manifest.json (manifest file)
* - public (public folder)
* - . (all files in the public folder)
* - . (all files in the public folder)
*/
"/((?!_next/static|_next/image|public/|favicon.ico|robots.txt|sitemap.xml|manifest.json).*)",
],
};Here my routing system if it helps with anything: My QuestionIs this I want to ensure this is the most performant and correct pattern supported by Thank you for any clarification you can provide! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
That's an interesting use case! But yes, that looks really solid to me what you're describing. Basically,
In your case, 1 and 3 are the same though.
You can return all, some or none (i.e. As for navigation APIs, you can omit the Hope this helps! |
Beta Was this translation helpful? Give feedback.
That's an interesting use case! But yes, that looks really solid to me what you're describing.
Basically,
next-intlallows you to define all of these independently:In your case, 1 and 3 are the same though.
You can return all, some or none (i.e.
[]) locales fromgenerateStaticParamsfor static rendering. If (1) can change at runtime, you might want to be prepared to render an unexpected locale though (e.g. don't usedynamicParams = false). Bu…