Closed cor-emble closed 1 year ago
I think you'll have to compose yourself the middleware, something like (not tested):
import { withAuth } from "next-auth/middleware";
import { createI18nMiddleware } from 'next-international/middleware'
import { NextRequest } from 'next/server'
const I18nMiddleware = createI18nMiddleware(['en', 'fr'] as const, 'fr')
const NextAuthMiddleware = withAuth({
pages: {
signIn: "/user/login",
},
});
export const config = {
matcher: ["/((?!api|user|static|favicon.ico).*)", "/"],
};
export default async function middleware(request) {
const i18nResponse = I18nMiddleware(request);
const nextAuthResponse = NextAuthMiddleware(request);
nextAuthResponse.cookies.add(i18nResponse.cookies.get('Next-Locale'))
nextAuthResponse.headers.set('X-Next-Locale', i18nResponse.headers.get('X-Next-Locale'))
return nextAuthResponse;
}
i have the same problem... help?
// middleware.ts
import { withAuth } from 'next-auth/middleware'
import { createI18nMiddleware } from 'next-international/middleware'
import { NextRequest } from 'next/server'
const I18nMiddleware = createI18nMiddleware(['pt', 'en'] as const, 'en', {
urlMappingStrategy: 'rewrite',
})
export const middleware = (request: NextRequest) => I18nMiddleware(request)
// eslint-disable-next-line @typescript-eslint/no-empty-function
export default withAuth(() => {}, {
callbacks: {
authorized: ({ req, token }: any) => {
const path = req.nextUrl.pathname
if (token?.error === 'RefreshAccessTokenError') return false
if (path.startsWith('/admin')) {
return token && token.roles && token.roles.includes('ADMIN')
}
return token !== null
},
},
})
export const config = {
matcher: [
'/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)',
'/admin/:path*',
],
}
Need some help with this too :/
Can anyone provide a minimal reproduction? I'm not familiar with next-auth using the App Router but it should be possible.
I don't use next-auth but I helped a friend using this code (not tested yet, reduced for minimalism)
import { withAuth } from "next-auth/middleware"
import { createI18nMiddleware } from 'next-international/middleware'
const I18nMiddleware = createI18nMiddleware({
locales: ['en', 'fr'],
defaultLocale: 'en',
})
export default withAuth(
function middleware(req) {
return I18nMiddleware(req)
}
)
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)'],
}
Tested working code here, GL with the typing issue...
import { withAuth } from 'next-auth/middleware';
import { createI18nMiddleware } from 'next-international/middleware';
import type { NextRequest } from 'next/server';
const i18nMiddleware = createI18nMiddleware({
locales: ['en'],
defaultLocale: 'en',
});
const authMiddleware = withAuth((requestWithAuth) =>
i18nMiddleware(requestWithAuth),
);
export default async function middleware(request: NextRequest) {
return request.nextUrl.pathname.includes('/admin')
? // @ts-expect-error This is a typing issue that I have no idea how to resolve, but the code works...
authMiddleware(request)
: i18nMiddleware(request);
}
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)'],
};
In order to have everything (except the api routes and statics) protected, the following middleware works:
import type { NextFetchEvent, NextRequest } from "next/server";
import { createI18nMiddleware } from "next-international/middleware";
import { NextRequestWithAuth, withAuth } from "next-auth/middleware";
const I18nMiddleware = createI18nMiddleware({
locales: ["en", "nl"],
defaultLocale: "en",
});
const authMiddleware = withAuth((requestWithAuth) =>
I18nMiddleware(requestWithAuth),
);
export default async function middleware(
request: NextRequest,
event: NextFetchEvent,
) {
return authMiddleware(request as NextRequestWithAuth, event);
}
export const config = {
// Matcher ignoring `/_next/` and `/api/`
matcher: ["/((?!api|_next/static|_next/image|favicon.ico|robots.txt).*)"],
};
Thnx all for the examples!
This is what i came up with and works in my case:
import { withAuth } from "next-auth/middleware";
import { createI18nMiddleware } from "next-international/middleware";
export const config = {
matcher: ["/((?!api|admin|auth|404|assets|favicon.ico).*)", "/"],
};
const i18nMiddleware = createI18nMiddleware({
locales: ["en", "nl"],
defaultLocale: "nl",
urlMappingStrategy: "rewrite",
});
export default withAuth(
function middleware(req) {
return i18nMiddleware(req);
},
{
pages: {
signIn: "/nl/user/login",
},
},
);
Thanks everyone for sharing code examples! I think we can close the issue now, feel free to open a new one if needed.
Hi!
We're in a process of migrating an older Next.js app with the pages dir to the new App router and are also moving from i18next to next-international.
The app uses Next auth for the authentication layer and besides the login and register pages all other pages need authentication. So we're using the next auth middleware as follows:
Does somebody has an example on how to combine this middleware with the next-international middleware?