{"id":17949,"date":"2025-08-29T12:48:48","date_gmt":"2025-08-29T10:48:48","guid":{"rendered":"https:\/\/pagepro.co\/blog\/?p=17949"},"modified":"2026-03-05T12:10:43","modified_gmt":"2026-03-05T11:10:43","slug":"next-js-middleware-what-is-it-and-when-to-use-it","status":"publish","type":"post","link":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/","title":{"rendered":"Next js Middleware &#8211; What Is It and When to Use It"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"tldr\">TL;DR<\/h2>\n\n\n\n<p>\u2022 Next.js middleware allows developers to run logic before a request reaches a route, enabling advanced request handling and routing control.<\/p>\n\n\n\n<p>\u2022 Middleware executes at the edge and can modify requests, responses, or redirects based on conditions such as authentication, localization, or user session data.<\/p>\n\n\n\n<p>\u2022 This feature is commonly used for implementing access control, A\/B testing, geolocation-based behavior, and request rewriting.<\/p>\n\n\n\n<p>\u2022 Because middleware runs before the application logic, it can improve performance by handling certain checks or redirects earlier in the request lifecycle.<\/p>\n\n\n\n<p>\u2022 Developers must design middleware carefully to avoid unnecessary complexity or performance overhead in large applications.<\/p>\n\n\n\n<p>\u2022 Understanding when to use middleware helps teams build more flexible routing and request-processing logic in modern Next.js applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"whats-middleware\">What&#8217;s Middleware?&nbsp;<\/h2>\n\n\n\n<p>Next.js middleware is a function that runs before a request is processed, allowing you to modify requests, responses, redirects, and headers at the edge. <\/p>\n\n\n\n<p>When working with <strong><a href=\"https:\/\/pagepro.co\/services\/nextjs-development\" target=\"_blank\" rel=\"noreferrer noopener\">Next.js Middleware<\/a><\/strong>, you can use this capability to handle various tasks at the edge of your application, before the request reaches your React components or API routes. It can help you <strong>build performant and secure applications<\/strong> with minimal overhead.<\/p>\n\n\n\n<p>Today, we&#8217;ll look into what <strong>Nextjs Middleware<\/strong> is, how it works, and when to use it effectively in your Next.js applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"understanding-middleware\">Understanding Middleware<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"964\" height=\"500\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Middleware-processing-request.png\" alt=\"Next js Middleware Response Processing\" class=\"wp-image-17956\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Middleware-processing-request.png 964w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Middleware-processing-request-300x156.png 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Middleware-processing-request-768x398.png 768w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Middleware-processing-request-500x259.png 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Middleware-processing-request-324x168.png 324w\" sizes=\"(max-width: 964px) 100vw, 964px\" \/><\/figure>\n\n\n\n<p>Middleware processes incoming requests by either <strong>passing the request forward<\/strong>, <strong>modifying it, or returning an early response<\/strong>. <\/p>\n\n\n\n<p>It acts as a chain where each piece of middleware performs its task before handing over the request to the next component. It&#8217;s commonly used across frameworks to <strong>perform repetitive tasks like validation, session management, or request logging<\/strong>. <\/p>\n\n\n\n<p>Custom <strong>Middleware built with Next.js<\/strong>&nbsp;extends these capabilities with the power of edge computing, enabling faster responses and greater control over the request-response lifecycle.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"next-js-middleware-basics\">Next.js Middleware Basics<\/h2>\n\n\n\n<p><strong>Important Note:<\/strong> In Next.js, only one <code>middleware.ts<\/code> file is supported per project. You can still use multiple source files, but only a single entry file is allowed. The middleware code is executed <strong>whenever a user requests any route within the Next.js application scope<\/strong>. <\/p>\n\n\n\n<p>At this point, you can choose to<strong> modify the request<\/strong> or <strong>pass it through unchanged<\/strong>. All operations are executed on the server side, in the Edge runtime, to be precise. <\/p>\n\n\n\n<p><strong>Only APIs compatible with the Edge runtime can be used, so be careful not to include any Node.js-specific APIs.<\/strong><\/p>\n\n\n\n<div class=\"wp-block-code-mind-cta c-cta-block\" style=\"background-color:#00141F;color:#FFFFFF\"><div class=\"c-cta-block__content\"><p class=\"c-cta-block__title\">Planning to use Next.js Middleware?<\/p><div class=\"c-cta-block__action\"><a href=\"https:\/\/pagepro.co\/contact\" class=\"c-cta-block__button ga-cta ga-cta-consultation theme-bg-3\">Contact Us<\/a><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"advantages-of-using-middleware-in-next-js-apps\">Advantages of Using Middleware in Next.js Apps&nbsp;<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"higher-performance-of-your-web-application\"><span class=\"underline-accent\">Higher Performance of Your Web Application<\/span><\/h3>\n\n\n\n<p>Middleware allows you to execute code as soon as a request is received. You can filter out unnecessary calls, like <strong>blocking unauthenticated users from certain routes<\/strong>. <\/p>\n\n\n\n<p>Running the code on the edge ensures that requests are processed with minimal latency, guaranteeing a <strong>faster request and response time<\/strong>.<\/p>\n\n\n\n<p>While middleware can improve request handling at the edge, overall user-perceived performance still depends on how your app is rendered and structured. Issues like overusing middleware or misconfiguring rendering strategies often overlap with <strong><a href=\"https:\/\/pagepro.co\/blog\/common-nextjs-mistakes-core-web-vitals\/?\" target=\"_blank\" rel=\"noreferrer noopener\">common Next.js mistakes that hurt Core Web Vitals<\/a><\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"better-security-with-middleware-function\"><span class=\"underline-accent\">Better Security with Middleware Function<\/span><\/h3>\n\n\n\n<p>Middleware is ideal for <strong>handling authenticate actions, validation, and other security measures<\/strong> before a request reaches your main application logic. <\/p>\n\n\n\n<p>It prevents <strong>unauthorized access to sensitive routes<\/strong> and makes sure all security checks happen consistently and early in the request lifecycle.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"centralized-code\"><span class=\"underline-accent\">Centralized Code<\/span><\/h3>\n\n\n\n<p>Implement middleware to enable a <strong>unified approach for handling tasks<\/strong> like setting custom headers or enforcing security policies. <\/p>\n\n\n\n<p>Instead of repeating code across multiple components, you can <strong>manage these rules in a single location<\/strong>, making the application easier to maintain and reducing potential errors caused by code duplication.<\/p>\n\n\n<div class=\"c-newsletter-sendgrid-wrapper js-newsletter-sendgrid-wrapper ga-filedownload-viewed\">\n    <div class=\"c-newsletter-sendgrid\">\n                    <p class=\"c-newsletter-sendgrid__title\">\n                Get Next.js Vercel Cost Optimization Guide            <\/p>\n        \n         \n            <p class=\"c-newsletter-sendgrid__description\">\n                Learn real-life techniques to optimize the hosting costs of your Next.js apps.            <\/p>\n        \n        <form action=\"\" class=\"c-newsletter-sendgrid__form f-form js-newsletter-sendgrid\" data-key=\"e60f07b6-7b2d-4939-88db-8a4715700f39\">\n            <div class=\"c-newsletter-sendgrid__form-mail\">\n                <label class=\"c-label\" for=\"newsletter_email\">Company E-mail address<\/label>\n                <input class=\"c-input js-newsletter-sendgrid-email\" type=\"email\" id=\"newsletter_email\" required>\n                <input class=\"c-newsletter-sendgrid__button ga-cta-filedownload\" type=\"submit\" value=\"Download\">\n            <\/div>\n            <div class=\"c-newsletter-sendgrid__form-consent\">\n                                                        <input class=\"c-checkbox js-newsletter-consent\" type=\"checkbox\" name=\"newsletter_consent\" id=\"newsletter_consent_1\" required>\n                    <label class=\"c-label\" for=\"newsletter_consent_1\">I accept the Privacy Policy and agree to process my personal data by Pagepro for marketing purposes.<\/label>\n                            <\/div>\n        <\/form>\n\n        <div class=\"c-newsletter-sendgrid__cover-container\">\n                            <img decoding=\"async\" class=\"c-newsletter-sendgrid__cover-1\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2025\/04\/Cover-1.jpg\" alt=\"Cover of a guide titled NEXT.JS VERCEL COST OPTIMISATION GUIDE by Jakub Dakowicz and Chris Lojniewski, featuring insights on self-hosting Nextjs, with a red geometric background and Pagepro logo in the top left corner.\" >\n                                            <\/div>\n\n        <div class=\"c-newsletter-sendgrid__popup-wrapper js-newsletter-sendgrid-popup is-hidden\">\n            <div class=\"c-newsletter-sendgrid__popup\">\n                <div class=\"c-newsletter-sendgrid__popup-icon\">\n                    <svg width=\"140\" height=\"140\" viewBox=\"0 0 140 140\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                    <g clip-path=\"url(#clip0_6621_2135)\">\n                    <path d=\"M65.625 100.625C65.625 109.908 69.3125 118.81 75.8763 125.374C82.44 131.938 91.3424 135.625 100.625 135.625C109.908 135.625 118.81 131.938 125.374 125.374C131.938 118.81 135.625 109.908 135.625 100.625C135.625 91.3424 131.938 82.44 125.374 75.8763C118.81 69.3125 109.908 65.625 100.625 65.625C91.3424 65.625 82.44 69.3125 75.8763 75.8763C69.3125 82.44 65.625 91.3424 65.625 100.625Z\" stroke=\"#0A2B3D\" stroke-width=\"8.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n                    <path d=\"M116.223 90.4517L99.2774 113.044C98.9005 113.545 98.4206 113.959 97.8701 114.259C97.3196 114.558 96.7113 114.737 96.0862 114.781C95.461 114.826 94.8335 114.736 94.246 114.518C93.6584 114.3 93.1244 113.959 92.6799 113.517L83.9299 104.767\" stroke=\"#0A2B3D\" stroke-width=\"8.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n                    <path d=\"M48.125 91.875H13.125C10.8044 91.875 8.57876 90.9531 6.93782 89.3122C5.29687 87.6712 4.375 85.4456 4.375 83.125V13.125C4.375 10.8044 5.29687 8.57876 6.93782 6.93782C8.57876 5.29687 10.8044 4.375 13.125 4.375H118.125C120.446 4.375 122.671 5.29687 124.312 6.93782C125.953 8.57876 126.875 10.8044 126.875 13.125V52.5\" stroke=\"#0A2B3D\" stroke-width=\"8.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n                    <path d=\"M124.898 7.5835L77.3909 44.1235C74.0176 46.7185 69.881 48.1255 65.625 48.1255C61.3691 48.1255 57.2325 46.7185 53.8592 44.1235L6.35254 7.5835\" stroke=\"#0A2B3D\" stroke-width=\"8.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n                    <\/g>\n                    <defs>\n                    <clipPath id=\"clip0_6621_2135\">\n                    <rect width=\"140\" height=\"140\" fill=\"white\"\/>\n                    <\/clipPath>\n                    <\/defs>\n                    <\/svg>\n                <\/div>\n                                    <p class=\"c-newsletter-sendgrid__popup-text\">\n                        Thank you for signing up. Check your e-mail for the guide.                    <\/p>\n                                <div class=\"c-newsletter-sendgrid__popup-action\">\n                    <button class=\"c-newsletter-sendgrid__button c-newsletter-sendgrid__button--full-width js-newsletter-sendgrid-popup-close\">Close<\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"best-use-cases-for-middleware-in-next-js-project\">Best Use Cases for Middleware in Next.js Project<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"basic-next-js-middleware-syntax\"><span class=\"underline-accent\">Basic Next.js Middleware syntax<\/span><\/h3>\n\n\n\n<p>In Next.js, middleware is defined as a function that runs <strong>before a request is completed<\/strong>. It allows you to inspect, modify, redirect, or block requests <strong>before rendering happens<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>import { NextResponse } from 'next\/server' import type { NextRequest } from 'next\/server' export function middleware(request: NextRequest) { return NextResponse.next() }<\/strong><\/code><\/pre>\n\n\n\n<p>This middleware runs on every incoming request that matches the configured routes. By default, it does not change the request or response \u2014 it simply allows the request to continue.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-next-js-middleware-works\"><span class=\"underline-accent\">How Next.js middleware works<\/span><\/h3>\n\n\n\n<ul>\n<li>Middleware executes <strong>before route handlers and page rendering<\/strong><\/li>\n\n\n\n<li>It runs at the <strong>Edge Runtime<\/strong>, not on the Node.js server<\/li>\n\n\n\n<li>It can:\n<ul>\n<li>Redirect users<\/li>\n\n\n\n<li>Rewrite URLs<\/li>\n\n\n\n<li>Modify request headers<\/li>\n\n\n\n<li>Block access based on conditions<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Middleware logic is applied only to routes defined in the <code>matcher<\/code> configuration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"limiting-middleware-to-specific-routes\"><span class=\"underline-accent\">Limiting middleware to specific routes<\/span><\/h3>\n\n\n\n<p>You can control where middleware runs using the <code>matcher<\/code> option:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code><strong>export const config = { matcher: &#91;'\/dashboard\/:path*'] }<\/strong><\/code><\/code><\/pre>\n\n\n\n<p>This ensures the middleware runs <strong>only for selected routes<\/strong>, improving performance and avoiding unnecessary execution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"initial-authentication-and-authorization\"><span class=\"underline-accent\">Initial Authentication and Authorization<\/span><\/h3>\n\n\n\n<p>Middleware works great for initial authorization checks before users access protected content. <\/p>\n\n\n\n<p>Verifying a valid token or simply checking for an authentication cookie ensures that only authorized users can reach sensitive routes.<strong> Unauthorized visitors can be redirected to a login page or shown a custom error message<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"request-logging-and-analytics\"><span class=\"underline-accent\">Request Logging and Analytics<\/span><\/h3>\n\n\n\n<p>Using middleware for logging allows <strong>smooth integration with third-party monitoring or analytics tools<\/strong>. <\/p>\n\n\n\n<p>All incoming requests can be captured, processed, and shaped <strong>before reaching your core application logic<\/strong>. Actions like filtering of data, monitoring user interactions, and the extraction of insights for performance optimization and anomaly detection become much simpler with middleware.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"seo-friendly-redirects\"><span class=\"underline-accent\">SEO-Friendly Redirects<\/span><\/h3>\n\n\n\n<p>Handling redirects efficiently is another strong use case for middleware. It\u2019s possible to <strong>redirect users from outdated URLs to new ones<\/strong> or implement location-based redirects based on the user\u2019s region. <\/p>\n\n\n\n<p>Using middleware for redirects <strong>improves the user experience<\/strong> by guiding visitors to the correct content. It also maintains SEO health by setting the proper status codes and avoiding broken links.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"maintenance-mode\"><span class=\"underline-accent\">Maintenance Mode<\/span><\/h3>\n\n\n\n<p>Middleware simplifies implementing maintenance modes during <strong>scheduled updates or unexpected outages<\/strong>. <\/p>\n\n\n\n<p>Incoming traffic can be <strong>redirected to a dedicated maintenance page<\/strong> or served a user-friendly message. This prevents users from encountering broken pages or errors, leaving their experience uninterrupted, even during critical updates.<\/p>\n\n\n\n<div class=\"c-case-study-block js-sticky-wide\">\n    <div class=\"c-case-study-block__content\">\n        <div class=\"c-case-study-block__text\">\n                            <p class=\"c-case-study-block__subtitle\">AMPLIENCE &#8211; GET STARTED GUIDE<\/p>\n                                        <p class=\"c-case-study-block__title\">Next.js in Action: Building an Interactive Guide Demystifying CMS\u2019s Capabilities<\/p>\n                                        <a href=\"https:\/\/pagepro.co\/case-studies\/amplience-get-started\" class=\"c-case-study-block__button\" target=\"_blank\">\n                    READ CASE STUDY                <\/a>\n                    <\/div>\n                    <figure class=\"c-case-study-block__media\">\n                <img decoding=\"async\" class=\"c-case-study-block__image\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/06\/amplience-blog.png\" alt=\"A tablet and smartphone display a website with the heading Generative Content with Shopping Context, showcasing software development outsourcing. A smiling woman with curly hair is featured prominently on the right side of both screens.\" \/>\n            <\/figure>\n            <\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"when-to-use-next-js-middleware\">When to Use&nbsp;Next.js Middleware<\/h2>\n\n\n\n<p><strong>I think it\u2019s worth using middleware whenever you can.<\/strong> Middleware can improve performance and eliminate code duplication. It does so by <strong>handling cross-cutting concerns<\/strong> like authentication tokens, localization, and redirects in one centralized location. <\/p>\n\n\n\n<p>Most applications require user authentication, support multiple locales, or need URL redirects due to legacy links on forums or third-party sites. <strong>If you have tools that can handle that in a single place<\/strong>, <strong>why not<\/strong> <strong>use them?<\/strong><\/p>\n\n\n\n<p>While middleware might add a bit of complexity, the streamlined logic and better application structure are worth it.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"next-js-middleware-best-practices\">Next.js Middleware Best Practices<\/h2>\n\n\n\n<p>Here&#8217;s how to make the most out of middleware in your Next.js app.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"modularize-your-middleware\"><span class=\"underline-accent\">Modularize Your Middleware<\/span><\/h3>\n\n\n\n<p>Since only a single <code>middleware.ts<\/code> file is allowed per project, organize your logic by splitting it into smaller, modular functions. Import these functions into the main middleware file to maintain <strong>clean and manageable code<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"optimize-code-execution-with-conditionals\"><span class=\"underline-accent\">Optimize Code Execution with Conditionals<\/span><\/h3>\n\n\n\n<p>When handling multiple actions within middleware, use conditionals to ensure that only necessary logic is executed for specific paths or requests. This helps <strong>reduce the runtime<\/strong> of the code execution and keeps the middleware efficient.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"leverage-matcher-configuration\"><span class=\"underline-accent\">Leverage matcher Configuration<\/span><\/h3>\n\n\n\n<p>Use the <code>matcher<\/code> configuration option to define which routes the middleware logic should apply to. Specifying targeted routes <strong>prevents unnecessary executions<\/strong> and makes the middleware run only when required, reducing performance overhead.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"keep-middleware-lightweight\"><span class=\"underline-accent\">Keep Middleware Lightweight<\/span><\/h3>\n\n\n\n<p>Avoid heavy computations or complex logic within middleware. Instead,<strong> focus on quick, non-blocking actions<\/strong> like authentication, logging, or basic redirects. Rely on synchronous actions where possible. It will help you prevent adding latency or delays to requests.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"handle-errors-and-edge-cases-gracefully\"><span class=\"underline-accent\">Handle Errors and Edge Cases Gracefully<\/span><\/h3>\n\n\n\n<p>Middleware should include good error handling to <strong>manage unexpected scenarios<\/strong> like token validation failures. Your middleware should return appropriate responses, redirects, or error messages to guide users through, preventing any interruptions in the app\u2019s flow.<\/p>\n\n\n\n<div class=\"c-newsletter-block-acf\">\n    <p class=\"c-newsletter-block-acf__title c-newsletter__header\">\n        EXPERT INSIGHTS, FRICTIONLESSLY DELIVERED!    <\/p>\n    <p class=\"c-newsletter-block-acf__desc c-newsletter__header\">\n        Curated tech news delivered straight to your inbox every month.    <\/p>\n    <form method=\"post\" class=\"c-newsletter-block-acf__form js-newsletter-form c-newsletter__action\" name=\"newsletter-block-form\">\n        <input name=\"newsletter-email\" id=\"newsletter-email\" type=\"text\" class=\"c-newsletter-block-acf__input js-newsletter-input\" placeholder=\"Company Email\" \/>\n        <input name=\"newsletter-campaign\" id=\"newsletter-campaign\" type=\"hidden\" value=\"\" \/>\n        <div class=\"c-newsletter-block-acf__group\">\n            <input name=\"consent\" id=\"consent\" type=\"checkbox\" class=\"js-newsletter-consent\" \/>\n            <label class=\"c-newsletter-block-acf__label\" for=\"consent\">I accept the <a href=\"https:\/\/pagepro.co\/privacy-policy\">Privacy Policy<\/a> and agree to process my personal data by Pagepro for marketing purposes.<\/label>\n        <\/div>\n        <input type=\"submit\" class=\"c-newsletter-block-acf__button button js-newsletter-sub ga-newsletter-form-content\" value=\"Sign up\" \/>\n        <p class=\"theme-size-1 js-message-valid is-hidden is-invalid\"><\/p>\n    <\/form>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-to-set-up-and-configure-next-js-middleware\">How to Set Up and Configure NExt.js Middleware<\/h2>\n\n\n\n<p>To start working with middleware, you just need to create a single file <code>middleware.ts<\/code> (or .js) in the root of your project. <\/p>\n\n\n\n<p>You can start with the sample code from the documentation and check if it\u2019s triggering with a single <code>console.log<\/code>. <strong>Make sure to include yours in the <code>config.matcher<\/code>!<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"typescript\">import { NextResponse } from 'next\/server'\n\nimport type { NextRequest } from 'next\/server'\n\n\u00a0\n\nexport function middleware(request: NextRequest) {\n\u00a0 console.log(request);\n\n\u00a0\u00a0return NextResponse.redirect(new URL('\/home', request.url))\n\n}\n\n\u00a0\n\nexport const config = {\n\n\u00a0\u00a0matcher:[\"\/((?!api|_next|public|static|.*\\\\..*).*)\"]\n\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"nextjs-middleware-code-examples\">NextJS Middleware Code Examples<\/h2>\n\n\n\n<p>I&#8217;ve prepared a few code examples for different middlewares you can implement in your apps. Feel free to use them!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"nextjs-middleware-for-authentication\"><span class=\"underline-accent\">NextJS Middleware for Authentication<\/span><\/h3>\n\n\n\n<p>This middleware checks if a user has a valid authentication token before allowing access to protected routes like <code>\/dashboard<\/code> or <code>\/profile<\/code>. <\/p>\n\n\n\n<p>If no token is found, <strong>the user is redirected to the login page<\/strong>. You can use it to secure private areas of your app, enforce role-based access, or control entry to subscription-only content.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"typescript\">\/\/ middleware.ts\n\nimport { NextResponse } from \"next\/server\";\n\nimport type { NextRequest } from \"next\/server\";\n\nexport function middleware(request: NextRequest) {\n\n\u00a0\u00a0const { pathname } = request.nextUrl;\n\n\u00a0\u00a0const protectedRoutes = [\"\/dashboard\", \"\/profile\"];\n\n\u00a0\u00a0if (protectedRoutes.some(route => pathname.startsWith(route))) {\n\n\u00a0\u00a0\u00a0\u00a0const token = request.cookies.get(\"token\");\n\n\u00a0\u00a0\u00a0\u00a0if (!token) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return NextResponse.redirect(new URL(\"\/login\", request.url));\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0}\n\n\u00a0\u00a0return NextResponse.next();\u00a0\n\n}\n\n\/\/ Apply middleware to all routes\n\nexport const config = {\n\n\u00a0\u00a0matcher: [\"\/:path*\"],\n\n};<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"redirects-rewrites-middleware\"><span class=\"underline-accent\">Redirects\/Rewrites Middleware <\/span><\/h3>\n\n\n\n<p>Forget about problems with redirects. In this example, the middleware handles them in your Next.js app. <\/p>\n\n\n\n<p>It <strong>automatically sends users from outdated routes<\/strong> like <code>\/old-page<\/code> or <code>\/legacy-route<\/code> to their new locations, and reducing the risk of broken links.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"typescript\">\/\/ middleware.ts\n\nimport { NextResponse } from 'next\/server';\n\nimport type { NextRequest } from 'next\/server';\n\nexport function middleware(request: NextRequest) {\n\n\u00a0\u00a0const { pathname } = request.nextUrl;\n\n\u00a0\u00a0if (pathname === '\/old-page') {\n\n\u00a0\u00a0\u00a0\u00a0return NextResponse.redirect(new URL('\/new-page', request.url));\n\n\u00a0\u00a0}\n\n\u00a0\u00a0if (pathname === '\/legacy-route') {\n\n\u00a0\u00a0\u00a0\u00a0return NextResponse.redirect(new URL('\/modern-route', request.url));\n\n\u00a0\u00a0}\n\n\u00a0\u00a0return NextResponse.next();\n\n}\n\nexport const config = {\n\n\u00a0\u00a0matcher: ['\/:path*'],\n\n};<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"localization-check-set-middleware\"><span class=\"underline-accent\">Localization Check\/Set Middleware <\/span><\/h3>\n\n\n\n<p>To make localization easier, middleware can detect the user\u2019s preferred language from their browser settings. It then automatically redirects them to the right localized version of your site. If there&#8217;s no preference, it defaults to English (<code>en-GB<\/code>). <\/p>\n\n\n\n<p>It\u2019s perfect for <strong>serving region-specific content<\/strong>, and improves user experience since they don&#8217;t have to deal with manual language switching.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"typescript\">\/ middleware.ts\n\nimport { NextResponse } from \"next\/server\";\n\nimport type { NextRequest } from \"next\/server\";\n\nconst supportedLocales = [\"en-GB\", \"pl-PL\", \"fr-FR\"] as const;\n\nconst getUserLocale = (request: NextRequest): string => {\n\n\u00a0\u00a0const acceptLanguage = request.headers.get(\"accept-language\");\n\n\u00a0\u00a0if (!acceptLanguage) return supportedLocales[0];\n\n\u00a0\u00a0const preferredLocale = acceptLanguage.split(\",\")[0];\n\n\u00a0\u00a0return preferredLocale &amp;&amp; supportedLocales.includes(preferredLocale)\n\n\u00a0\u00a0\u00a0\u00a0? preferredLocale\n\n\u00a0\u00a0\u00a0\u00a0: \"en-GB\";\n\n};\n\nexport function middleware(request: NextRequest) {\n\n\u00a0\u00a0const { pathname } = request.nextUrl;\n\n\u00a0\u00a0if (supportedLocales.some(locale => pathname.startsWith(`\/${locale}`))) {\n\n\u00a0\u00a0\u00a0\u00a0return NextResponse.next();\n\n\u00a0\u00a0}\n\n\u00a0\u00a0const locale = getUserLocale(request);\n\n\u00a0\u00a0return NextResponse.redirect(\n\n\u00a0\u00a0\u00a0\u00a0new URL(`\/${locale}${pathname}`, request.url),\n\n\u00a0\u00a0);\n\n}\n\nexport const config = {\n\n\u00a0\u00a0matcher: [\"\/:path*\"],\n\n};<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"logging-middleware\"><span class=\"underline-accent\">Logging Middleware<\/span><\/h3>\n\n\n\n<p>You don&#8217;t have to add logging code to every route. Monitoring traffic, debugging issues, auditing user activity, or collecting analytics can be made easier with middleware. <\/p>\n\n\n\n<p>This middleware <strong>logs every incoming request to your Next.js app<\/strong>, capturing details like the HTTP method, URL, and user\u2019s IP address. <\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"typescript\">import { NextResponse } from \"next\/server\";\n\nimport type { NextRequest } from \"next\/server\";\n\nexport function middleware(request: NextRequest) {\n\n\u00a0\u00a0const { method, url, ip } = request;\n\n\u00a0\u00a0logRequest(method, url, ip); \/\/ here is your logging function\n\n\u00a0\u00a0return NextResponse.next();\n\n}\n\nexport const config = {\n\n\u00a0\u00a0matcher: [\"\/((?!_next|public|static|.*\\\\..*).*)\"],\n\n};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"middleware-in-your-next-js-project\">Middleware in Your Next.js Project<\/h2>\n\n\n\n<p>Middleware offers a lot of benefits at a low cost. Now that you know what it is, its common use cases and sample code, you&#8217;re ready to go! <\/p>\n\n\n\n<p>Give middleware a try in your next project or check if you can fit them somewhere within your current one!<\/p>\n\n\n\n<div class=\"wp-block-code-mind-cta c-cta-block\" style=\"background-color:#00141F;color:#FFFFFF\"><div class=\"c-cta-block__content\"><p class=\"c-cta-block__title\">Are you ready to use Next.js for your next project?<\/p><div class=\"c-cta-block__action\"><a href=\"https:\/\/pagepro.co\/contact\" class=\"c-cta-block__button ga-cta ga-cta-consultation theme-bg-3\">Contact us<\/a><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"frequently-asked-questions\">Frequently Asked Questions<\/h2>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1763125423885\"><strong class=\"schema-faq-question\">Can Next JS Middleware Be Async<\/strong> <p class=\"schema-faq-answer\">Yes. Middleware can be async and you can await edge-compatible operations like <code>fetch()<\/code>. Just make sure you return a <code>NextResponse<\/code> (e.g., <code>NextResponse.next()<\/code>, redirect, or rewrite) and avoid Node-only APIs (<code>fs<\/code>, <code>net<\/code>, etc.).<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1763125431460\"><strong class=\"schema-faq-question\">How NextJS Middleware Works<\/strong> <p class=\"schema-faq-answer\">Middleware runs before a request reaches your route. It inspects the incoming request (URL, headers, cookies), and decides what to do after. It can:<br\/>1. Continue (NextResponse.next())<br\/>2. Redirect the user<br\/>3. Rewrite to a different route<br\/>4. Modify headers\/cookies<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1763125459080\"><strong class=\"schema-faq-question\">Can I Have Multiple Middleware In NextJS?<\/strong> <p class=\"schema-faq-answer\">You have <strong>one<\/strong> <code>middleware.ts<\/code> (or <code>.js<\/code>) at the app root. To handle different concerns, compose smaller functions inside that file and control execution with <code>matcher<\/code> or conditional logic.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1763125469456\"><strong class=\"schema-faq-question\">Does Next.js Middleware Run on the Server?<\/strong> <p class=\"schema-faq-answer\">Middleware always runs in the <strong>Edge Runtime<\/strong>, not the traditional Node.js server or the browser. Even when you self-host with <code>next start<\/code>, it still executes in the Edge Runtime (simulated locally).<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1763125476699\"><strong class=\"schema-faq-question\">How To Create Middleware NextJS<\/strong> <p class=\"schema-faq-answer\">Start by creating middleware.ts in the project root (or <code>src\/<\/code>). Then <code>export middleware(req: NextRequest)<\/code> and return a <code>NextResponse<\/code>. Optionally, you can also <code>export config = { matcher: [...] }<\/code> to target specific paths.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1763125488737\"><strong class=\"schema-faq-question\">What\u2019s The Difference Between NextJS Middleware Rewrite Vs Redirect<\/strong> <p class=\"schema-faq-answer\">Redirect changes the URL in the browser (HTTP 3xx) and triggers a new request. You can use it for moves\/login flows.<br\/>Meanwhile, Rewrite keeps the URL the same but serves content from a different route internally. It works great for vanity URLs, A\/B tests, or localization without changing the visible URL.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1763125499350\"><strong class=\"schema-faq-question\">What to Do When Nextjs Middleware Is Not Working?<\/strong> <p class=\"schema-faq-answer\">If your Next.js middleware is failing, here are some things you should check to fix it:<br\/><br\/>1. <strong>File &amp; location<\/strong>: <code>middleware.ts<\/code> at project root (or <code>src\/<\/code>).<br\/>2. <strong>Matcher<\/strong>: Verify patterns; exclude static assets if needed (e.g., <code>\/_next<\/code>, files with extensions).<br\/>3. <strong>Edge compatibility<\/strong>: Remove Node-only APIs; use <code>Web\/Edge<\/code> APIs only.<br\/>4. <strong>URLs<\/strong>: Build absolute URLs with new URL(<code>'\/path', req.url<\/code>) to avoid host issues.<br\/>5. <strong>Return paths<\/strong>: Always return a <code>NextResponse<\/code>; avoid missing return or infinite loops.<br\/>6. <strong>Conflicts<\/strong>: Check <code>next.config.js<\/code> redirects\/rewrites that might clash.<br\/>7. <strong>Cookies\/headers<\/strong>: Read via <code>req.cookies.get() \/ req.headers.get()<\/code>.<br\/>8. <strong>Limit scope<\/strong>: Add a precise matcher to prevent unexpected triggers.<\/p> <\/div> <\/div>\n\n\n\n<p>If you still have issues, log in middleware (headers, pathname) and reproduce locally, then test on your hosting platform (e.g., Vercel) to spot environment differences.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"read-more\">Read More <\/h2>\n\n\n\n<ul>\n<li><a href=\"https:\/\/pagepro.co\/blog\/next-js-vs-node-js-with-decision-making-framework\/\" target=\"_blank\" rel=\"noreferrer noopener\">Node.js vs Next.js<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/pagepro.co\/blog\/how-to-use-next-js-static-site-generator\/\" target=\"_blank\" rel=\"noreferrer noopener\">Next.js as a Static Site Generator<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/pagepro.co\/blog\/nextjs-performance-optimization-in-9-steps\/\" target=\"_blank\" rel=\"noreferrer noopener\">Next.js Performance Optimization<\/a> <a href=\"https:\/\/pagepro.co\/blog\/nextjs-performance-optimization-in-9-steps\/\" target=\"_blank\" rel=\"noreferrer noopener\"> in 9 Simple Steps<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/pagepro.co\/blog\/benefits-of-next-js\/\" target=\"_blank\" rel=\"noreferrer noopener\">Benefits of Using Next JS for Building Websites and Apps<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sources\">Sources<\/h2>\n\n\n\n<ul>\n<li><a href=\"https:\/\/nextjs.org\/docs\/app\/api-reference\/file-conventions\/middleware\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Next.js Documentation: <\/a><a href=\"http:\/\/middleware.js\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Middleware.js<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/nextjs.org\/docs\/messages\/middleware-upgrade-guide\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Middleware Upgrade Guide<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/nextjs.org\/docs\/app\/getting-started\/route-handlers-and-middleware\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Route Handlers and Middleware<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn all about Next js Middleware &#8211; what is it, when to use it (spoiler alert: whenever you can) among with the code examples.<\/p>\n","protected":false},"author":16,"featured_media":19733,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[659],"tags":[59,510],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Next.js Middleware Explained: Best Practices and Examples<\/title>\n<meta name=\"description\" content=\"Learn all about Next.js middleware - what is it, when to use it (spoiler alert: whenever you can) and check the code examples.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Next.js Middleware Explained: Best Practices and Examples\" \/>\n<meta property=\"og:description\" content=\"Learn all about Next.js middleware - what is it, when to use it (spoiler alert: whenever you can) and check the code examples.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\" \/>\n<meta property=\"og:site_name\" content=\"Pagepro\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/thisispagepro\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-29T10:48:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-05T11:10:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Next-js-Middleware-\u2013-What-Is-It-and-When-to-Use-It.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"582\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jakub Dakowicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jakub Dakowicz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\"},\"author\":{\"name\":\"Jakub Dakowicz\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf\"},\"headline\":\"Next js Middleware &#8211; What Is It and When to Use It\",\"datePublished\":\"2025-08-29T10:48:48+00:00\",\"dateModified\":\"2026-03-05T11:10:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\"},\"wordCount\":2050,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#organization\"},\"keywords\":[\"best practices\",\"web development\"],\"articleSection\":[\"Next js\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#respond\"]}]},{\"@type\":[\"WebPage\",\"FAQPage\"],\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\",\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\",\"name\":\"Next.js Middleware Explained: Best Practices and Examples\",\"isPartOf\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#website\"},\"datePublished\":\"2025-08-29T10:48:48+00:00\",\"dateModified\":\"2026-03-05T11:10:43+00:00\",\"description\":\"Learn all about Next.js middleware - what is it, when to use it (spoiler alert: whenever you can) and check the code examples.\",\"breadcrumb\":{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#breadcrumb\"},\"mainEntity\":[{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125423885\"},{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125431460\"},{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125459080\"},{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125469456\"},{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125476699\"},{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125488737\"},{\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125499350\"}],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/pagepro.co\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\/\/pagepro.co\/blog\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Next js Middleware &#8211; What Is It and When to Use It\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/pagepro.co\/blog\/#website\",\"url\":\"https:\/\/pagepro.co\/blog\/\",\"name\":\"Pagepro\",\"description\":\"Frictionless Next.js, Expo &amp; Sanity Development Blog\",\"publisher\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/pagepro.co\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/pagepro.co\/blog\/#organization\",\"name\":\"Pagepro\",\"url\":\"https:\/\/pagepro.co\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png\",\"contentUrl\":\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png\",\"width\":440,\"height\":200,\"caption\":\"Pagepro\"},\"image\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/thisispagepro\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf\",\"name\":\"Jakub Dakowicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g\",\"caption\":\"Jakub Dakowicz\"},\"description\":\"Jakub is the Chief Technology Officer at Pagepro, where he leads technical strategy and oversees the architecture of complex web platforms built with Next.js and headless CMS solutions. With nearly nine years at Pagepro and over five years leading the engineering team, he has been instrumental in shaping the company\u2019s architectural standards, development workflows, and scalability practices. Jakub focuses on building robust, composable systems that balance performance, maintainability, and long-term business flexibility. He drives technical decision-making across projects, ensuring that solutions are not only modern, but strategically aligned with client growth.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/jakub-dakowicz-939838102\/\"],\"url\":\"https:\/\/pagepro.co\/blog\/author\/jakub_dakowicz\/\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125423885\",\"position\":1,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125423885\",\"name\":\"Can Next JS Middleware Be Async\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes. Middleware can be async and you can await edge-compatible operations like fetch(). Just make sure you return a NextResponse (e.g., NextResponse.next(), redirect, or rewrite) and avoid Node-only APIs (fs, net, etc.).\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125431460\",\"position\":2,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125431460\",\"name\":\"How NextJS Middleware Works\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Middleware runs before a request reaches your route. It inspects the incoming request (URL, headers, cookies), and decides what to do after. It can:<br\/>1. Continue (NextResponse.next())<br\/>2. Redirect the user<br\/>3. Rewrite to a different route<br\/>4. Modify headers\/cookies\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125459080\",\"position\":3,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125459080\",\"name\":\"Can I Have Multiple Middleware In NextJS?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"You have <strong>one<\/strong> middleware.ts (or .js) at the app root. To handle different concerns, compose smaller functions inside that file and control execution with matcher or conditional logic.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125469456\",\"position\":4,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125469456\",\"name\":\"Does Next.js Middleware Run on the Server?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Middleware always runs in the <strong>Edge Runtime<\/strong>, not the traditional Node.js server or the browser. Even when you self-host with next start, it still executes in the Edge Runtime (simulated locally).\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125476699\",\"position\":5,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125476699\",\"name\":\"How To Create Middleware NextJS\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Start by creating middleware.ts in the project root (or src\/). Then export middleware(req: NextRequest) and return a NextResponse. Optionally, you can also export config = { matcher: [...] } to target specific paths.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125488737\",\"position\":6,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125488737\",\"name\":\"What\u2019s The Difference Between NextJS Middleware Rewrite Vs Redirect\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Redirect changes the URL in the browser (HTTP 3xx) and triggers a new request. You can use it for moves\/login flows.<br\/>Meanwhile, Rewrite keeps the URL the same but serves content from a different route internally. It works great for vanity URLs, A\/B tests, or localization without changing the visible URL.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125499350\",\"position\":7,\"url\":\"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125499350\",\"name\":\"What to Do When Nextjs Middleware Is Not Working?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"If your Next.js middleware is failing, here are some things you should check to fix it:<br\/><br\/>1. <strong>File &amp; location<\/strong>: middleware.ts at project root (or src\/).<br\/>2. <strong>Matcher<\/strong>: Verify patterns; exclude static assets if needed (e.g., \/_next, files with extensions).<br\/>3. <strong>Edge compatibility<\/strong>: Remove Node-only APIs; use Web\/Edge APIs only.<br\/>4. <strong>URLs<\/strong>: Build absolute URLs with new URL('\/path', req.url) to avoid host issues.<br\/>5. <strong>Return paths<\/strong>: Always return a NextResponse; avoid missing return or infinite loops.<br\/>6. <strong>Conflicts<\/strong>: Check next.config.js redirects\/rewrites that might clash.<br\/>7. <strong>Cookies\/headers<\/strong>: Read via req.cookies.get() \/ req.headers.get().<br\/>8. <strong>Limit scope<\/strong>: Add a precise matcher to prevent unexpected triggers.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Next.js Middleware Explained: Best Practices and Examples","description":"Learn all about Next.js middleware - what is it, when to use it (spoiler alert: whenever you can) and check the code examples.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/","og_locale":"en_US","og_type":"article","og_title":"Next.js Middleware Explained: Best Practices and Examples","og_description":"Learn all about Next.js middleware - what is it, when to use it (spoiler alert: whenever you can) and check the code examples.","og_url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/","og_site_name":"Pagepro","article_publisher":"https:\/\/www.facebook.com\/thisispagepro","article_published_time":"2025-08-29T10:48:48+00:00","article_modified_time":"2026-03-05T11:10:43+00:00","og_image":[{"width":1024,"height":582,"url":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2024\/10\/Next-js-Middleware-\u2013-What-Is-It-and-When-to-Use-It.png","type":"image\/png"}],"author":"Jakub Dakowicz","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jakub Dakowicz","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#article","isPartOf":{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/"},"author":{"name":"Jakub Dakowicz","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf"},"headline":"Next js Middleware &#8211; What Is It and When to Use It","datePublished":"2025-08-29T10:48:48+00:00","dateModified":"2026-03-05T11:10:43+00:00","mainEntityOfPage":{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/"},"wordCount":2050,"commentCount":0,"publisher":{"@id":"https:\/\/pagepro.co\/blog\/#organization"},"keywords":["best practices","web development"],"articleSection":["Next js"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#respond"]}]},{"@type":["WebPage","FAQPage"],"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/","url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/","name":"Next.js Middleware Explained: Best Practices and Examples","isPartOf":{"@id":"https:\/\/pagepro.co\/blog\/#website"},"datePublished":"2025-08-29T10:48:48+00:00","dateModified":"2026-03-05T11:10:43+00:00","description":"Learn all about Next.js middleware - what is it, when to use it (spoiler alert: whenever you can) and check the code examples.","breadcrumb":{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#breadcrumb"},"mainEntity":[{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125423885"},{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125431460"},{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125459080"},{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125469456"},{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125476699"},{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125488737"},{"@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125499350"}],"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/pagepro.co\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/pagepro.co\/blog\/"},{"@type":"ListItem","position":3,"name":"Next js Middleware &#8211; What Is It and When to Use It"}]},{"@type":"WebSite","@id":"https:\/\/pagepro.co\/blog\/#website","url":"https:\/\/pagepro.co\/blog\/","name":"Pagepro","description":"Frictionless Next.js, Expo &amp; Sanity Development Blog","publisher":{"@id":"https:\/\/pagepro.co\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/pagepro.co\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/pagepro.co\/blog\/#organization","name":"Pagepro","url":"https:\/\/pagepro.co\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png","contentUrl":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png","width":440,"height":200,"caption":"Pagepro"},"image":{"@id":"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/thisispagepro"]},{"@type":"Person","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf","name":"Jakub Dakowicz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g","caption":"Jakub Dakowicz"},"description":"Jakub is the Chief Technology Officer at Pagepro, where he leads technical strategy and oversees the architecture of complex web platforms built with Next.js and headless CMS solutions. With nearly nine years at Pagepro and over five years leading the engineering team, he has been instrumental in shaping the company\u2019s architectural standards, development workflows, and scalability practices. Jakub focuses on building robust, composable systems that balance performance, maintainability, and long-term business flexibility. He drives technical decision-making across projects, ensuring that solutions are not only modern, but strategically aligned with client growth.","sameAs":["https:\/\/www.linkedin.com\/in\/jakub-dakowicz-939838102\/"],"url":"https:\/\/pagepro.co\/blog\/author\/jakub_dakowicz\/"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125423885","position":1,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125423885","name":"Can Next JS Middleware Be Async","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Yes. Middleware can be async and you can await edge-compatible operations like fetch(). Just make sure you return a NextResponse (e.g., NextResponse.next(), redirect, or rewrite) and avoid Node-only APIs (fs, net, etc.).","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125431460","position":2,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125431460","name":"How NextJS Middleware Works","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Middleware runs before a request reaches your route. It inspects the incoming request (URL, headers, cookies), and decides what to do after. It can:<br\/>1. Continue (NextResponse.next())<br\/>2. Redirect the user<br\/>3. Rewrite to a different route<br\/>4. Modify headers\/cookies","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125459080","position":3,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125459080","name":"Can I Have Multiple Middleware In NextJS?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"You have <strong>one<\/strong> middleware.ts (or .js) at the app root. To handle different concerns, compose smaller functions inside that file and control execution with matcher or conditional logic.","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125469456","position":4,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125469456","name":"Does Next.js Middleware Run on the Server?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Middleware always runs in the <strong>Edge Runtime<\/strong>, not the traditional Node.js server or the browser. Even when you self-host with next start, it still executes in the Edge Runtime (simulated locally).","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125476699","position":5,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125476699","name":"How To Create Middleware NextJS","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Start by creating middleware.ts in the project root (or src\/). Then export middleware(req: NextRequest) and return a NextResponse. Optionally, you can also export config = { matcher: [...] } to target specific paths.","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125488737","position":6,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125488737","name":"What\u2019s The Difference Between NextJS Middleware Rewrite Vs Redirect","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Redirect changes the URL in the browser (HTTP 3xx) and triggers a new request. You can use it for moves\/login flows.<br\/>Meanwhile, Rewrite keeps the URL the same but serves content from a different route internally. It works great for vanity URLs, A\/B tests, or localization without changing the visible URL.","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125499350","position":7,"url":"https:\/\/pagepro.co\/blog\/next-js-middleware-what-is-it-and-when-to-use-it\/#faq-question-1763125499350","name":"What to Do When Nextjs Middleware Is Not Working?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"If your Next.js middleware is failing, here are some things you should check to fix it:<br\/><br\/>1. <strong>File &amp; location<\/strong>: middleware.ts at project root (or src\/).<br\/>2. <strong>Matcher<\/strong>: Verify patterns; exclude static assets if needed (e.g., \/_next, files with extensions).<br\/>3. <strong>Edge compatibility<\/strong>: Remove Node-only APIs; use Web\/Edge APIs only.<br\/>4. <strong>URLs<\/strong>: Build absolute URLs with new URL('\/path', req.url) to avoid host issues.<br\/>5. <strong>Return paths<\/strong>: Always return a NextResponse; avoid missing return or infinite loops.<br\/>6. <strong>Conflicts<\/strong>: Check next.config.js redirects\/rewrites that might clash.<br\/>7. <strong>Cookies\/headers<\/strong>: Read via req.cookies.get() \/ req.headers.get().<br\/>8. <strong>Limit scope<\/strong>: Add a precise matcher to prevent unexpected triggers.","inLanguage":"en-US"},"inLanguage":"en-US"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/17949"}],"collection":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/comments?post=17949"}],"version-history":[{"count":29,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/17949\/revisions"}],"predecessor-version":[{"id":23128,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/17949\/revisions\/23128"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/media\/19733"}],"wp:attachment":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/media?parent=17949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/categories?post=17949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/tags?post=17949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}