#Why is my middleware not running?

29 messages · Page 1 of 1 (latest)

full heath
#

I'm trying to rewrite every other pages to 404 except specific 4 pages but my middleware isn't catching them? In fact the middleware doesn't even log the console.log() test I put at the beginning of the onRequest block. Why is this happening?
@desert meteor

desert meteorBOT
#

Hi @full heath. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

There are a few common reasons why your middleware might not be running at all:

1. Wrong File Location or Export

Make sure your middleware file is at src/middleware.js (or src/middleware.ts, or src/middleware/index.js|ts). Also, the onRequest function must not be a default export — it must be a named export:

// src/middleware.js ✅ Correct
export function onRequest(context, next) {
  console.log("Middleware running!"); // Should appear in your terminal
  // ...
  return next();
}

[Basic Usage]

2. console.log Output Location

Since middleware runs on the server, your console.log output will appear in the terminal where Astro is running, not in the browser's developer console. Make sure you're checking the right place. [Debugging with console.log]

3. Middleware Must Return a Response

Your middleware must always return either a Response directly or the result of calling next(). If it returns nothing, Astro will throw a MiddlewareNoDataOrNextCalled error. [Middleware No Data]

4. Static (Prerendered) Pages

Middleware only runs at request time for on-demand rendered (dynamic) pages. If your pages are statically prerendered (the default in Astro), middleware runs at build time, not when a user visits the page. This means your rewrite logic won't execute on page visits for static pages. [Adapter Features]

Example: Rewriting to 404

Here's how you could rewrite unlisted pages to a 404:

#
// src/middleware.js
const ALLOWED_PATHS = ["/page1", "/page2", "/page3", "/page4"];

export const onRequest = async (context, next) => {
  console.log("Middleware running for:", context.url.pathname); // Check terminal!
  
  if (!ALLOWED_PATHS.includes(context.url.pathname)) {
    return context.rewrite("/404");
  }
  
  return next();
};

[Rewrites]

The most likely culprit if the middleware isn't running at all is either the wrong file path/export style, or the fact that your pages are statically prerendered and you're not checking the terminal for logs.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@full heath Kapa.ai is still learning and improving, please let me know how I did by reacting below.

full heath
#

I'm using typescript, not common js. @desert meteor

desert meteorBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

No problem! The same principles apply in TypeScript. Here's the TypeScript version of the middleware:

// src/middleware.ts
import { defineMiddleware } from "astro:middleware";

const ALLOWED_PATHS = ["/page1", "/page2", "/page3", "/page4"];

export const onRequest = defineMiddleware((context, next) => {
  console.log("Middleware running for:", context.url.pathname); // Check your terminal!

  if (!ALLOWED_PATHS.includes(context.url.pathname)) {
    return context.rewrite("/404");
  }

  return next();
});

Using defineMiddleware() is the recommended approach in TypeScript as it automatically types the context and next arguments, giving you type safety and autocompletion. [Middleware Types]

The key reminders from before still apply:

  • The file should be at src/middleware.ts
  • onRequest must be a named export, not a default export
  • Check your terminal (not the browser console) for the console.log output [Basic Usage]

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@full heath Kapa.ai is still learning and improving, please let me know how I did by reacting below.

full heath
#

Nope, nothing at all is working. I have written the code you gave me precisely and not even a single log is coming from the middleware. @desert meteor

desert meteorBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

If not even a single log is appearing in your terminal, the most likely cause is that your pages are statically prerendered (Astro's default). Middleware only runs at request time for on-demand rendered pages — if your pages are prerendered, middleware runs at build time, not when a user visits the page, so you'd never see runtime logs.

To fix this, you need to enable server-side (on-demand) rendering. You can do this by adding export const prerender = false to your pages, or by switching your entire project to server output mode in your Astro config.

The knowledge sources don't go into detail about configuring output modes, but this is the most likely explanation given that your middleware code looks correct based on what you've described.

Quick checklist to rule out other causes:

  1. File location — Is the file exactly at src/middleware.ts (or src/middleware/index.ts)? [Basic Usage]
  2. Named export — Are you using export const onRequest = defineMiddleware(...) (not export default)? [Middleware Types]
  3. Terminal, not browser — Are you checking the terminal where astro dev is running, not the browser console? [Debugging]
  4. On-demand rendering — Are your pages statically prerendered? If so, middleware won't run on page visits.
#

If all four of these are confirmed correct and it's still not working, there may be an error during middleware loading itself — check your terminal for any MiddlewareCantBeLoaded errors, which are thrown when an unknown error occurs while loading the middleware. [Middleware Load Error]

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@full heath Kapa.ai is still learning and improving, please let me know how I did by reacting below.

full heath
#

Any other alternative? (It's not working after I have met all the conditions. @desert meteor

desert meteorBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Based on the knowledge sources available to me, I've covered the main documented reasons why middleware might not run. Unfortunately, the knowledge sources don't provide additional troubleshooting steps beyond what's already been discussed.

That said, here are a few things worth double-checking that are directly supported by the docs:

Verify your export is exactly correct:

// src/middleware.ts
import { defineMiddleware } from "astro:middleware";

export const onRequest = defineMiddleware((context, next) => {
  console.log("test");
  return next();
});

The key requirements from the docs are: [Basic Usage]

  • File must be at src/middleware.ts or src/middleware/index.ts
  • Must be a named export (export const onRequest), never a default export
  • Must return a Response or the result of next()

If you're using sequence(), make sure the export is still named onRequest: [Chaining middleware]

export const onRequest = sequence(yourMiddlewareFunction);

Beyond this, the knowledge sources I have don't contain enough information to diagnose further. I'd recommend:

  • Checking the Astro Discord community where the Astro team and community can help debug more complex issues
  • Filing a bug report if you believe this is unexpected behavior

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@full heath Kapa.ai is still learning and improving, please let me know how I did by reacting below.

full heath
#

Ah! I just needed to restart the server. The middleware is working fine now. @desert meteor .

desert meteorBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Glad to hear it's working now! A server restart is sometimes needed to pick up new files like src/middleware.ts that didn't exist when the dev server was first started. [Astro dev]

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@full heath Kapa.ai is still learning and improving, please let me know how I did by reacting below.

full heath
#

Hmmm! My middleware is returning "Loop Detected". Why is this happening? I see the server logging 508 error for one of the pages I don't want visible. @desert meteor

desert meteorBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

A 508 Loop Detected error in your middleware is almost certainly caused by your rewrite to /404 triggering the middleware again, which then tries to rewrite to /404 again, creating an infinite loop.

Here's what's happening:

  1. User visits /some-page → middleware runs → not in allowed list → rewrites to /404
  2. The rewrite to /404 triggers middleware again → /404 is not in your allowed list → rewrites to /404 again → infinite loop

The fix: Add /404 to your allowed paths list:

// src/middleware.ts
import { defineMiddleware } from "astro:middleware";

const ALLOWED_PATHS = ["/page1", "/page2", "/page3", "/page4", "/404"];

export const onRequest = defineMiddleware((context, next) => {
  console.log("Middleware running for:", context.url.pathname);

  if (!ALLOWED_PATHS.includes(context.url.pathname)) {
    return context.rewrite("/404");
  }

  return next();
});

This is consistent with how rewrites work in Astro — Astro.rewrite() triggers a new, complete rendering phase and re-executes any middleware for the new route. [Rewrites] So your middleware will run again for the /404 path, and if it's not in the allowed list, it will keep rewriting to /404 indefinitely.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@full heath Kapa.ai is still learning and improving, please let me know how I did by reacting below.

full heath
#

Awesome! Everything is all fine now. @desert meteor

desert meteorBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Glad everything is working! Feel free to ask if you have any more questions about Astro. 😊

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: