I’m working on a Next.js application, and I have a specific page, let’s call it "thank-you," that I want to prevent users from accessing directly via the URL. However, I want to allow access to this page only through internal navigation within the app, such as clicking a button.
I’ve tried using a middleware function to redirect direct requests to the home page, and it works as expected. However, when I try to navigate to the "thank-you" page using client-side routing (e.g., router.push("/thank-you")), it still triggers the middleware and redirects to the home page.
Here’s a simplified version of the code:
Middleware Function (middleware.ts):
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL("/", request.url));
}
export const config = {
matcher: ["/thank-you"],
};
Button Click Handling (YourComponent.tsx):
import { useRouter } from "next/router";
export default function Home() {
const router = useRouter();
const handleButtonClick = () => {
router.push("/thank-you");
};
...
}
How can I prevent direct access to the "thank-you" page while allowing access through internal navigation within the app?
Any help or suggestions would be greatly appreciated!
UPDATE
I tried with getServerSideProps
and still have the same problem.
Redirect to home happens from button click as well.
export const getServerSideProps = () => {
return {
redirect: {
permanent: false,
destination: "/",
},
props: {},
};
};
2
Answers
This seems like auth-guard issue. Add AuthGuard in root folder. If using app Router it would be layout, and control access with redux or other state management.
I didn’t include but you also should change authRights.thankYou to false in auth guard or in thank you page.
Root Layout
AuthGuard
Component that redirects to Thank you.
Maybe this is a bit too simple, but why expose a route to the component when don’t want it accessible via a direct URL?
The simplest solution is to simply avoid the issue entirely and not expose an URL for the thank-you page. You can do this by creating a
<ThankYou />
component, and render that on the current page as part of some procedure.This can be done by toggling some state (
showThankYou
for example):Or by returning it as part of a more complicated process:
Because this doesn’t expose a route to the "thank you" page, users can only get there by following the procedure.