diff --git a/packages/starlight/components/StarlightPage.astro b/packages/starlight/components/StarlightPage.astro index 7846a594e4d..532e36ffac5 100644 --- a/packages/starlight/components/StarlightPage.astro +++ b/packages/starlight/components/StarlightPage.astro @@ -1,4 +1,5 @@ --- +import { attachRouteDataAndRunMiddleware } from '../utils/routing/middleware'; import { generateStarlightPageRouteData, type StarlightPageProps as Props, @@ -7,13 +8,10 @@ import Page from './Page.astro'; export type StarlightPageProps = Props; -// TODO: This is a bit tricky to solve. -// We can’t apply other middleware transformations to route data here, so that makes -// the `` behaviour quite different from regular pages. -Astro.locals.starlightRoute = await generateStarlightPageRouteData({ - props: Astro.props, - url: Astro.url, -}); +await attachRouteDataAndRunMiddleware( + Astro, + await generateStarlightPageRouteData({ props: Astro.props, url: Astro.url }) +); --- diff --git a/packages/starlight/locals.ts b/packages/starlight/locals.ts index a408258d270..548e8888040 100644 --- a/packages/starlight/locals.ts +++ b/packages/starlight/locals.ts @@ -1,9 +1,10 @@ import { defineMiddleware } from 'astro:middleware'; -import { useTranslations } from './utils/translations'; import { useRouteData } from './utils/routing/data'; +import { attachRouteDataAndRunMiddleware } from './utils/routing/middleware'; +import { useTranslations } from './utils/translations'; export const onRequest = defineMiddleware(async (context, next) => { context.locals.t = useTranslations(context.currentLocale); - context.locals.starlightRoute = await useRouteData(context); + await attachRouteDataAndRunMiddleware(context, await useRouteData(context)); return next(); }); diff --git a/packages/starlight/utils/routing/middleware.ts b/packages/starlight/utils/routing/middleware.ts new file mode 100644 index 00000000000..a496b001a43 --- /dev/null +++ b/packages/starlight/utils/routing/middleware.ts @@ -0,0 +1,19 @@ +import type { APIContext } from 'astro'; +import { klona } from 'klona/lite'; +import { routeMiddleware } from 'virtual:starlight/route-middleware'; +import type { StarlightRouteData } from './types'; + +/** + * Adds a deep clone of the passed `routeData` object to locals and then runs middleware. + * @param context Astro context object + * @param routeData Initial route data object to attach. + */ +export async function attachRouteDataAndRunMiddleware( + context: APIContext, + routeData: StarlightRouteData +) { + context.locals.starlightRoute = klona(routeData); + for (const middlewareFn of routeMiddleware) { + await middlewareFn(context); + } +}