K
Kinde11mo ago
ruby

redirect from root "/" with middleware in next.js

I want to make a classic stuff, i have a SaaS with a landing page and some routes, a login and after auth here then you are redirect to dashboard... until here everything okay, but i want to make like vercel, is you are authenticate and you go to vercel.com then they redirect you to /dashboard, easy i think... but i cant be able to do that, if i include "/" in the matcher, i am forced to move to login page... and if not include then the function inside middleware is not execute... currently i have this, i prefer have everything about protected routes manage in middleware so i dont really want to explore another fix in the main page or in every single routes of my web...
No description
5 Replies
MALEV0L3NT
MALEV0L3NT11mo ago
I'm not sure if there is a way to fix this purely in middleware, and I know you said you'd like to handle it all in middleware (which makes sense), but I think there is a pretty easy way to do this where you only have to edit one extra file (the index page). You can keep your current middleware as it is, but in your index ("/") page, do something like this:
if (await isAuthenticated()) {
redirect("/dashboard");
}
if (await isAuthenticated()) {
redirect("/dashboard");
}
This way, you still use the middleware for all the other pages you add, it's not much extra code and only in one extra file, I think this would work pretty well
ruby
rubyOP11mo ago
Yes, its a clean fix, but i have to add to the rest of pages (/aboutUs, /contact, /pricing...), for me, make sense its always go inside the middleware and you have a variable like clerk for control the public pages and his management
MALEV0L3NT
MALEV0L3NT11mo ago
Ah I see, I didn't realise you had more pages like that, I understand What does req.kindeAuth give you? Is it a boolean telling you if you're authenticated?
// middleware.ts
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextRequest, NextResponse } from "next/server";

interface KindeRequest extends NextRequest {
kindeAuth: any;
}

export default function middleware(req: KindeRequest) {
if (!["/", "/pricing"].includes(req.url)) {
return withAuth(req);
}

if (req.kindeAuth) {
return NextResponse.redirect(new URL("/dashboard", req.url));
}

return NextResponse.next();
}

export const config = {
matcher: ["/", "/pricing", "/dashboard"],
};
// middleware.ts
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextRequest, NextResponse } from "next/server";

interface KindeRequest extends NextRequest {
kindeAuth: any;
}

export default function middleware(req: KindeRequest) {
if (!["/", "/pricing"].includes(req.url)) {
return withAuth(req);
}

if (req.kindeAuth) {
return NextResponse.redirect(new URL("/dashboard", req.url));
}

return NextResponse.next();
}

export const config = {
matcher: ["/", "/pricing", "/dashboard"],
};
@ruby I haven't tested this at all (I'm at work and am unable to test rn), but would this (or something similar) work? I was thinking of setting my website up like this too but I've instead opted to go the route of separate subdomains for the marketing site and platform site
ruby
rubyOP11mo ago
dont work, probably because you cant use req.kindeAuth without wrapper the middleware with "withAuth()"
MALEV0L3NT
MALEV0L3NT10mo ago
What's the error message you're getting? I've done some testing and refactoring, I think this should work how you want it to:
// middleware.ts
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
import { NextRequest, NextResponse } from "next/server";

export default async function middleware(req: NextRequest) {
const { isAuthenticated } = getKindeServerSession();

if (!["/", "/pricing"].includes(req.nextUrl.pathname)) {
return withAuth(req);
}

if (await isAuthenticated()) {
return NextResponse.redirect(new URL("/dashboard", req.url));
}

return NextResponse.next();
}

export const config = {
matcher: ["/", "/pricing", "/dashboard"],
};
// middleware.ts
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
import { NextRequest, NextResponse } from "next/server";

export default async function middleware(req: NextRequest) {
const { isAuthenticated } = getKindeServerSession();

if (!["/", "/pricing"].includes(req.nextUrl.pathname)) {
return withAuth(req);
}

if (await isAuthenticated()) {
return NextResponse.redirect(new URL("/dashboard", req.url));
}

return NextResponse.next();
}

export const config = {
matcher: ["/", "/pricing", "/dashboard"],
};
Middleware runs on the sever so we can technically use getKindeServerSession in the middleware Hey @ruby, did you have any luck with this?
Want results from more Discord servers?
Add your server