Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
db2f072
Add route data to `Astro.locals`
delucis Sep 22, 2024
988c554
Use local instead of props in Starlight’s components
delucis Sep 22, 2024
286e9c8
Refactor route components
delucis Sep 22, 2024
34129ab
Merge branch 'main' into chris/locals-route-data
delucis Oct 19, 2024
9aa7f35
Merge branch 'main' into chris/locals-route-data
delucis Nov 6, 2024
990bc51
Merge branch 'main' into chris/locals-route-data
delucis Dec 14, 2024
28039b4
Fix 404 render
delucis Dec 14, 2024
08c18a7
Make `routeData` a getter to avoid null checks in components
delucis Dec 14, 2024
52a13fe
Move 404 route data logic up out of components
delucis Dec 14, 2024
c1ffade
Fix SSR 404s
delucis Dec 14, 2024
e7ced3d
Rename `routeData` => `starlightRoute`
delucis Dec 14, 2024
8c67752
Merge branch 'main' into chris/locals-route-data
delucis Dec 17, 2024
243786a
Draft docs & schema
delucis Dec 18, 2024
a547e92
Add default and description in middleware config schema
delucis Dec 18, 2024
8f44f89
Tweak proposed middleware API in docs
delucis Dec 18, 2024
2cc0a8f
Move route data docs to dedicated reference page
delucis Dec 18, 2024
c21fba9
Update component overrides guide to match locals usage
delucis Dec 18, 2024
1e79b85
Add reference link to guide
delucis Dec 18, 2024
f150aba
Update config test snapshot
delucis Dec 19, 2024
840fd32
Fix links in English pages
delucis Dec 19, 2024
8db3c72
Merge branch 'main' into chris/locals-route-data
delucis Dec 19, 2024
6d0c68b
Refactor routing utilities to avoid type issues
delucis Dec 19, 2024
67cb8ed
Also move `StarlightRouteData` type
delucis Dec 19, 2024
33e6d53
More type refactoring
delucis Dec 19, 2024
bac78a0
Remove deprecated `labels` prop from route data
delucis Dec 23, 2024
2f19039
Add virtual module that exports route middleware
delucis Dec 23, 2024
f6f9af5
Add new dependency to deep clone route data
delucis Dec 23, 2024
0107e9a
Run user middleware when adding route data to pages
delucis Dec 23, 2024
72a9577
FIx tests
delucis Dec 23, 2024
b362c7a
Remove unused import
delucis Dec 26, 2024
72f3bfb
Merge branch 'main' into chris/locals-route-data
delucis Jan 8, 2025
9aa3461
Add changeset for move of route data to locals
delucis Jan 8, 2025
3a30a0b
Remove props type import in DocSearch component
delucis Jan 9, 2025
503b46d
Step up and Badge on (#2778)
trueberryless Jan 10, 2025
c8e26f8
Create `@astrojs/starlight/route-data` module to export utilities
delucis Jan 10, 2025
4eb3adf
Export `StarlightRouteData` type
delucis Jan 11, 2025
eb0357f
Deprecate the old override props export
delucis Jan 11, 2025
4e1e936
`pnpm format`
delucis Jan 11, 2025
a7eebad
Document `defineRouteMiddleware()` and `StarlightRouteData` type
delucis Jan 11, 2025
7554878
Reorganise `Props` type deprecation to fix JSDoc tooltip
delucis Jan 11, 2025
18faac2
Add a demo route middleware file
delucis Jan 11, 2025
e5df5ec
Merge branch 'main' into chris/locals-route-data
delucis Jan 28, 2025
3c91de4
Use `AstroError` for invalid plugin config mutation
delucis Jan 31, 2025
0ec6e4e
Add support for `next()` callback to middleware system
delucis Jan 31, 2025
bb35c02
Implement `addRouteMiddleware()` plugin API
delucis Jan 31, 2025
b4acdb6
Add tests
delucis Jan 31, 2025
621a59e
Document support for multiple user middleware and use of `next()`
delucis Jan 31, 2025
3cb40cd
Document `addRouteMiddleware()` plugin API
delucis Jan 31, 2025
b87650c
Fix `injectTranslations()` type in plugin quick API docs
delucis Jan 31, 2025
15da794
Fix typo
delucis Jan 31, 2025
650e14c
Update virtual module types to include `next()`
delucis Jan 31, 2025
a743cee
deprecated > not required
delucis Feb 4, 2025
ca6f249
More extensive comment
delucis Feb 4, 2025
47988d4
Move route data generation to route component
delucis Feb 5, 2025
50bec23
Add tests for starlightRoute getter
delucis Feb 5, 2025
765beca
Handle route data for SSR route
delucis Feb 5, 2025
0de3e36
Fix missing `next` type in middleware handler type
delucis Feb 5, 2025
ca58aed
Add `order: default` to `addRouteMiddleware` types in docs and tweak …
delucis Feb 5, 2025
9ad43c1
Merge branch 'main' into chris/locals-route-data
delucis Feb 5, 2025
13d2038
Switch to alternative SSR approach more close to what we already did
delucis Feb 5, 2025
883d4a5
Add doc comments to `locals` types
delucis Feb 12, 2025
56621a6
Merge branch 'main' into chris/locals-route-data
delucis Feb 12, 2025
5471975
Improve `starlightRoute` error message
delucis Feb 13, 2025
102bd61
Fix test snapshot of error message
delucis Feb 13, 2025
43b67a3
`this` > `that`
delucis Feb 13, 2025
6d05cd9
Docs pass
delucis Feb 14, 2025
8a41943
Remove demo middleware from docs
delucis Feb 14, 2025
9f3475a
Fix broken links
delucis Feb 14, 2025
bd785d9
Update Docsearch plugin peer dependency version
delucis Feb 14, 2025
8238a86
Add DocSearch plugin changeset
delucis Feb 14, 2025
1820dec
Merge branch 'main' into chris/locals-route-data
delucis Feb 15, 2025
1ffda84
Fix type that got lost in the merge
delucis Feb 15, 2025
0496d99
Removes DocSearch plugin changeset as one was already added to the sa…
delucis Feb 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move 404 route data logic up out of components
  • Loading branch information
delucis committed Dec 14, 2024
commit 52a13fe68c54760b198f12d29d3a92d73a5418cc
10 changes: 4 additions & 6 deletions packages/starlight/components/StarlightPage.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---
import { attachRouteData } from '../utils/route-data';
import {
generateStarlightPageRouteData,
type StarlightPageProps as Props,
Expand All @@ -11,11 +10,10 @@ 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 `<StarlightPage>` behaviour quite different from regular pages.
attachRouteData(
Astro.locals,
await generateStarlightPageRouteData({ props: Astro.props, url: Astro.url }),
Astro.url
);
Astro.locals.routeData = await generateStarlightPageRouteData({
props: Astro.props,
url: Astro.url,
});
---

<Page><slot /></Page>
4 changes: 2 additions & 2 deletions packages/starlight/locals.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { defineMiddleware } from 'astro:middleware';
import { useTranslations } from './utils/translations';
import { attachRouteData, useRouteData } from './utils/route-data';
import { useRouteData } from './utils/route-data';

export const onRequest = defineMiddleware(async (context, next) => {
context.locals.t = useTranslations(context.currentLocale);
attachRouteData(context.locals, await useRouteData(context), context.url);
context.locals.routeData = await useRouteData(context);
return next();
});
50 changes: 0 additions & 50 deletions packages/starlight/routes/static/404.astro
Original file line number Diff line number Diff line change
@@ -1,57 +1,7 @@
---
import { getEntry, render } from 'astro:content';
import project from 'virtual:starlight/project-context';
import config from 'virtual:starlight/user-config';
import { getCollectionPathFromRoot } from '../../utils/collection';
import {
normalizeCollectionEntry,
type Route,
type StarlightDocsCollectionEntry,
type StarlightDocsEntry,
} from '../../utils/routing';
import { BuiltInDefaultLocale } from '../../utils/i18n';
import CommonPage from '../common.astro';
import { attachRouteData, generateRouteData } from '../../utils/route-data';

export const prerender = true;

const { lang = BuiltInDefaultLocale.lang, dir = BuiltInDefaultLocale.dir } =
config.defaultLocale || {};
let locale = config.defaultLocale?.locale;
if (locale === 'root') locale = undefined;

const entryMeta = { dir, lang, locale };

const fallbackEntry: StarlightDocsEntry = {
slug: '404',
id: '404',
body: '',
collection: 'docs',
data: {
title: '404',
template: 'splash',
editUrl: false,
head: [],
hero: { tagline: Astro.locals.t('404.text'), actions: [] },
pagefind: false,
sidebar: { hidden: false, attrs: {} },
draft: false,
},
filePath: `${getCollectionPathFromRoot('docs', project)}/404.md`,
};

const userEntry = (await getEntry('docs', '404')) as StarlightDocsCollectionEntry;
const entry = userEntry ? normalizeCollectionEntry(userEntry) : fallbackEntry;
const route: Route = { ...entryMeta, entryMeta, entry, id: entry.id, slug: entry.slug };
const { Content, headings } = await render(route.entry);
attachRouteData(
Astro.locals,
{
...generateRouteData({ props: { ...route, headings }, url: Astro.url }),
Content,
},
Astro.url
);
---

<CommonPage />
70 changes: 47 additions & 23 deletions packages/starlight/utils/route-data.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import type { APIContext, MarkdownHeading } from 'astro';
import project from 'virtual:starlight/project-context';
import config from 'virtual:starlight/user-config';
import { generateToC, type TocItem } from './generateToC';
import { getNewestCommitDate } from 'virtual:starlight/git-info';
import { getPrevNextLinks, getSidebar, type SidebarEntry } from './navigation';
import { ensureTrailingSlash } from './path';
import { getRouteBySlugParam, type Route } from './routing';
import {
getRouteBySlugParam,
normalizeCollectionEntry,
type Route,
type StarlightDocsCollectionEntry,
type StarlightDocsEntry,
} from './routing';
import { formatPath } from './format-path';
import { useTranslations } from './translations';
import { DeprecatedLabelsPropProxy } from './i18n';
import { render, type RenderResult } from 'astro:content';
import { BuiltInDefaultLocale, DeprecatedLabelsPropProxy } from './i18n';
import { getEntry, render, type RenderResult } from 'astro:content';
import { getCollectionPathFromRoot } from './collection';

export interface PageProps extends Route {
headings: MarkdownHeading[];
Expand Down Expand Up @@ -39,26 +47,10 @@ export interface StarlightRouteData extends Route {
Content?: RenderResult['Content'];
}

export function attachRouteData(
locals: App.Locals,
routeData: StarlightRouteData | undefined,
currentUrl: URL
): void {
Reflect.defineProperty(locals, 'routeData', {
enumerable: true,
configurable: true,
get() {
if (!routeData) {
throw new Error('Starlight route data undefined for route: ' + currentUrl.pathname);
}
return routeData;
},
});
}

export async function useRouteData(context: APIContext): Promise<StarlightRouteData | undefined> {
const route = getRouteBySlugParam(context.params.slug);
if (!route) return;
export async function useRouteData(context: APIContext): Promise<StarlightRouteData> {
const route =
('slug' in context.params && getRouteBySlugParam(context.params.slug)) ||
(await get404Route(context.locals));
const { Content, headings } = await render(route.entry);
const routeData = generateRouteData({ props: { ...route, headings }, url: context.url });
return { ...routeData, Content };
Expand Down Expand Up @@ -149,3 +141,35 @@ export function getSiteTitle(lang: string): string {
export function getSiteTitleHref(locale: string | undefined): string {
return formatPath(locale || '/');
}

/** Generate a route object for Starlight’s 404 page. */
async function get404Route(locals: App.Locals): Promise<Route> {
const { lang = BuiltInDefaultLocale.lang, dir = BuiltInDefaultLocale.dir } =
config.defaultLocale || {};
let locale = config.defaultLocale?.locale;
if (locale === 'root') locale = undefined;

const entryMeta = { dir, lang, locale };

const fallbackEntry: StarlightDocsEntry = {
slug: '404',
id: '404',
body: '',
collection: 'docs',
data: {
title: '404',
template: 'splash',
editUrl: false,
head: [],
hero: { tagline: locals.t('404.text'), actions: [] },
pagefind: false,
sidebar: { hidden: false, attrs: {} },
draft: false,
},
filePath: `${getCollectionPathFromRoot('docs', project)}/404.md`,
};

const userEntry = (await getEntry('docs', '404')) as StarlightDocsCollectionEntry;
const entry = userEntry ? normalizeCollectionEntry(userEntry) : fallbackEntry;
return { ...entryMeta, entryMeta, entry, id: entry.id, slug: entry.slug };
}
Loading