Astro JS - Middleware



What is Middleware?

Middleware is mechanism that allows you to intercept and process incoming HTTP requests before they reach your page or API route. The functions defined in middleware can be used to modify the request, add headers, handle authentication, logging, and perform other tasks before passing control to the final handler.

In astro framework, middleware works at server level. Means, it only runs when using SSR (Server-Side Rendering) with an adapter like Node.js, Deno, or Vercel. Now, Let's see how create and use middleware in astro.

How to Use Middleware in Astro?

The middleware is typically defined in src/middleware.ts or src/middleware.js files. The JavaScript function defined in the middleware file will recive a context object and can modify it or return a new context object. Let's see an example:

Example

In the code below, we define a middleware function that logs the incoming request URL. We then use this middleware function in the Astro config file.

// src/middleware.ts

import type { MiddlewareHandler } from 'astro';

// Middleware function
const middleware: MiddlewareHandler = async (context, next) => {
    console.log('Incoming request:', context.request.url);

    // Example: Adding a custom header
    context.locals.myCustomValue = "Hello from Middleware";

    // Proceed to the next step in the request lifecycle
    return next();
};

export default middleware;

Create a Authentication Middleware

The authentication middleware function will check if the user is authorized to access the requested resource in a web application. If the user is not authorized, the middleware function can return a 401 Unauthorized response. Let's see an example:

// src/middleware.ts

import type { MiddlewareHandler } from 'astro';

const authMiddleware: MiddlewareHandler = async (context, next) => {
    const user = context.request.headers.get('Authorization');

    if (!user) {
        return new Response('Unauthorized', { status: 401 });
    }
    return next(); // Allow request if authorized
};

export default authMiddleware;

Chaining Middleware

Middleware functions can be chained together to create a middleware pipeline. We can use the 'sequence()' function, that accepts middleware functions as arguments, and will execute them in the order in which they are passed. Let's see an example:

// src/middleware.ts

import { sequence } from "astro:middleware";

async function validation(_, next) {
    console.log("validation request");
    const response = await next();
    console.log("validation response");
    return response;
}

async function auth(_, next) {
    console.log("auth request");
    const response = await next();
    console.log("auth response");
    return response;
}

async function greeting(_, next) {
    console.log("greeting request");
    const response = await next();
    console.log("greeting response");
    return response;
}

export const onRequest = sequence(validation, auth, greeting);
Advertisements