Skip to content

Astro page layout and middleware execution order

One thing I discovered the hard way (through trial and error) is the order in which pages, layouts and the middleware are called in Astro.

I was doing something related to caching, and I had a workflow where I was doing something in a page, like setting a response header property, or setting a value in Astro.locals :

---
Astro.locals.test = 'test'
Astro.response.headers.set('test', 'test')
---

<p>test</p>

After doing so, I had access to those values after calling next() in the middleware:

import type { MiddlewareHandler } from 'astro'

export const onRequest: MiddlewareHandler = async (context, next) => {

	const response = await next()
	
	console.log(context.locals.test)
	console.log(response.headers.get('test'))

	return response
}

Then I decided to move some of the logic I had in the page in a layout, because I was duplicating some portion of code across multiple pages:

---
import Layout from '@layouts/Layout.astro'
---

<Layout />

In this layout I did the exact same thing I had in the page, previously:

---
Astro.locals.test = 'test'
Astro.response.headers.set('test', 'test')
---

<p>test</p>

but to my surprise, none of those values were now available in the middleware.

Turns out that (to my understanding) the order of execution is different.

The page code is ran calling next() in the middleware.

The layout code is ran after the middleware runs.

To fix my problem I eventually moved some of the logic I had in the middleware to my layout.


download all my books for free

  • javascript handbook
  • typescript handbook
  • css handbook
  • node.js handbook
  • astro handbook
  • html handbook
  • next.js pages router handbook
  • alpine.js handbook
  • htmx handbook
  • react handbook
  • sql handbook
  • git cheat sheet
  • laravel handbook
  • express handbook
  • swift handbook
  • go handbook
  • php handbook
  • python handbook
  • cli handbook
  • c handbook

subscribe to my newsletter to get them

Terms: by subscribing to the newsletter you agree the following terms and conditions and privacy policy. The aim of the newsletter is to keep you up to date about new tutorials, new book releases or courses organized by Flavio. If you wish to unsubscribe from the newsletter, you can click the unsubscribe link that's present at the bottom of each email, anytime. I will not communicate/spread/publish or otherwise give away your address. Your email address is the only personal information collected, and it's only collected for the primary purpose of keeping you informed through the newsletter. It's stored in a secure server based in the EU. You can contact Flavio by emailing flavio@flaviocopes.com. These terms and conditions are governed by the laws in force in Italy and you unconditionally submit to the jurisdiction of the courts of Italy.

Related posts about astro: