Ok Intl has me confused as shit
Answered
Arinji posted this in #help-forum
ArinjiOP
import { match } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
const locales = ["en"];
const defaultLocale = "en";
function getLocale() {
const headers = { "accept-language": "en-US,en;q=0.5" };
const languages = new Negotiator({ headers }).languages();
const currentLocale = match(languages, locales, defaultLocale);
return currentLocale;
}
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
console.log(pathname);
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
console.log(pathnameHasLocale);
if (!pathnameHasLocale) {
let locale = getLocale();
request.nextUrl.pathname = `/${locale}${pathname}`;
if (locale === defaultLocale) return NextResponse.rewrite(request.nextUrl);
return NextResponse.redirect(request.nextUrl);
}
const pathnameWithoutLocale = (() => {
const parts = pathname.split("/");
console.log(parts);
parts.shift();
parts.shift();
return `/${parts.join("/")}`;
})();
if (pathnameWithoutLocale.startsWith("/admin/register")) {
console.log("RUN");
const redirectURL = request.nextUrl.searchParams.get("redirect");
const response = NextResponse.next();
if (redirectURL) {
response.cookies.set("redirect", redirectURL, { path: "/" });
}
return response;
}
if (request.nextUrl.pathname.indexOf("opengraph-image") !== -1)
return NextResponse.next();
return NextResponse.next();
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};It will stop at the rewrite section, and rewrite the pathname to /en/admin/register.
For any request made without the locale, it will return and only if the locale is present, the middleware will continue. Does this mean we cant do default locales lol?
Answered by Arinji
Ok found a solution, it might be scuffed.. but it works
import { match } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
const locales = ["en"];
const defaultLocale = "en";
function getLocale() {
const headers = { "accept-language": "en-US,en;q=0.5" };
const languages = new Negotiator({ headers }).languages();
const currentLocale = match(languages, locales, defaultLocale);
return currentLocale;
}
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
console.log(pathname);
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
console.log(pathnameHasLocale);
let response: NextResponse | undefined = undefined;4 Replies
ArinjiOP
Ok found a solution, it might be scuffed.. but it works
import { match } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
const locales = ["en"];
const defaultLocale = "en";
function getLocale() {
const headers = { "accept-language": "en-US,en;q=0.5" };
const languages = new Negotiator({ headers }).languages();
const currentLocale = match(languages, locales, defaultLocale);
return currentLocale;
}
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
console.log(pathname);
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
console.log(pathnameHasLocale);
let response: NextResponse | undefined = undefined;Answer
ArinjiOP
if (!pathnameHasLocale) {
const locale = getLocale();
request.nextUrl.pathname = `/${locale}${pathname}`;
response =
locale === defaultLocale
? NextResponse.rewrite(request.nextUrl)
: NextResponse.redirect(request.nextUrl);
}
const pathnameWithoutLocale = (() => {
const parts = pathname.split("/").filter(Boolean);
if (locales.includes(parts[0])) {
parts.shift();
}
return `/${parts.join("/")}`;
})();
console.log("HEE", pathnameWithoutLocale);
if (pathnameWithoutLocale.startsWith("/admin/register")) {
console.log("RUN");
const redirectURL = request.nextUrl.searchParams.get("redirect");
console.log(redirectURL);
if (redirectURL && response) {
response.cookies.set("redirect", redirectURL, { path: "/" });
} else if (redirectURL) {
const cookieResponse = NextResponse.next();
cookieResponse.cookies.set("redirect", redirectURL, { path: "/" });
return cookieResponse;
}
}
if (request.nextUrl.pathname.indexOf("opengraph-image") !== -1) {
return NextResponse.next();
}
console.log(response);
return response || NextResponse.next();
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};ArinjiOP
so how it works is that, if a locale is not set, so the pathname dosent start with /en, it will set the response variable with a rewrite to the new url. If it is set, nothing happens there.
Then we get the pathname without the locale.
For the admin check, we first get the redicrect url from the request. If we had planned to rewrite with the default locale, we add the cookie to the response, else we just directly redirect since the locale was already set from before.
And finally at the end we return the response if it was set, or just do NextResponse.next if it wasnt present.
Then we get the pathname without the locale.
For the admin check, we first get the redicrect url from the request. If we had planned to rewrite with the default locale, we add the cookie to the response, else we just directly redirect since the locale was already set from before.
And finally at the end we return the response if it was set, or just do NextResponse.next if it wasnt present.
@joulev mark if you get the time :D
thanks
thanks