Reputation: 3112
I'm developing a Next.JS app where a user should login to see the content.I want to redirect the user to '/' if their username and password are correct.However my implementation seems not working.
I searched on SO for questions regarding this,but all of them were talking about redirecting with getInitialProps
but it doesn't help me since I want to redirect user from my custom express server.
Login.js
async handleSubmit(event) {
event.preventDefault()
const { username, password } = this.state
try {
const response = await fetch('/log_in', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
})
}
catch (error) {
console.log(error)
}
}
server.js
app.post('/log_in', (req,res) => {
console.log(`login form data`);
console.log(`Username : ${req.body.username}`);
console.log(`password : ${req.body.password}`);
if(req.body.username == "user" && req.body.password == "123"){
res.redirect('/')
}
})
Upvotes: 46
Views: 89092
Reputation: 1
Try this.
import { NextResponse } from "next/server";
const redirects = {
"/introduction/getting-started": "/introduction/welcome",
};
export function middleware(request) {
const url = request.nextUrl.clone();
const path = url.pathname;
if (redirects[path]) {
url.pathname = redirects[path];
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: Object.keys(redirects),
};
Docs: https://nextjs.org/docs/app/building-your-application/routing/middleware
Upvotes: -1
Reputation: 2866
You'll want to leverage a redirect
function in your Server Components, Route Handlers, and Server Actions per the doc:
For instance, here's a sample for server components pulled from the docs, in a hypothetical app route of app/team/[id]/page.js
, with a server-side redirect to the /login
route if the team
object is falsy:
import { redirect } from 'next/navigation'
async function fetchTeam(id) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
This is now possible on Next.js 10+ without having to do any sort of response header manipulation directly. Use getServerSideProps
or getStaticProps
and return a redirect
key as the only value from it if your conditions are met:
export async function getServerSideProps(context) {
if(context.req.body.username == "user" && context.req.body.password == "123"){
return {
redirect: {
permanent: false,
destination: "/"
}
}
}
}
Upvotes: 86
Reputation: 63
After the Nextjs 13, if you are using App router then @bsplosion answer doesn't work the way it used to or I can say there is a better option for server side redirecting. i.e, redirect()
of next/navigation
.
It is explained very well here
Upvotes: 2
Reputation: 31
To those who are looking for GLOBAL server side redirects
getServerSideProps
. It cannot be used inside _app.js
file. This means we have to duplicate code for every page copying if (...) { ... return { redirect: {...} } }
blocks to every private page's getServerSideProps
functionIn _app
we need to create custom MyApp
component, because getInitialProps
doesn't work on _app
by default as it said here
// _app.tsx
import type { AppContext, AppProps } from "next/app";
import App from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
MyApp.getInitialProps = (appContext: AppContext) => {
const { res, query } = appContext.ctx;
// Load the page getInitiaProps
const pageProps = App.getInitialProps(appContext);
if (query.logged !== 'true') {
// On the server, we'll use an HTTP response to
// redirect with the status code of our choice.
// 307 is for temporary redirects.
res.writeHead(307, { location: `/app/login` });
res.end();
return {};
}
return { ...pageProps };
};
export default MyApp;
Example:
/app?logged=true
, I stay on the page(or any other page with logged=true
flag)./app
, I'm redirected to the login pageRef: https://github.com/vercel/next.js/discussions/14547#discussioncomment-387271
Upvotes: 0
Reputation: 2068
It's a good idea for SEO to redirect server side if you can (not for login like the questions mention).
But for things like user language etc it's probably a good idea to use server side redirects like this. ----- REMOVED since it was bad code --------
Update, I ended up with this as I did have some problems with headers already sent. Please let me know how this can be fixed as it's not the most ideal (although Google does understand it according to this article https://www.seroundtable.com/google-meta-refresh-redirects-work-25335.html)
export default function HomePage({ language }) {
return (
<Head>
<title>-</title>
<meta httpEquiv="refresh" content={`0;url=/${language}/discover/0`} />
</Head>
);
}
Update Nextjs is adding native support there is an RFC available: https://github.com/vercel/next.js/discussions/17078
Upvotes: 6