Using Astro locals
By Flavio Copes
Learn how to use Astro locals to share data between middleware and pages via context.locals, and how to type them in env.d.ts to fix the TypeScript error.
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
}
}
}Related posts about astro: