Next.js Discord

Discord Forum

NextAuth route.ts with localized routing

Unanswered
Giant Chinchilla posted this in #help-forum
Open in Discord
Giant ChinchillaOP
I have app router with app/[lang] and everything inside it with middleware managing the localization. I seem to have a problem adding auth. I added app/[lang]/api/auth/[...nextauth]/route.ts, but it doesn't seem to reach it (added console log in route.ts) when I call signIn from a login form.

Is the problem in the localization middleware or the next auth setup?

5 Replies

Giant ChinchillaOP
LoginForm.tsx
import { signIn } from "next-auth/react";

const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    const response = await signIn("credentials", {
        email: form.email,
        password: form.password,
        redirect: false,
    });
    console.log(response);
};

what I get output in terminal:
 GET /api/auth/providers 404 in 17ms
 GET /api/auth/error 404 in 17ms

for some reason it does GET on /api/auth/providers
route.ts
import NextAuth from "next-auth";
import { authOptions } from "@/auth.config";
 
const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
auth.config.ts
import { NextAuthConfig  } from "next-auth";
import Credentials from "next-auth/providers/credentials";
// import { authApi } from "@/api";

export const authOptions: NextAuthConfig = {
    pages: {
        signIn: '/auth',
        signOut: '/auth',
    },
    callbacks: {
        authorized({ auth, request: { nextUrl } }) {
            // const isLoggedIn = !!auth?.user;
            // const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');

            // if (isOnDashboard) {
            //     if (isLoggedIn) return true;
            //     return false; // Redirect unauthenticated users to login page
            // } else if (isLoggedIn) {
            //     return Response.redirect(new URL('/dashboard', nextUrl));
            // }

            return true;
        },
    },
    providers: [
        Credentials({
            async authorize(credentials) {
                console.log(credentials);

                if (credentials) {
                    if ("email" in credentials && "password" in credentials) {
                        const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_UR}/auth/login`, {
                            method: 'POST',
                            headers: {
                                'Content-type': 'application/json',
                                'Accept': 'application/json',
                            },
                            body: JSON.stringify(credentials),
                        });
                        console.log(response);
                        // await authApi.login(credentials).then((res) => {
                        //     console.log(res);
                        // });

                        return null;
                    }
                }

                return null;
            },
        }),
    ],
};
middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { match as matchLocale } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";
import { i18n } from "../i18n-config";
import NextAuth from "next-auth";
import { authOptions } from "./auth.config";

const { auth } = NextAuth(authOptions);

export default auth(async 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 ([
        '/manifest.json',
        '/favicon.ico',
    ].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);
        const locale = i18n.defaultLocale;

        // e.g. incoming request is /products
        // The new URL is now /en-US/products
        return NextResponse.redirect(
            new URL(
                `/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
                request.url,
            ),
        );
    }
});

export const config = {
    // Matcher ignoring `/_next/` and `/api/`
    matcher: ["/((?!api|_next/static|_next/image|favicon.ico|svg|images|fonts).*)"],
};
Giant ChinchillaOP
moving route.ts out of /app/[lang] and just under /app, now it reaches the route.ts, but I get 500 error which is different problem entirely