Assistance Needed with Implementing Localization in Next.js with Payload CMS 3.0 #9435
-
Hi, Friends! I'm developing a web application using Payload CMS 3.0, incorporating the website template for a portion of the app. My goal is to implement localization by structuring my URLs to include locale codes, such as:
While attempting to set up dynamic routing with ProblemI'm encountering routing conflicts when setting up
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 11 replies
-
If you'd like to share an example repo for how you're currently doing it, I'd be happy to take a look. This thing is something I've done for quite a few projects and I do run things a bit differently. In any case, I also have a public repo with an older version of Payload, when it was in beta. I haven't gotten the chance to update it yet, as it's just a hobby project. But, it may still be enough to get you going. |
Beta Was this translation helpful? Give feedback.
-
Hey! Same here. I started learning Payload 3.0. |
Beta Was this translation helpful? Give feedback.
-
I'm also trying to integrate next-intl into my payload project, but haven't managed to combine the next-intl middleware with mine yet. has anyone had a similar case and could help? I'm pretty new to nextjs and payload, probably there is a better approach to do this? here's my custom middleware.ts export const middleware = async (request: NextRequest) => {
// ---------------------------------------------------------------------------------
// header anreichern
// ---------------------------------------------------------------------------------
const requestHeaders = request.headers;
const modifiedHeaders = new Headers(requestHeaders);
const host = requestHeaders.get('host') ?? '';
const protocol = requestHeaders.get('x-forwarded-proto') ?? 'https';
const hostname = host.split(':')[0];
const origin = `${protocol}://${host}`;
const {pathname, searchParams} = request.nextUrl;
const searchParamsString = searchParams.toString() ? `?${searchParams.toString()}` : '';
const customHeaders = [
{name: X_HEADER_DOMAIN, value: hostname},
{name: X_HEADER_PATHNAME, value: pathname},
{name: X_HEADER_BASE_URL, value: origin},
{name: X_HEADER_SEARCH_PARAMS, value: searchParamsString},
{name: X_HEADER_LOCALE, value: searchParams.get('locale')},
{name: X_HEADER_DRAFT_MODE, value: searchParams.get('draftMode')},
{name: X_HEADER_LIVE_PREVIEW, value: searchParams.get('livePreview')},
{name: X_HEADER_REDIRECT_BACK, value: searchParams.get('redirectBack')},
];
customHeaders.forEach((header) => {
if (header.value) {
modifiedHeaders.set(header.name, header.value);
}
});
const newResponse = NextResponse.next({
request: {
headers: modifiedHeaders,
},
});
// ---------------------------------------------------------------------------------
// folgende routen sollen nicht weiter bearbeitet werden
// ---------------------------------------------------------------------------------
if (
pathname.startsWith(ROUTE_API) ||
pathname.startsWith(ROUTE_STATIC) ||
pathname.startsWith(ROUTE_ADMIN) ||
pathname.startsWith(ROUTE_NEXT) ||
/\.(.*)$/.test(pathname) // dateien im "public" ordner
) {
return newResponse;
}
// ---------------------------------------------------------------------------------
// sicherstellen das nur die tenant hauptdomain verwendet wird
// ---------------------------------------------------------------------------------
try {
const result = await typedFetch<GetPrimaryDomainResponse>(`${origin}${ROUTE_API}/tenants/primarydomain`, {
headers: {
[X_HEADER_DOMAIN]: hostname,
},
});
const primaryDomain = result.json.primaryDomain;
if (primaryDomain && primaryDomain !== hostname) {
const primaryDomainUrl = new URL(origin);
primaryDomainUrl.hostname = primaryDomain;
return NextResponse.redirect(primaryDomainUrl.toString(), {
status: 301,
});
}
} catch (err) {
console.warn('problem while primary domain redirect', err);
}
// ---------------------------------------------------------------------------------
// dauerhaft geschützte routen absichern
// ---------------------------------------------------------------------------------
const loggedInUser = await getLoggedInUser();
const protectedRoutes = ['/du-kommst-hier-nicht-rein'];
if (!loggedInUser && protectedRoutes.includes(pathname)) {
try {
const redirectUrl = new URL(origin);
const redirectSearchParams = new URLSearchParams({
redirectBack: encodeURI(pathname + searchParamsString),
});
redirectUrl.pathname = ROUTE_LOGIN;
redirectUrl.search = redirectSearchParams.toString();
return NextResponse.redirect(redirectUrl.toString());
} catch (err) {
console.warn('problem while redirecting protected route to login', err);
}
}
return newResponse;
}; |
Beta Was this translation helpful? Give feedback.
If you'd like to share an example repo for how you're currently doing it, I'd be happy to take a look. This thing is something I've done for quite a few projects and
next-intl
is usually my preference.I do run things a bit differently. In any case, I also have a public repo with an older version of Payload, when it was in beta. I haven't gotten the chance to update it yet, as it's just a hobby project. But, it may still be enough to get you going.
https://github.com/conqdb/conqdb/tree/main/apps/webI forgot, that one doesn't have completely dynamic pages, my bad!