Starlight 0.32

By
Chris Swithinbank

Starlight 0.32 is here! Let’s unpack what’s new as we work our way towards a v1 release.

🧘 We’ve been stretching to make Starlight extra extendable. Here’s our latest flow for more flexibility:

To upgrade an existing Starlight site, use the automated @astrojs/upgrade CLI tool. This will update Starlight, Astro, and any other integrations you are using:

npx @astrojs/upgrade

A new route data paradigm

Starlight’s component override system allows users to customize a site’s appearance with their own components. This is great for extending Starlight’s UI, but over time, we saw a pattern develop where people also used overrides to modify component data, while still reusing Starlight’s built-in components.

To make this use case easier, v0.32 introduces a new route middleware system that provides full access to Starlight’s data model without needing to override any components. This is particularly helpful for plugins as it avoids common conflicts where several plugins tried to override the same component.

Similar to Astro’s middleware system, route middleware is called for every Starlight page render and gives you the opportunity to modify any data before it gets rendered. This is a powerful way to implement custom logic not currently possible with configuration alone.

In the following example, we try to make our docs more exciting by adding exclamation marks to the end of every page’s title!!!

import { defineRouteMiddleware } from '@astrojs/starlight/route-data';
export const onRequest = defineRouteMiddleware((context) => {
// Get the content collection entry for this page.
const { entry } = context.locals.starlightRoute;
// Update the title to add exclamation marks.
entry.data.title = entry.data.title + '!!!';
});

See the “Route Data” guide for full details about how to write route middleware.

Breaking changes

To better support route middleware, we have updated how Starlight’s default components receive route data.

Previously, all of Starlight’s templating components, including user or plugin overrides, had access to a data object for the current route via Astro.props. This data is now available as Astro.locals.starlightRoute instead.

See the Starlight changelog for full details of how to migrate to this new approach.

New i18n APIs for plugins

This release gives plugins full access to Starlight’s powerful built-in internationalization system.

Plugins can now call useTranslations() in the config:setup hook to access any of Starlight’s UI strings. This opens up possibilities for localized logging, using translations in Markdown plugins, and more.

This example plugin logs Starlight’s default “Built with Starlight” text string and uses the translation matching the user’s locale if it is available:

export default {
name: 'localizedPlugin',
hooks: {
'config:setup'({ useTranslations, logger }) {
// Detect the current user’s preferred locale.
const userLocale = Intl.DateTimeFormat().resolvedOptions().locale;
// Get a `t()` function for the locale.
const t = useTranslations(userLocale);
// Log the localized string.
logger.info(t('builtWithStarlight.label'));
},
},
};

Updated plugin hooks

As part of the rework to support translation use in plugins, we have split the old setup hook into two: i18n:setup and config:setup. Use of the setup hook is deprecated and plugins should migrate to using config:setup instead:

export default {
name: 'starlight-plugin',
hooks: {
'setup'({ config }) {
'config:setup'({ config }) {
// Your plugin configuration setup code
},
},
};

Plugins using the injectTranslations() utility need to move this to the dedicated i18n:setup hook:

export default {
name: 'plugin-with-translations',
hooks: {
'config:setup'({ injectTranslations }) {
'i18n:setup'({ injectTranslations }) {
injectTranslations({
en: { 'myPlugin.doThing': 'Do the thing' },
fr: { 'myPlugin.doThing': 'Faire le truc' },
});
},
},
};

Multisite search support

Starlight provides site search out of the box using Pagefind. This release exposes Pagefind’s multisite search configuration, so you can support searching across multiple sites.

For example, if you have a main site at example.com indexed with Pagefind and your Starlight site deployed to the docs.example.com subdomain, you can display search results from your main site in your docs with the mergeIndex configuration option:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
export default defineConfig({
site: 'https://docs.example.com/',
integrations: [
starlight({
title: 'Docs with multisite search',
pagefind: {
mergeIndex: [{ bundlePath: 'https://example.com/pagefind' }],
},
}),
],
});

See Pagefind’s guide to “Searching multiple sites” for full details of the available configuration options.

Bug fixes and more

As always, we’ve also been working to fix issues since the v0.31 release. See the Starlight changelog for all the details including detailed migration guidance.

Thanks

Thanks to everyone who contributed to this release with PRs and reviews, including HiDeoo, Emilien Guilmineau, trueberryless, Sarah Rainsberger, Lorenzo Lewis, and Yan Thomas.

We look forward to seeing what you build with Starlight 0.32! If you have questions, comments, or just want to say hi, drop by the Astro Discord.

Previously…

Starlight 0.28

Meet the latest Starlight features: i18next, on-demand rendering support, sidebar persistence, smart tabs, and more for your docs.