Using Astro locals
Astro locals are a great way to share variables between middleware and page components (note: not layouts, as discussed in another post).
You can add a property in the src/middleware.ts
file:
import type { MiddlewareHandler } from 'astro'
export const onRequest: MiddlewareHandler = async (context, next) => {
context.locals.test = 'test'
return await next()
}
and access it in the page component:
---
console.log(Astro.locals.test)
---
....
…this unlocks a few useful scenarios.
Mostly setting some property in a page, and using it in the middleware.
Note that if you add a property in the middleware you’ll see this TS issue:
To fix this problem, add to src/env.d.ts
the type of the new property:
/// <reference types="astro/client" />
declare namespace App {
interface Locals {
test: string
}
}
and define your middleware in this way:
import { defineMiddleware } from 'astro:middleware'
export const onRequest = defineMiddleware(async (context, next) => {
context.locals.test = 'test'
return await next()
})
UPDATE: somehow this didn’t work for me recently, I used this instead (src https://github.com/withastro/astro/issues/7394#issuecomment-2212516410):
/// <reference types="astro/client" />
declare global {
namespace App {
interface Locals extends Record<string, any> {
test: string
}
}
}
I wrote 17 books to help you become a better developer, download them all at $0 cost by joining my newsletter
JOIN MY CODING BOOTCAMP, an amazing cohort course that will be a huge step up in your coding career - covering React, Next.js - next edition February 2025