Replies: 7 comments 6 replies
-
Did you find a solution ? |
Beta Was this translation helpful? Give feedback.
-
Did you find a solution? Also running into this |
Beta Was this translation helpful? Give feedback.
-
Actually I couldn't find any sloutions for this, to be honest I didn't try but I changed to clerck js authentication and it worked |
Beta Was this translation helpful? Give feedback.
-
How can I exclude dynamic routes from the middleware |
Beta Was this translation helpful? Give feedback.
-
This worked for me "next": "^14.1.0",
"react": "18.2.0",
"next-auth": "5.0.0-beta.13",
"next-intl": "^3.4.2", import type { NextRequest } from "next/server"
import createIntlMiddleware from "next-intl/middleware"
import { auth } from "@/auth"
import { defaultLocale, localePrefix, locales } from "./messages/config"
const publicPages = [
"/",
"/sign-in",
"/sign-up",
"/forgot-password",
"/reset-password",
"/unauthorized",
"/contact",
"/about",
"/help",
"/privacy-policy",
"/terms-of-service",
"/cookie-policy",
"/end-user-license-agreement"
]
const intlMiddleware = createIntlMiddleware({
locales,
defaultLocale,
localePrefix
})
const authMiddleware = auth((req) => {
// private routes here
const session = req.auth
if (session) {
return intlMiddleware(req)
}
})
export default function middleware(req: NextRequest) {
const publicPathnameRegex = RegExp(
`^(/(${locales.join("|")}))?(${publicPages.flatMap((p) => (p === "/" ? ["", "/"] : p)).join("|")})/?$`,
"i"
)
const isPublicPage = publicPathnameRegex.test(req.nextUrl.pathname)
if (isPublicPage) {
return intlMiddleware(req)
} else {
return (authMiddleware as any)(req)
}
}
export const config = {
matcher: ["/((?!api|_next|.*\\..*).*)"]
} |
Beta Was this translation helpful? Give feedback.
-
Let nextAuth handle it first and then pass that request to I18nMiddlewareimport { getToken } from "next-auth/jwt";
import { withAuth } from "next-auth/middleware";
import { createI18nMiddleware } from "next-international/middleware";
const I18nMiddleware = createI18nMiddleware({
locales: ["en", "fa"],
defaultLocale: "fa",
});
const withAuthMiddleware = withAuth(
async function middleware(req) {
const token = await getToken({ req });
const isAuth = !!token;
const isAuthPage =
req.nextUrl.pathname.startsWith("/login") ||
req.nextUrl.pathname.startsWith("/register");
if (isAuthPage) {
if (isAuth) {
return I18nMiddleware(req);
// return NextResponse.redirect(new URL("/dashboard", req.url));
}
return null;
}
if (!isAuth) {
let from = req.nextUrl.pathname;
if (req.nextUrl.search) {
from += req.nextUrl.search;
}
return I18nMiddleware(req);
// return NextResponse.redirect(
// new URL(`/login?from=${encodeURIComponent(from)}`, req.url),
// );
}
},
{
callbacks: {
async authorized() {
// This is a work-around for handling redirect on auth pages.
// We return true here so that the middleware function above
// is always called.
return true;
},
},
},
);
export default withAuthMiddleware;
export const config = {
matcher: [
"/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)",
],
}; |
Beta Was this translation helpful? Give feedback.
-
Combining NextAuth (v5) and Next-Intl middleware in a Next.js application can be efficiently achieved by chaining middleware functions. This approach allows you to manage authentication and internationalization in a modular and maintainable manner. Below is a step-by-step guide on how to implement this:
Step 1: Create a Chain UtilityFirst, create a // chain.ts
import { NextMiddlewareResult } from 'next/dist/server/web/types'
import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'
export type CustomMiddleware = (
request: NextRequest,
event: NextFetchEvent,
response: NextResponse
) => NextMiddlewareResult | Promise<NextMiddlewareResult>
type MiddlewareFactory = (middleware: CustomMiddleware) => CustomMiddleware
export function chain(
functions: MiddlewareFactory[],
index = 0
): CustomMiddleware {
const current = functions[index]
if (current) {
const next = chain(functions, index + 1)
return current(next)
}
return (
request: NextRequest,
event: NextFetchEvent,
response: NextResponse
) => {
return response
}
} Step 2: Implement the Internationalization MiddlewareCreate a file // withI18nMiddleware.ts
import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'
import { i18n } from '@/i18n.config'
import { match as matchLocale } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
import { CustomMiddleware } from './chain'
function getLocale(request: NextRequest): string | undefined {
const negotiatorHeaders: Record<string, string> = {}
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value))
// @ts-ignore locales are readonly
const locales: string[] = i18n.locales
const languages = new Negotiator({ headers: negotiatorHeaders }).languages()
const locale = matchLocale(languages, locales, i18n.defaultLocale)
return locale
}
export function withI18nMiddleware(middleware: CustomMiddleware) {
return async (
request: NextRequest,
event: NextFetchEvent,
response: NextResponse
) => {
const pathname = request.nextUrl.pathname
const pathnameIsMissingLocale = i18n.locales.every(
locale => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
)
if (pathnameIsMissingLocale) {
const locale = getLocale(request)
return NextResponse.redirect(
new URL(
`/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`,
request.url
)
)
}
return middleware(request, event, response)
}
} Step 3: Implement the Authentication MiddlewareCreate a file // withAuthMiddleware.ts
import { getToken } from 'next-auth/jwt';
import { NextResponse } from 'next/server';
import type { NextFetchEvent, NextRequest } from 'next/server';
import { CustomMiddleware } from './chain';
export function withAuthMiddleware(middleware: CustomMiddleware): CustomMiddleware {
return async (request: NextRequest, event: NextFetchEvent, response: NextResponse) => {
const token = await getToken({ req: request, secret: process.env.NEXTAUTH_SECRET });
if (!token) {
return NextResponse.redirect(new URL('/api/auth/signin', request.url));
}
return middleware(request, event, response);
};
} Step 4: Combine the MiddlewaresCreate a // middleware.ts
import { chain } from '@/middlewares/chain'
import { withI18nMiddleware } from '@/middlewares/withI18nMiddleware'
import { withAuthMiddleware } from '@/middlewares/withAuthMiddleware'
export default chain([withI18nMiddleware, withAuthMiddleware])
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico|images).*)'],
} Explanation
By following these steps, you can efficiently combine NextAuth and Next-Intl middleware in your Next.js application, ensuring both authentication and internationalization are seamlessly handled. |
Beta Was this translation helpful? Give feedback.
-
Hello,
I think in the Next Auth(V5) which is released recently they have changed a couple of things so the pervious workarounds does not really help in my knowledge. My middleware code is down below and i really don't know how to chain this two middleware. Can I request a reproduction of this code Thanks again
Beta Was this translation helpful? Give feedback.
All reactions