@astrojs/starlight 0.31.1 → 0.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/components/Banner.astro +1 -3
  3. package/components/ContentPanel.astro +0 -4
  4. package/components/DraftContentNotice.astro +0 -1
  5. package/components/EditLink.astro +1 -2
  6. package/components/FallbackContentNotice.astro +0 -1
  7. package/components/Footer.astro +3 -5
  8. package/components/Head.astro +1 -2
  9. package/components/Header.astro +5 -6
  10. package/components/Hero.astro +1 -2
  11. package/components/LanguageSelect.astro +2 -3
  12. package/components/LastUpdated.astro +1 -3
  13. package/components/MarkdownContent.astro +0 -1
  14. package/components/MobileMenuFooter.astro +3 -4
  15. package/components/MobileMenuToggle.astro +0 -1
  16. package/components/MobileTableOfContents.astro +1 -2
  17. package/components/Page.astro +32 -32
  18. package/components/PageFrame.astro +2 -3
  19. package/components/PageSidebar.astro +3 -5
  20. package/components/PageTitle.astro +1 -2
  21. package/components/Pagination.astro +1 -2
  22. package/components/Search.astro +17 -3
  23. package/components/Sidebar.astro +3 -5
  24. package/components/SidebarPersister.astro +1 -2
  25. package/components/SidebarSublist.astro +2 -1
  26. package/components/SiteTitle.astro +1 -2
  27. package/components/SkipLink.astro +0 -1
  28. package/components/SocialIcons.astro +0 -1
  29. package/components/StarlightPage.astro +7 -3
  30. package/components/TableOfContents.astro +1 -2
  31. package/components/ThemeProvider.astro +0 -1
  32. package/components/ThemeSelect.astro +0 -1
  33. package/components/TwoColumnContent.astro +1 -5
  34. package/index.ts +7 -9
  35. package/integrations/asides.ts +4 -7
  36. package/integrations/expressive-code/index.ts +15 -10
  37. package/integrations/shared/{pathToLocale.ts → absolutePathToLang.ts} +7 -5
  38. package/integrations/virtual-user-config.ts +27 -0
  39. package/locals.d.ts +26 -0
  40. package/locals.ts +37 -2
  41. package/package.json +5 -3
  42. package/props.ts +13 -1
  43. package/route-data.ts +11 -0
  44. package/routes/common.astro +5 -11
  45. package/routes/ssr/index.astro +1 -1
  46. package/routes/static/404.astro +1 -41
  47. package/routes/static/index.astro +1 -4
  48. package/schemas/pagefind.ts +97 -33
  49. package/types.ts +1 -0
  50. package/utils/i18n.ts +0 -20
  51. package/utils/navigation.ts +19 -36
  52. package/utils/plugins.ts +316 -141
  53. package/utils/{route-data.ts → routing/data.ts} +56 -30
  54. package/utils/{routing.ts → routing/index.ts} +6 -44
  55. package/utils/routing/middleware.ts +81 -0
  56. package/utils/routing/types.ts +96 -0
  57. package/utils/slugs.ts +2 -10
  58. package/utils/starlight-page.ts +2 -10
  59. package/utils/user-config.ts +8 -0
  60. package/virtual-internal.d.ts +4 -0
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  import Select from './Select.astro';
3
- import type { Props } from '../props';
4
3
  ---
5
4
 
6
5
  <starlight-theme-select>
@@ -1,10 +1,6 @@
1
- ---
2
- import type { Props } from '../props';
3
- ---
4
-
5
1
  <div class="lg:sl-flex">
6
2
  {
7
- Astro.props.toc && (
3
+ Astro.locals.starlightRoute.toc && (
8
4
  <aside class="right-sidebar-container print:hidden">
9
5
  <div class="right-sidebar">
10
6
  <slot name="right-sidebar" />
package/index.ts CHANGED
@@ -18,7 +18,6 @@ import { starlightExpressiveCode } from './integrations/expressive-code/index';
18
18
  import { starlightSitemap } from './integrations/sitemap';
19
19
  import { vitePluginStarlightUserConfig } from './integrations/virtual-user-config';
20
20
  import { rehypeRtlCodeSupport } from './integrations/code-rtl-support';
21
- import { createTranslationSystemFromFs } from './utils/translations-fs';
22
21
  import {
23
22
  injectPluginTranslationsTypes,
24
23
  runPlugins,
@@ -65,16 +64,10 @@ export default function StarlightIntegration(
65
64
  config.i18n
66
65
  );
67
66
 
68
- const integrations = pluginResult.integrations;
67
+ const { integrations, useTranslations, absolutePathToLang } = pluginResult;
69
68
  pluginTranslations = pluginResult.pluginTranslations;
70
69
  userConfig = starlightConfig;
71
70
 
72
- const useTranslations = createTranslationSystemFromFs(
73
- starlightConfig,
74
- config,
75
- pluginTranslations
76
- );
77
-
78
71
  addMiddleware({ entrypoint: '@astrojs/starlight/locals', order: 'pre' });
79
72
 
80
73
  if (!starlightConfig.disable404Route) {
@@ -127,7 +120,12 @@ export default function StarlightIntegration(
127
120
  },
128
121
  markdown: {
129
122
  remarkPlugins: [
130
- ...starlightAsides({ starlightConfig, astroConfig: config, useTranslations }),
123
+ ...starlightAsides({
124
+ starlightConfig,
125
+ astroConfig: config,
126
+ useTranslations,
127
+ absolutePathToLang,
128
+ }),
131
129
  ],
132
130
  rehypePlugins: [rehypeRtlCodeSupport()],
133
131
  shikiConfig:
@@ -14,15 +14,13 @@ import { toString } from 'mdast-util-to-string';
14
14
  import remarkDirective from 'remark-directive';
15
15
  import type { Plugin, Transformer } from 'unified';
16
16
  import { visit } from 'unist-util-visit';
17
- import type { StarlightConfig } from '../types';
18
- import type { createTranslationSystemFromFs } from '../utils/translations-fs';
19
- import { pathToLocale } from './shared/pathToLocale';
20
- import { localeToLang } from './shared/localeToLang';
17
+ import type { HookParameters, StarlightConfig } from '../types';
21
18
 
22
19
  interface AsidesOptions {
23
20
  starlightConfig: Pick<StarlightConfig, 'defaultLocale' | 'locales'>;
24
21
  astroConfig: { root: AstroConfig['root']; srcDir: AstroConfig['srcDir'] };
25
- useTranslations: ReturnType<typeof createTranslationSystemFromFs>;
22
+ useTranslations: HookParameters<'config:setup'>['useTranslations'];
23
+ absolutePathToLang: HookParameters<'config:setup'>['absolutePathToLang'];
26
24
  }
27
25
 
28
26
  /** Hacky function that generates an mdast HTML tree ready for conversion to HTML by rehype. */
@@ -151,8 +149,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
151
149
  };
152
150
 
153
151
  const transformer: Transformer<Root> = (tree, file) => {
154
- const locale = pathToLocale(file.history[0], options);
155
- const lang = localeToLang(options.starlightConfig, locale);
152
+ const lang = options.absolutePathToLang(file.path);
156
153
  const t = options.useTranslations(lang);
157
154
  visit(tree, (node, index, parent) => {
158
155
  if (!parent || index === undefined || !isNodeDirective(node)) {
@@ -5,10 +5,10 @@ import {
5
5
  } from 'astro-expressive-code';
6
6
  import { addClassName } from 'astro-expressive-code/hast';
7
7
  import type { AstroIntegration } from 'astro';
8
- import type { StarlightConfig } from '../../types';
9
- import type { createTranslationSystemFromFs } from '../../utils/translations-fs';
10
- import { pathToLocale } from '../shared/pathToLocale';
8
+ import type { HookParameters, StarlightConfig } from '../../types';
9
+ import { absolutePathToLang } from '../shared/absolutePathToLang';
11
10
  import { slugToLocale } from '../shared/slugToLocale';
11
+ import { localeToLang } from '../shared/localeToLang';
12
12
  import {
13
13
  applyStarlightUiThemeColors,
14
14
  preprocessThemes,
@@ -64,7 +64,7 @@ export type StarlightExpressiveCodeOptions = Omit<AstroExpressiveCodeOptions, 't
64
64
 
65
65
  type StarlightEcIntegrationOptions = {
66
66
  starlightConfig: StarlightConfig;
67
- useTranslations?: ReturnType<typeof createTranslationSystemFromFs> | undefined;
67
+ useTranslations: HookParameters<'config:setup'>['useTranslations'];
68
68
  };
69
69
 
70
70
  /**
@@ -110,8 +110,8 @@ export function getStarlightEcConfigPreprocessor({
110
110
  },
111
111
  });
112
112
 
113
- // Add Expressive Code UI translations (if any) for all defined locales
114
- if (useTranslations) addTranslations(starlightConfig, useTranslations);
113
+ // Add Expressive Code UI translations for all defined locales
114
+ addTranslations(starlightConfig, useTranslations);
115
115
 
116
116
  return {
117
117
  themes,
@@ -153,10 +153,15 @@ export function getStarlightEcConfigPreprocessor({
153
153
  },
154
154
  ...otherStyleOverrides,
155
155
  },
156
- getBlockLocale: ({ file }) =>
157
- file.url
158
- ? slugToLocale(file.url.pathname.slice(1), starlightConfig)
159
- : pathToLocale(file.path, { starlightConfig, astroConfig }),
156
+ getBlockLocale: ({ file }) => {
157
+ if (file.url) {
158
+ const locale = slugToLocale(file.url.pathname.slice(1), starlightConfig);
159
+ return localeToLang(starlightConfig, locale);
160
+ }
161
+ // Note that EC cannot use the `absolutePathToLang` helper passed down to plugins as this callback
162
+ // is also called in the context of the `<Code>` component.
163
+ return absolutePathToLang(file.path, { starlightConfig, astroConfig });
164
+ },
160
165
  plugins,
161
166
  ...rest,
162
167
  };
@@ -1,11 +1,12 @@
1
1
  import type { AstroConfig } from 'astro';
2
2
  import type { StarlightConfig } from '../../types';
3
+ import { localeToLang } from './localeToLang';
3
4
  import { getCollectionPath } from '../../utils/collection';
4
5
  import { slugToLocale } from './slugToLocale';
5
6
 
6
- /** Get current locale from the full file path. */
7
- export function pathToLocale(
8
- path: string | undefined,
7
+ /** Get current language from an absolute file path. */
8
+ export function absolutePathToLang(
9
+ path: string,
9
10
  {
10
11
  starlightConfig,
11
12
  astroConfig,
@@ -13,7 +14,7 @@ export function pathToLocale(
13
14
  starlightConfig: Pick<StarlightConfig, 'defaultLocale' | 'locales'>;
14
15
  astroConfig: { root: AstroConfig['root']; srcDir: AstroConfig['srcDir'] };
15
16
  }
16
- ): string | undefined {
17
+ ): string {
17
18
  const docsPath = getCollectionPath('docs', astroConfig.srcDir);
18
19
  // Format path to unix style path.
19
20
  path = path?.replace(/\\/g, '/');
@@ -23,5 +24,6 @@ export function pathToLocale(
23
24
  // Strip docs path leaving only content collection file ID.
24
25
  // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
25
26
  const slug = path?.replace(docsPath, '');
26
- return slugToLocale(slug, starlightConfig);
27
+ const locale = slugToLocale(slug, starlightConfig);
28
+ return localeToLang(starlightConfig, locale);
27
29
  }
@@ -100,6 +100,33 @@ export function vitePluginStarlightUserConfig(
100
100
  } catch {}
101
101
  export const collections = userCollections;`,
102
102
  'virtual:starlight/plugin-translations': `export default ${JSON.stringify(pluginTranslations)}`,
103
+ /**
104
+ * Exports an array of route middleware functions.
105
+ * For example, might generate a module that looks like:
106
+ *
107
+ * ```js
108
+ * import { onRequest as routeMiddleware0 } from "/users/houston/docs/src/middleware";
109
+ * import { onRequest as routeMiddleware1 } from "@houston-inc/plugin/middleware";
110
+ *
111
+ * export const routeMiddleware = [
112
+ * routeMiddleware0,
113
+ * routeMiddleware1,
114
+ * ];
115
+ * ```
116
+ */
117
+ 'virtual:starlight/route-middleware':
118
+ opts.routeMiddleware
119
+ .reduce(
120
+ ([imports, entries], id, index) => {
121
+ const importName = `routeMiddleware${index}`;
122
+ imports += `import { onRequest as ${importName} } from ${resolveId(id)};\n`;
123
+ entries += `\t${importName},\n`;
124
+ return [imports, entries] as [string, string];
125
+ },
126
+ ['', 'export const routeMiddleware = [\n'] as [string, string]
127
+ )
128
+ .join('\n') + '];',
129
+ /** Map of modules exporting Starlight’s templating components. */
103
130
  'virtual:starlight/pagefind-config': `export const pagefindUserConfig = ${JSON.stringify(opts.pagefind || {})}`,
104
131
  ...virtualComponentModules,
105
132
  } satisfies Record<string, string>;
package/locals.d.ts CHANGED
@@ -12,6 +12,32 @@ declare namespace StarlightApp {
12
12
  */
13
13
  declare namespace App {
14
14
  interface Locals {
15
+ /**
16
+ * Starlight’s localization API, powered by i18next.
17
+ *
18
+ * @see https://starlight.astro.build/guides/i18n/#using-ui-translations
19
+ *
20
+ * @example
21
+ * // Render a UI string for the current locale.
22
+ * <p>{Astro.locals.t('404.text')}</p>
23
+ */
15
24
  t: import('./utils/createTranslationSystem').I18nT;
25
+
26
+ /**
27
+ * Starlight’s data for the current route.
28
+ *
29
+ * @see https://starlight.astro.build/guides/route-data/
30
+ *
31
+ * @throws Will throw an error if accessed on non-Starlight routes.
32
+ *
33
+ * @example
34
+ * // Render the title for the current page
35
+ * <h1>{Astro.locals.starlightRoute.entry.data.title}</h1>
36
+ *
37
+ * @example
38
+ * // Check if the current page should render the sidebar
39
+ * const { hasSidebar } = Astro.locals.starlightRoute;
40
+ */
41
+ starlightRoute: import('./utils/routing/types').StarlightRouteData;
16
42
  }
17
43
  }
package/locals.ts CHANGED
@@ -1,8 +1,43 @@
1
+ import type { APIContext } from 'astro';
2
+ import { AstroError } from 'astro/errors';
1
3
  import { defineMiddleware } from 'astro:middleware';
4
+ import type { StarlightRouteData } from './route-data';
2
5
  import { useTranslations } from './utils/translations';
3
6
 
4
- export const onRequest = defineMiddleware((context, next) => {
7
+ export const onRequest = defineMiddleware(async (context, next) => {
5
8
  context.locals.t = useTranslations(context.currentLocale);
6
-
9
+ initializeStarlightRoute(context);
7
10
  return next();
8
11
  });
12
+
13
+ /**
14
+ * Sets up a `starlightRoute` property on locals. Initially, this will throw an error if accessed.
15
+ * When rendering, Starlight’s routes set `starlightRoute` with the resolved route data object for
16
+ * the current page.
17
+ *
18
+ * This ensures Starlight components can easily access `starlightRoute` without needing type guards,
19
+ * we can throw a helpful message if `starlightRoute` is accessed on non-Starlight pages, and we
20
+ * avoid generating route data in this middleware which also runs for non-Starlight route.
21
+ */
22
+ export function initializeStarlightRoute(context: APIContext) {
23
+ if ('starlightRoute' in context.locals) return;
24
+ const state: { routeData: StarlightRouteData | undefined } = { routeData: undefined };
25
+ Object.defineProperty(context.locals, 'starlightRoute', {
26
+ get() {
27
+ if (!state.routeData) {
28
+ throw new AstroError(
29
+ '`locals.starlightRoute` is not defined',
30
+ 'This usually means a component that accesses `locals.starlightRoute` is being rendered outside of a Starlight page, which is not supported.\n\n' +
31
+ 'If this is a component you authored, you can do one of the following:\n\n' +
32
+ '1. Avoid using this component in non-Starlight pages.\n' +
33
+ '2. Wrap the code that reads `locals.starlightRoute` in a `try/catch` block and handle the cases where `starlightRoute` is not available.\n\n' +
34
+ 'If this is a Starlight built-in or third-party component, you may need to report a bug or avoid this use of the component.'
35
+ );
36
+ }
37
+ return state.routeData;
38
+ },
39
+ set(routeData: StarlightRouteData) {
40
+ state.routeData = routeData;
41
+ },
42
+ });
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/starlight",
3
- "version": "0.31.1",
3
+ "version": "0.32.1",
4
4
  "description": "Build beautiful, high-performance documentation websites with Astro",
5
5
  "keywords": [
6
6
  "docs",
@@ -159,6 +159,7 @@
159
159
  "./props": "./props.ts",
160
160
  "./schema": "./schema.ts",
161
161
  "./loaders": "./loaders.ts",
162
+ "./route-data": "./route-data.ts",
162
163
  "./types": "./types.ts",
163
164
  "./expressive-code": {
164
165
  "types": "./expressive-code.d.ts",
@@ -178,10 +179,10 @@
178
179
  "@astrojs/markdown-remark": "^6.0.1",
179
180
  "@playwright/test": "^1.45.0",
180
181
  "@types/node": "^18.16.19",
181
- "@vitest/coverage-v8": "^3.0.1",
182
+ "@vitest/coverage-v8": "^3.0.5",
182
183
  "astro": "^5.1.5",
183
184
  "linkedom": "^0.18.4",
184
- "vitest": "^3.0.1"
185
+ "vitest": "^3.0.5"
185
186
  },
186
187
  "dependencies": {
187
188
  "@astrojs/mdx": "^4.0.5",
@@ -198,6 +199,7 @@
198
199
  "hastscript": "^9.0.0",
199
200
  "i18next": "^23.11.5",
200
201
  "js-yaml": "^4.1.0",
202
+ "klona": "^2.0.6",
201
203
  "mdast-util-directive": "^3.0.0",
202
204
  "mdast-util-to-markdown": "^2.1.0",
203
205
  "mdast-util-to-string": "^4.0.0",
package/props.ts CHANGED
@@ -1,2 +1,14 @@
1
- export type { StarlightRouteData as Props } from './utils/route-data';
1
+ import type { StarlightRouteData } from './utils/routing/types';
2
2
  export type { StarlightPageProps } from './utils/starlight-page';
3
+
4
+ /**
5
+ * @deprecated The `Props` type is deprecated. If updating an override to use
6
+ * `Astro.locals.starlightRoute` instead of `Astro.props`, import the new `StarlightRouteData`
7
+ * type instead:
8
+ * ```astro
9
+ * ---
10
+ * import type { StarlightRouteData } from '@astrojs/starlight/route-data';
11
+ * ---
12
+ * ```
13
+ */
14
+ export type Props = StarlightRouteData;
package/route-data.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { APIContext } from 'astro';
2
+ export type { StarlightRouteData } from './utils/routing/types';
3
+
4
+ export type RouteMiddlewareHandler = (
5
+ context: APIContext,
6
+ next: () => Promise<void>
7
+ ) => void | Promise<void>;
8
+
9
+ export function defineRouteMiddleware(fn: RouteMiddlewareHandler) {
10
+ return fn;
11
+ }
@@ -1,17 +1,11 @@
1
1
  ---
2
- import { render } from 'astro:content';
3
- import { generateRouteData } from '../utils/route-data';
4
- import type { Route } from '../utils/routing';
5
2
  import Page from '../components/Page.astro';
3
+ import { useRouteData } from '../utils/routing/data';
4
+ import { attachRouteDataAndRunMiddleware } from '../utils/routing/middleware';
6
5
 
7
- export type Props = {
8
- route: Route;
9
- };
6
+ await attachRouteDataAndRunMiddleware(Astro, await useRouteData(Astro));
10
7
 
11
- const { route } = Astro.props;
12
-
13
- const { Content, headings } = await render(route.entry);
14
- const routeData = generateRouteData({ props: { ...route, headings }, url: Astro.url });
8
+ const { Content, entry } = Astro.locals.starlightRoute;
15
9
  ---
16
10
 
17
- <Page {...routeData}><Content frontmatter={route.entry.data} /></Page>
11
+ <Page>{Content && <Content frontmatter={entry.data} />}</Page>
@@ -11,4 +11,4 @@ if (route === undefined) {
11
11
  }
12
12
  ---
13
13
 
14
- <CommonPage route={route} />
14
+ <CommonPage />
@@ -1,47 +1,7 @@
1
1
  ---
2
- import { getEntry } from 'astro:content';
3
- import project from 'virtual:starlight/project-context';
4
- import config from 'virtual:starlight/user-config';
5
- import { getCollectionPathFromRoot } from '../../utils/collection';
6
- import {
7
- normalizeCollectionEntry,
8
- type Route,
9
- type StarlightDocsCollectionEntry,
10
- type StarlightDocsEntry,
11
- } from '../../utils/routing';
12
- import { BuiltInDefaultLocale } from '../../utils/i18n';
13
2
  import CommonPage from '../common.astro';
14
3
 
15
4
  export const prerender = true;
16
-
17
- const { lang = BuiltInDefaultLocale.lang, dir = BuiltInDefaultLocale.dir } =
18
- config.defaultLocale || {};
19
- let locale = config.defaultLocale?.locale;
20
- if (locale === 'root') locale = undefined;
21
-
22
- const entryMeta = { dir, lang, locale };
23
-
24
- const fallbackEntry: StarlightDocsEntry = {
25
- slug: '404',
26
- id: '404',
27
- body: '',
28
- collection: 'docs',
29
- data: {
30
- title: '404',
31
- template: 'splash',
32
- editUrl: false,
33
- head: [],
34
- hero: { tagline: Astro.locals.t('404.text'), actions: [] },
35
- pagefind: false,
36
- sidebar: { hidden: false, attrs: {} },
37
- draft: false,
38
- },
39
- filePath: `${getCollectionPathFromRoot('docs', project)}/404.md`,
40
- };
41
-
42
- const userEntry = (await getEntry('docs', '404')) as StarlightDocsCollectionEntry;
43
- const entry = userEntry ? normalizeCollectionEntry(userEntry) : fallbackEntry;
44
- const route: Route = { ...entryMeta, entryMeta, entry, id: entry.id, slug: entry.slug };
45
5
  ---
46
6
 
47
- <CommonPage {route} />
7
+ <CommonPage />
@@ -1,5 +1,4 @@
1
1
  ---
2
- import type { InferGetStaticPropsType } from 'astro';
3
2
  import { paths } from '../../utils/routing';
4
3
  import CommonPage from '../common.astro';
5
4
 
@@ -8,8 +7,6 @@ export const prerender = true;
8
7
  export async function getStaticPaths() {
9
8
  return paths;
10
9
  }
11
-
12
- type Props = InferGetStaticPropsType<typeof getStaticPaths>;
13
10
  ---
14
11
 
15
- <CommonPage route={Astro.props} />
12
+ <CommonPage />
@@ -1,43 +1,107 @@
1
1
  import { z } from 'astro/zod';
2
2
 
3
+ const indexWeightSchema = z.number().nonnegative().optional();
4
+ const pagefindRankingWeightsSchema = z.object({
5
+ /**
6
+ * Set Pagefind’s `pageLength` ranking option.
7
+ *
8
+ * The default value is `0.1` and values must be in the range `0` to `1`.
9
+ *
10
+ * @see https://pagefind.app/docs/ranking/#configuring-page-length
11
+ */
12
+ pageLength: z.number().min(0).max(1).default(0.1),
13
+ /**
14
+ * Set Pagefind’s `termFrequency` ranking option.
15
+ *
16
+ * The default value is `0.1` and values must be in the range `0` to `1`.
17
+ *
18
+ * @see https://pagefind.app/docs/ranking/#configuring-term-frequency
19
+ */
20
+ termFrequency: z.number().min(0).max(1).default(0.1),
21
+ /**
22
+ * Set Pagefind’s `termSaturation` ranking option.
23
+ *
24
+ * The default value is `2` and values must be in the range `0` to `2`.
25
+ *
26
+ * @see https://pagefind.app/docs/ranking/#configuring-term-saturation
27
+ */
28
+ termSaturation: z.number().min(0).max(2).default(2),
29
+ /**
30
+ * Set Pagefind’s `termSimilarity` ranking option.
31
+ *
32
+ * The default value is `9` and values must be greater than or equal to `0`.
33
+ *
34
+ * @see https://pagefind.app/docs/ranking/#configuring-term-similarity
35
+ */
36
+ termSimilarity: z.number().min(0).default(9),
37
+ });
38
+ const pagefindIndexOptionsSchema = z.object({
39
+ /**
40
+ * Overrides the URL path that Pagefind uses to load its search bundle
41
+ */
42
+ basePath: z.string().optional(),
43
+ /**
44
+ * Appends the given baseURL to all search results. May be a path, or a full domain
45
+ */
46
+ baseUrl: z.string().optional(),
47
+ /**
48
+ * Multiply all rankings for this index by the given weight.
49
+ *
50
+ * @see https://pagefind.app/docs/multisite/#changing-the-weighting-of-individual-indexes
51
+ */
52
+ indexWeight: indexWeightSchema,
53
+ /**
54
+ * Apply this filter configuration to all search results from this index.
55
+ *
56
+ * Only applies in multisite setups.
57
+ *
58
+ * @see https://pagefind.app/docs/multisite/#filtering-results-by-index
59
+ */
60
+ mergeFilter: z.record(z.string(), z.string().or(z.array(z.string()).nonempty())).optional(),
61
+ /**
62
+ * Language of this index.
63
+ *
64
+ * @see https://pagefind.app/docs/multisite/#merging-a-specific-language-index
65
+ */
66
+ language: z.string().optional(),
67
+ /**
68
+ * Configure how search result rankings are calculated by Pagefind.
69
+ */
70
+ ranking: pagefindRankingWeightsSchema.optional(),
71
+ });
72
+
3
73
  const pagefindSchema = z.object({
74
+ /**
75
+ * Configure how search results from the current website are weighted by Pagefind
76
+ * compared to results from other sites when using the `mergeIndex` option.
77
+ *
78
+ * @see https://pagefind.app/docs/multisite/#changing-the-weighting-of-individual-indexes
79
+ */
80
+ indexWeight: indexWeightSchema,
4
81
  /** Configure how search result rankings are calculated by Pagefind. */
5
- ranking: z
6
- .object({
7
- /**
8
- * Set Pagefind’s `pageLength` ranking option.
9
- *
10
- * The default value is `0.1` and values must be in the range `0` to `1`.
11
- *
12
- * @see https://pagefind.app/docs/ranking/#configuring-page-length
13
- */
14
- pageLength: z.number().min(0).max(1).default(0.1),
15
- /**
16
- * Set Pagefind’s `termFrequency` ranking option.
17
- *
18
- * The default value is `0.1` and values must be in the range `0` to `1`.
19
- *
20
- * @see https://pagefind.app/docs/ranking/#configuring-term-frequency
21
- */
22
- termFrequency: z.number().min(0).max(1).default(0.1),
23
- /**
24
- * Set Pagefind’s `termSaturation` ranking option.
25
- *
26
- * The default value is `2` and values must be in the range `0` to `2`.
27
- *
28
- * @see https://pagefind.app/docs/ranking/#configuring-term-saturation
29
- */
30
- termSaturation: z.number().min(0).max(2).default(2),
82
+ ranking: pagefindRankingWeightsSchema.default({}),
83
+ /**
84
+ * Configure how search indexes from different sites are merged by Pagefind.
85
+ *
86
+ * @see https://pagefind.app/docs/multisite/#searching-additional-sites-from-pagefind-ui
87
+ */
88
+ mergeIndex: z
89
+ .array(
31
90
  /**
32
- * Set Pagefind’s `termSimilarity` ranking option.
33
- *
34
- * The default value is `9` and values must be greater than or equal to `0`.
91
+ * Each entry of this array represents a `PagefindIndexOptions` from pagefind.
35
92
  *
36
- * @see https://pagefind.app/docs/ranking/#configuring-term-similarity
93
+ * @see https://github.com/CloudCannon/pagefind/blob/v1.3.0/pagefind_web_js/lib/coupled_search.ts#L549
37
94
  */
38
- termSimilarity: z.number().min(0).default(9),
39
- })
40
- .default({}),
95
+ pagefindIndexOptionsSchema.extend({
96
+ /**
97
+ * Set Pagefind’s `bundlePath` mergeIndex option.
98
+ *
99
+ * @see https://pagefind.app/docs/multisite/#searching-additional-sites-from-pagefind-ui
100
+ */
101
+ bundlePath: z.string(),
102
+ })
103
+ )
104
+ .optional(),
41
105
  });
42
106
 
43
107
  export const PagefindConfigSchema = () => pagefindSchema;
package/types.ts CHANGED
@@ -2,5 +2,6 @@ export type { StarlightConfig } from './utils/user-config';
2
2
  export type {
3
3
  StarlightPlugin,
4
4
  StarlightUserConfigWithPlugins as StarlightUserConfig,
5
+ HookParameters,
5
6
  } from './utils/plugins';
6
7
  export type { StarlightIcon } from './components/Icons';
package/utils/i18n.ts CHANGED
@@ -2,26 +2,6 @@ import type { AstroConfig } from 'astro';
2
2
  import { AstroError } from 'astro/errors';
3
3
  import type { StarlightConfig } from './user-config';
4
4
 
5
- /**
6
- * A proxy object that throws an error when a user tries to access the deprecated `labels` prop in
7
- * a component override.
8
- *
9
- * @todo Remove in a future release once people have updated — no later than v1.
10
- */
11
- export const DeprecatedLabelsPropProxy = new Proxy<Record<string, never>>(
12
- {},
13
- {
14
- get(_, key) {
15
- const label = String(key);
16
- throw new AstroError(
17
- `The \`labels\` prop in component overrides has been removed.`,
18
- `Replace \`Astro.props.labels["${label}"]\` with \`Astro.locals.t("${label}")\` instead.\n` +
19
- 'For more information see https://starlight.astro.build/guides/i18n/#using-ui-translations'
20
- );
21
- },
22
- }
23
- );
24
-
25
5
  /**
26
6
  * A list of well-known right-to-left languages used as a fallback when determining the text
27
7
  * direction of a locale is not supported by the `Intl.Locale` API in the current environment.