In this tutorial, we will discuss a very important aspect of web applications and how to implement protected routes in the Next Js application.
Protected routes play a key role in managing user access and ensuring the security of web applications. This article will dive deep into the concept of protected routes in Next.js, illustrating how to implement them in a sample application.
Furthermore, we will explore various use cases with examples, share tips and tricks, and discuss solutions to common issues that arise with protected routes. Whether you are a seasoned developer or a beginner, this guide seeks to equip you with the knowledge and skills to efficiently utilize protected routes in Next.js.
Next.js is a powerful, server-side rendering framework for React.js. It brings a pack of benefits like automatic routing, static exporting, and hot code reloading, which makes it a popular choice among developers.
Protected routes are an essential feature of any web application that requires user authentication. They prevent unauthorized access to certain pages of your application, redirecting users to an authentication page if necessary. Implementing this feature in Next.js applications is a common practice and can greatly enhance application security.
How to Implement Protected Routes in Next.js Application?
Follow these quick steps to implement protected routes easily in your Nextjs application:
[lwptoc]
Step 1 – Setup Application
To exhibit protected routes in Next.js, let’s create a simple application. We will have a login page, a dashboard, and a user profile page. The dashboard and profile page will be our protected routes that should only be accessible to authenticated users.
1. Setting Up the Next.js Application
First, install Node.js and npm on your system if you haven’t done already. Next, install the create-next-app
tool, which is a CLI tool for creating new Next.js applications.
npm install -g create-next-app
Now, create a new Next.js application. In this case, the application is named “nextjs-protected-routes”. You can selected following suggested options or go as per your needs:
$ npx create-next-app nextjs-protected-routes
? Would you like to use TypeScript with this project? » No
? Would you like to use ESLint with this project? » Yes
? Would you like to use Tailwind CSS with this project? » No
? Would you like to use `src/` directory with this project? » Yes
? Use App Router (recommended)? » Yes
? Would you like to customize the default import alias? » No
2. Creating the Pages
Next, we will create three pages — login.js, dashboard.js, and profile.js — under the pages directory. To do this, add the following code:
Login Page:
// pages/login.js
export default function Login() {
return (
<div>
<h2>Login Page</h2>
// Add your login form here
</div>
);
}
Dashboard Page
// pages/dashboard.js
export default function Dashboard() {
return (
<div>
<h2>Dashboard</h2>
// Add your dashboard content here
</div>
);
}
Profile Page
// pages/profile.js
export default function Profile() {
return (
<div>
<h2>Profile Page</h2>
// Add your profile content here
</div>
);
}
Step 3 – Create a mock authentication function
For the purpose of testing, you can create a mock authentication function. This function will simulate the process of user login.
Here is an example implementation:
// utils/auth.js
export function authenticate(username, password) {
if (username === 'test' && password === 'test') {
localStorage.setItem('user', JSON.stringify({ username }));
return true;
}
return false;
}
If the username and password match to ‘test’, a localStorage key will be set to allow visit the protected pages.
Step 4 – Update the Login Page
Update your login page to include a form that accepts a username and password. When the form is submitted, call the authenticate
function. If the authentication is successful, redirect the user to one of the protected pages.
// pages/login.js
import { authenticate } from '../utils/auth';
import { useRouter } from 'next/router';
export default function Login() {
const router = useRouter();
const handleSubmit = (event) => {
event.preventDefault();
const username = event.target.username.value;
const password = event.target.password.value;
if (authenticate(username, password)) {
router.push('/dashboard');
} else {
// handle login error
}
};
return (
<div>
<h2>Login Page</h2>
<form onSubmit={handleSubmit}>
<input name="username" type="text" placeholder="Username" required />
<input name="password" type="password" placeholder="Password" required />
<button type="submit">Log in</button>
</form>
</div>
);
}
Step 2 – Implementing Protected Routes in Next.js
To implement protected routes, you can leverage Higher Order Components (HOCs) or use Next.js server-side rendering capabilities. For simplicity, let’s use a HOC that will check if a user is authenticated before rendering a page.
// hoc/withAuth.js
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function withAuth(Component) {
return function ProtectedRoute({ ...props }) {
const router = useRouter();
const user = JSON.parse(localStorage.getItem('user'));
const userIsAuthenticated = user !== null;
useEffect(() => {
if (!userIsAuthenticated) {
router.push('/login');
}
}, [userIsAuthenticated, router]);
return <Component {...props} />;
};
}
Then, in your protected pages (dashboard.js and profile.js), you can use this HOC as follows:
Dashboard page
// pages/dashboard.js
import withAuth from '../hoc/withAuth';
function Dashboard() {
<h2>Dashboard</h2>
// Add your dashboard content here
}
export default withAuth(Dashboard);
Similarly, wrap the Profile with withAuth
HOC
// pages/profile.js
import withAuth from '../hoc/withAuth';
function Profile() {
<h2>Profile Page</h2>
// Add your profile content here
}
export default withAuth(Profile);
Your protected routes are now set up. If a user attempts to access the Dashboard or Profile page without being authenticated, they will be redirected to the Login page.
Step 3 – Run the Application
Start your application (npm run dev
), and navigate to one of the protected pages (e.g., http://localhost:3000/dashboard
). You should be redirected to the login page. Enter the username and password (“test” and “test”), and submit the form. You should now be redirected to the dashboard page.
Various Use Cases of Protected Routes:
1. E-commerce Application: In an e-commerce application, protected routes are crucial. Certain pages, such as user account details, order history, and checkout pages, should only be accessible to authenticated users. Using Next.js protected routes, you can easily ensure only logged-in users can access these sensitive pages.
2. Blogging Platform: If you’re developing a blogging platform, you might want to restrict certain actions, like posting a blog or commenting, to registered users. Protected routes can ensure these actions are only accessible to those who have signed in.
3. Admin Panel: An admin panel is a classic example of a protected route. Only users with admin privileges should be able to access this part of your application. With Next.js, you can easily implement this kind of authorization.
Common Issues and Solutions
Following are some common issues which we can face while implementing the protected route. Let’s have a look with their possible solutions at hand:
1. Flash of Unwanted Content (FOUC): This occurs when a protected page is briefly visible before the redirect to the login page occurs. To mitigate this, use a loading state during the authentication check process.
2. Unnecessary Redirects: Sometimes, even after successful login, the user might be redirected to the login page. This could be due to the authentication state not updating promptly. To solve this, ensure you update the authentication state before redirecting users after login.
3. Protecting API Routes: Apart from protecting client-side routes, you might also need to protect your API routes. Next.js API routes can be secured using various strategies like JWT or session-based authentication.
Conclusion
Implementing protected routes is an integral part of developing a secure web application. With Next.js, this task becomes simple and efficient. This guide discussed how to create a sample application with protected routes, various use cases, and tips for avoiding common issues. With these insights, you should be able to leverage the power of Next.js to build robust and secure applications.