🚀 Astro JS Middleware Example #
Astro now includes middleware, which performs a similar function to SvelteKit hooks, Deno Fresh middleware or middleware offered by serverless hosts (such as Cloudflare Workers). Here, we see an Astro JS Middleware example, as well as what middleware is and when you will pull it out of the Astro tool belt. For our example, we add request logging using Astro middleware with the Logtail serverless logging service.
What is Middleware? #
Middleware is just code which runs on a server to intercept requests, potentially modifying
them. Astro route files will be invoked, typically for specific routes (/docs/getting-started
, for example). Middleware is a little different in that respect, in that it can be less specific; you can invoke a middleware function for all routes, or selected sub-paths.
With the logging example we consider, there will be some request details you want to capture, no
matter which route the request was made to. Included here might be the request pathname, the
time of the request, and perhaps even the time taken to respond. A single middleware file for
all routes, rather than including the logging logic in the .astro
file for every route, makes sense here.
We will see within your middleware function, you can peek at what the response will be, then
send that response, “as-is” or even change certain parts, adding HTTP headers or even changing out parts of the response body, where that makes sense. We
also see Astro lets you pass through data to .astro
files using the
locals object, offering another way to update content. Although Astro middleware works on both SSR and static routes, you will get the most out of it on SSR sites.
🤔 Why use Middleware? #
Some uses for middleware are:
- analytics code;
- logging;
- performance and reliability measurement;
- manipulating HTML content (e.g. highlighting search terms in body text);
- adding response headers (such as HTTP security headers); and
- proxying requests, for example to keep a WordPress backend URL private .
🧱 What are we Building? #
We will look at code for a basic Astro JS middleware logging example. In the code we shall see how you add a middleware function in Astro, as well as the most important methods, for intercepting requests. We also see how you can leave the response intact, yet still pass data through, for use in your front end code.
If that sounds like what you were looking for, then why don’t we get started? We won’t build an app from scratch, so, you probably want to create a feature branch on an existing project. If this is your first time working in Astro, though, see the quick guide on how to spin up a new Astro project.
🛠️ Astro SSR Middleware #
Middleware works on static as well as SSR sites, however you get most benefit on an SSR site, so
we set the output
and adapter
fields
in lines (10
& 11
), below. Drop
these if you want to stay static. And, of course, switch out the Cloudflare adapter if you prefer
using another host.
🕵🏽 Astro JS Middleware: Middleware Code #
To add Astro middleware to all routes, just create a src/middleware.ts
(or src/middleware.js
) file which exports an onRequest
handler:
Some interesting points here:
-
onRequest
has two arguments: a context object andnext
-
request
on the context object is the incoming HTTP request from which you can destructure a URL, as well as other fields, which you will be familiar with -
locals
(on the context object) lets us pass out data from middleware -
next
is a function; calling that function gives you access to the response that the route normally generates (without middleware) -
onRequest
returns a response object; in this case it is just the response which would have been sent anyway, though you can modify the response, adding HTTP headers or tinkering with the body
We also set locals.timestamp
, above. We will see that value is
passed through to the front end code a little later.
Astro JS Middleware Example: Adding Logging #
For our example, we want to log the request to our serverless logging service. Since we are just
reporting, onRequest
can just return the response which would have
been sent anyway (no need to modify the response).
Here is the extra code for logging a few response details, using Logtail:
Logtail has a REST API , and we can send the log data using fetch
; notice fetch is
simply available in line 25
; no need to import it. You might
notice, from the Content-Type
header, that the message body is in msgpack format. This is a slightly more efficient format than JSON. To encode the logData
regular JavaScript object in msgpack format, we use the msgpackr
package, imported in line 2
. The final piece to note is that
you will need to add your LOGTAIL_SOURCE_TOKEN
to your .env
file, sggo that you can import it in line 4
.
🖥️ Astro JS Middleware Example: Frontend #
You can update the response in your middleware, perhaps replacing template parameters. We might
use this technique to vary content by region or time of day, and can do so just by altering the
returned response from within the middleware. Another way of adding new data in middleware is
using the locals
object. In the middleware code, we added the timestamp
there:
We can access that value in individual .astro
files. Here is an example:
In line 2
, we pull our timestamp
off
Astro.locals
. Note, this could be any arbitrary value we decided
to include in the middleware function, though it should be possible to serialize the value as
JSON. Finally, that value is now available for use in markup, as in line 11
.
Interestingly, middleware works on static as well as SSR sites. For a static site, though, the value displayed here would be the time stamp at build time, rather than at the point the request was made. This is still useful, though, for example to include build time in a page footer.
🗳 Poll #
🙌🏽 Astro JS Middleware Example: Wrapping Up #
In this post, we saw an example of using the Astro middleware API. In particular, we saw:
- how to add middleware to your Astro site;
- how you might use Astro middleware for request logging; and
- using Astro.locals to pass out data from middleware for use in markup.
You can see the full code for this project in the Rodney Lab GitHub repo . Also see the Astro docs . I do hope you have found this post useful, and am keen to hear how you will use middleware in your next projects. Also, let me know about any possible improvements to the content above.
🏁 Astro JS Middleware Example: Summary #
Does Astro support middleware? #
- Yes! Though at the time of writing, support is experimental. While Astro middleware remains experimental, you will have to enable it manually. You can enable Astro middleware by setting `experimental.middleware` to `true` in your `astro.config.mjs` `defineConfig` object. Once that is set, add a `src/middleware.ts` (or equivalent JavaScript) file to your project. You need to export an `onRequest` function from there. `onRequest` itself, has two arguments, the context (similar to Astro endpoint context) and `next`. `next` is a function which gives you access to the incoming request’s regular response object. If you are just adding middleware for logging, for example, you can return this response object without touching it. If you want to update template parameters within the response, on the other hand, return your updated response object instead.
Does Astro Middleware work with both SSG and static sites? #
- Yes, Astro middleware works on static sites as well as SSG ones. We saw, as an example, you might use `Astro.locals` to add a build time stamp to the footer on every page. With middleware, you can add the timestamp logic to a single file: middleware.ts.
How can you add request logging in Astro? #
- Astro middleware is a great place to add logging. You might want to track how long requests take, which regions you get most traffic from, or even which days or what time of day visitors are most active on the site. You can do all of that by adding logging, using a serverless log provider like Logtail. Logtail has a REST API, and it is quick to code up debug, info and error logs, for consumption in the Logtail console or further downstream.
🙏🏽 Astro JS Middleware Example: Feedback #
Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please consider supporting me through Buy me a Coffee.
Just dropped a new post looking at a logging example with Astro middleware, and also pass out custom locals data.
— Rodney (@askRodney) May 15, 2023
Hope you find it useful!
#askRodneyhttps://t.co/8sy96786B4
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter, @[email protected] on Mastodon and also the #rodney Element Matrix room. Also, see further ways to get in touch with Rodney Lab. I post regularly on Astro as well as SEO. Also, subscribe to the newsletter to keep up-to-date with our latest projects.