Issue with Auth api routes working alongside localizaztion
Answered
Spectacled bear posted this in #help-forum
Spectacled bearOP
OK, here's my weird question but I don't understand how this works, here's part of my current app structure:
src
app/[lang]
api
(auth)/[...nextauth]/route.ts
(see img)
the way it woirks is, it appends /en or /el to the url depending on the locale (so instead of /portfolio, it's now /en/portfolio || /el/portfolio)
Should I be keeping the api routes like that though? for example, for nextauth, the route becomes /en/api/auth/providers instead of being /api/auth/providers
the above route should eb returning json with my providers, but it doesnt, instead it returns "bad request".
Should I be excluding api routes from that locale rule?
src
app/[lang]
api
(auth)/[...nextauth]/route.ts
(see img)
the way it woirks is, it appends /en or /el to the url depending on the locale (so instead of /portfolio, it's now /en/portfolio || /el/portfolio)
Should I be keeping the api routes like that though? for example, for nextauth, the route becomes /en/api/auth/providers instead of being /api/auth/providers
the above route should eb returning json with my providers, but it doesnt, instead it returns "bad request".
Should I be excluding api routes from that locale rule?
Answered by Spectacled bear
added
to stop middleware from redirecting /[locale]/api/ urls, moved api routes outside of /[lang] (/app/[lang]/api -> /app/api and /app/[locale]
if (request.url.includes("/api/")) {
return;
}to stop middleware from redirecting /[locale]/api/ urls, moved api routes outside of /[lang] (/app/[lang]/api -> /app/api and /app/[locale]
2 Replies
Spectacled bearOP
middleware.ts:
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { i18n } from '../i18n-config';
import { match as matchLocale } from '@formatjs/intl-localematcher';
import Negotiator from 'negotiator';
function getLocale(request: NextRequest): string | undefined {
// Negotiator expects plain object so we need to transform headers
const negotiatorHeaders: Record<string, string> = {};
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
// Use negotiator and intl-localematcher to get best locale
let languages = new Negotiator({ headers: negotiatorHeaders }).languages();
// @ts-ignore locales are readonly
const locales: string[] = i18n.locales;
return matchLocale(languages, locales, i18n.defaultLocale);
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
// `/_next/` and `/api/` are ignored by the watcher, but we need to ignore files in `public` manually.
// If you have one
if (
[
'/manifest.json',
'/favicon.ico',
// Your other files in `public`
].includes(pathname)
)
return;
// Check if there is any supported locale in the pathname
const pathnameIsMissingLocale = i18n.locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
// Redirect if there is no locale
if (pathnameIsMissingLocale) {
const locale = getLocale(request);
// e.g. incoming request is /products
// The new URL is now /en-US/products
return NextResponse.redirect(new URL(`/${locale}/${pathname}`, request.url));
}
}
import { auth } from './auth';
export default auth((request: NextRequest) => {
console.log("ROUTE: ", request.nextUrl.pathname);
})
export const config = {
matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
};Spectacled bearOP
added
to stop middleware from redirecting /[locale]/api/ urls, moved api routes outside of /[lang] (/app/[lang]/api -> /app/api and /app/[locale]
if (request.url.includes("/api/")) {
return;
}to stop middleware from redirecting /[locale]/api/ urls, moved api routes outside of /[lang] (/app/[lang]/api -> /app/api and /app/[locale]
Answer