Open In App

Next JS Middleware: Extending Functionality in Your Application

Last Updated : 13 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Middleware plays an important role in creating backend applications which are used to intercept incoming requests, perform actions, and modify responses before send to routing handlers. In this article, we will understand middleware in Next.js by creating an authentication middleware.

Prerequisites:

What are Middlewares?

Middleware is a piece of code that redefines the functionality of your written logic. It enhances the logic and provides an additional capability. It has access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. Middleware modifies a request before it reaches the destination. It is very helpful in performing tasks like authentication and data manipulation.

Syntax:

// Define your middleware function
const myMiddleware = (req: Request, res: Response, next: NextFunction) => {
// Middleware logic
console.log('Middleware executed');
// Call the next middleware function in the stack
next();
};

Functioning of a Middleware

  • HOC Initialization – When using a middleware function with a component, the middleware function runs first.
  • Middleware Logic – Middleware contains special logic related to middleware purposes. This logic may be authentication, authorization, or data fetching.
  • Component Rendering – After the middleware logic runs, it decides whether to render a wrapped component or not.
  • Conditional Rendering – If the middleware allows, the wrapped component is rendered with necessary props.
  • Redirect or Alternative rendering – If the middleware logic denies rendering the wrapped component, the middleware performs a redirect to another page, an alternative component.

Example: In this example, We will secure the profile page within an authentication middleware with the help of a higher-order component (HOC) to envelop the profile page component. This higher-order component will interfere with the request to the profile page, ensuring that only users with valid credentials can access it.

Steps to Create a Next.js app

Step 1: Create a Next.js app by using the command provided below.

npx create-next-app next-middleware

m2

Enter into the app directory created.

cd next-middleware

Step 2: Create the required files and folders as suggested in file structure.

File Structure:

m1

file structure

The updated dependencies in package.json file will look like:

"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.1.0"
},
"devDependencies": {
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0"
}

Example: Add the following codes in the respective files.

Javascript




//authMiddleware.js
 
import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
 
const authMiddleware = (WrappedComponent) => {
    const AuthComponent = (props) => {
        const router = useRouter();
        const [isAuthenticated, setIsAuthenticated] = useState(false);
 
        useEffect(() => {
            // Check for your authentication criteria here
            const username = localStorage.getItem("username");
            const password = localStorage.getItem("password");
 
            if (username === "geeksforgeeks" && password === "1234") {
                setIsAuthenticated(true);
            } else {
                router.replace("/login");
            }
        }, []);
 
        if (isAuthenticated) {
            return <WrappedComponent {...props} />;
        } else {
            return null;
        }
    };
 
    return AuthComponent;
};
 
export default authMiddleware;


Javascript




//Profile.js
 
import React from 'react'
import authMiddleware from '../middlewares/authMiddleware'
 
const profile = () => {
    return (
        <div className='max-w-sm mx-auto mt-12
                        text-3xl bg-blue-400 text-white
                        shadow-3xl rounded-xl border p-10'>
            <h1>
                Hi I am the User, and I am Logged In
            </h1>
        </div>
    )
}
 
export default authMiddleware(profile)


Javascript




//Login.js
 
import { useState } from "react";
import { useRouter } from "next/router";
 
const Login = () => {
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const router = useRouter();
 
    const handleLogin = () => {
        // Check the username and password and perform login logic
        localStorage.setItem("username", username);
        localStorage.setItem("password", password);
        // Redirect to the profile page
        router.push("/profile");
    };
 
    const handleKeyPress = (e) => {
        if (e.key === "Enter") {
            handleLogin();
        }
    };
 
    return (
        <div className="flex flex-col max-w-sm mt-12 space-y-3 mx-auto">
            <h1 className="text-gray-600 text-2xl">Login</h1>
            <input
                className="border p-2"
                placeholder="Enter username"
                value={username}
                onChange={(e) => setUsername(e.target.value)}
                onKeyPress={handleKeyPress}
            />
            <input
                className="border p-2"
                placeholder="Enter password"
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                onKeyPress={handleKeyPress}
            />
            <button
                onClick={handleLogin}
                className="border p-2 focus:bg-white focus:text-gray-400
                    focus:border bg-sky-600 text-white"
            >
                Submit
            </button>
        </div>
    );
};
 
export default Login;


Step 3: To start the application run the following codes.

npm run dev

Output:

Animation32



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads