Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Pagefind to 1.3.0 and configure Pagefind logging levels #2728

Merged
merged 15 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
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
7 changes: 7 additions & 0 deletions .changeset/long-pears-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@astrojs/starlight': minor
---

Updates minimum Pagefind dependency to v1.3.0, sets new defaults for Pagefind’s ranking options, and adds support for manually configuring the ranking options

The new ranking option defaults have been evaluated against Starlight’s own docs to improve the quality of search results. See [“Customize Pagefind's result ranking”](https://pagefind.app/docs/ranking/) for more details about how they work.
5 changes: 5 additions & 0 deletions .changeset/young-plants-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/starlight': minor
---

Fixes Pagefind logging to respect the Astro log level. When using Astro’s `--verbose` or `--silent` CLI flags, these are now respected by Pagefind as well.
20 changes: 18 additions & 2 deletions docs/src/content/docs/reference/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -447,16 +447,32 @@ When using custom themes and setting this to `true`, you must provide at least o

### `pagefind`

**type:** `boolean`
**type:** <code>boolean | <a href="#pagefindoptions">PagefindOptions</a></code>
**default:** `true`

Define whether Starlight’s default site search provider [Pagefind](https://pagefind.app/) is enabled.
Configure Starlight’s default site search provider [Pagefind](https://pagefind.app/).

Set to `false` to disable indexing your site with Pagefind.
This will also hide the default search UI if in use.

Pagefind cannot be enabled when the [`prerender`](#prerender) option is set to `false`.

Set `pagefind` to an object to configure the Pagefind search client.
See [“Customize Pagefind's result ranking”](https://pagefind.app/docs/ranking/) in the Pagefind documentation for more details about using the `pagefind.ranking` option to control how search result ranking is calculated.

#### `PagefindOptions`

```ts
interface PagefindOptions {
ranking?: {
pageLength?: number;
termFrequency?: number;
termSaturation?: number;
termSimilarity?: number;
};
}
```

### `prerender`

**type:** `boolean`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
{
"name": "/_astro/*.js",
"path": "examples/basics/dist/_astro/*.js",
"limit": "23.5 kB",
"limit": "27 kB",
"gzip": true
},
{
Expand Down
9 changes: 8 additions & 1 deletion packages/starlight/__tests__/basics/config-errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,14 @@ test('parses valid config successfully', () => {
"isUsingBuiltInDefaultLocale": true,
"lastUpdated": false,
"locales": undefined,
"pagefind": true,
"pagefind": {
"ranking": {
"pageLength": 0.1,
"termFrequency": 0.1,
"termSaturation": 2,
"termSimilarity": 9,
},
},
"pagination": true,
"prerender": true,
"tableOfContents": {
Expand Down
3 changes: 3 additions & 0 deletions packages/starlight/components/Search.astro
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ if (project.trailingSlash === 'never') dataAttributes['data-strip-trailing-slash
</script>

<script>
import { pagefindUserConfig } from 'virtual:starlight/pagefind-config';

class SiteSearch extends HTMLElement {
constructor() {
super();
Expand Down Expand Up @@ -139,6 +141,7 @@ if (project.trailingSlash === 'never') dataAttributes['data-strip-trailing-slash
// @ts-expect-error — Missing types for @pagefind/default-ui package.
const { PagefindUI } = await import('@pagefind/default-ui');
new PagefindUI({
...pagefindUserConfig,
element: '#starlight__search',
baseUrl: import.meta.env.BASE_URL,
bundlePath: import.meta.env.BASE_URL.replace(/\/$/, '') + '/pagefind/',
Expand Down
23 changes: 20 additions & 3 deletions packages/starlight/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/// <reference path="./virtual.d.ts" />

import mdx from '@astrojs/mdx';
import type { AstroIntegration } from 'astro';
import type { AstroIntegration, AstroIntegrationLogger } from 'astro';
import { AstroError } from 'astro/errors';
import { spawn } from 'node:child_process';
import { dirname, relative } from 'node:path';
Expand Down Expand Up @@ -145,13 +145,14 @@ export default function StarlightIntegration(
injectPluginTranslationsTypes(pluginTranslations, injectTypes);
},

'astro:build:done': ({ dir }) => {
'astro:build:done': ({ dir, logger }) => {
if (!userConfig.pagefind) return;
const loglevelFlag = getPagefindLoggingFlags(logger.options.level);
const targetDir = fileURLToPath(dir);
const cwd = dirname(fileURLToPath(import.meta.url));
const relativeDir = relative(cwd, targetDir);
return new Promise<void>((resolve) => {
spawn('npx', ['-y', 'pagefind', '--site', relativeDir], {
spawn('npx', ['-y', 'pagefind', ...loglevelFlag, '--site', relativeDir], {
stdio: 'inherit',
shell: true,
cwd,
Expand All @@ -161,3 +162,19 @@ export default function StarlightIntegration(
},
};
}

/** Map the logging level of Astro’s logger to one of Pagefind’s logging level flags. */
function getPagefindLoggingFlags(level: AstroIntegrationLogger['options']['level']) {
switch (level) {
case 'silent':
case 'error':
return ['--silent'];
case 'warn':
return ['--quiet'];
case 'debug':
return ['--verbose'];
case 'info':
default:
return [];
}
}
1 change: 1 addition & 0 deletions packages/starlight/integrations/virtual-user-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export function vitePluginStarlightUserConfig(
} catch {}
export const collections = userCollections;`,
'virtual:starlight/plugin-translations': `export default ${JSON.stringify(pluginTranslations)}`,
'virtual:starlight/pagefind-config': `export const pagefindUserConfig = ${JSON.stringify(opts.pagefind || {})}`,
...virtualComponentModules,
} satisfies Record<string, string>;

Expand Down
4 changes: 2 additions & 2 deletions packages/starlight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
"dependencies": {
"@astrojs/mdx": "^4.0.1",
"@astrojs/sitemap": "^3.1.6",
"@pagefind/default-ui": "^1.0.3",
"@pagefind/default-ui": "^1.3.0",
"@types/hast": "^3.0.4",
"@types/js-yaml": "^4.0.9",
"@types/mdast": "^4.0.4",
Expand All @@ -207,7 +207,7 @@
"mdast-util-directive": "^3.0.0",
"mdast-util-to-markdown": "^2.1.0",
"mdast-util-to-string": "^4.0.0",
"pagefind": "^1.0.3",
"pagefind": "^1.3.0",
"rehype": "^13.0.1",
"rehype-format": "^5.0.0",
"remark-directive": "^3.0.0",
Expand Down
44 changes: 44 additions & 0 deletions packages/starlight/schemas/pagefind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { z } from 'astro/zod';

const pagefindSchema = z.object({
/** Configure how search result rankings are calculated by Pagefind. */
ranking: z
.object({
/**
* Set Pagefind’s `pageLength` ranking option.
*
* The default value is `0.1` and values must be in the range `0` to `1`.
*
* @see https://pagefind.app/docs/ranking/#configuring-page-length
*/
pageLength: z.number().min(0).max(1).default(0.1),
/**
* Set Pagefind’s `termFrequency` ranking option.
*
* The default value is `0.1` and values must be in the range `0` to `1`.
*
* @see https://pagefind.app/docs/ranking/#configuring-term-frequency
*/
termFrequency: z.number().min(0).max(1).default(0.1),
/**
* Set Pagefind’s `termSaturation` ranking option.
*
* The default value is `2` and values must be in the range `0` to `2`.
*
* @see https://pagefind.app/docs/ranking/#configuring-term-saturation
*/
termSaturation: z.number().min(0).max(2).default(2),
/**
* Set Pagefind’s `termSimilarity` ranking option.
*
* The default value is `9` and values must be greater than or equal to `0`.
*
* @see https://pagefind.app/docs/ranking/#configuring-term-similarity
*/
termSimilarity: z.number().min(0).default(9),
})
.default({}),
});

export const PagefindConfigSchema = () => pagefindSchema;
export const PagefindConfigDefaults = () => pagefindSchema.parse({});
22 changes: 15 additions & 7 deletions packages/starlight/utils/user-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { ExpressiveCodeSchema } from '../schemas/expressiveCode';
import { FaviconSchema } from '../schemas/favicon';
import { HeadConfigSchema } from '../schemas/head';
import { LogoConfigSchema } from '../schemas/logo';
import { PagefindConfigDefaults, PagefindConfigSchema } from '../schemas/pagefind';
import { SidebarItemSchema } from '../schemas/sidebar';
import { TitleConfigSchema, TitleTransformConfigSchema } from '../schemas/site-title';
import { SocialLinksSchema } from '../schemas/social';
import { TableOfContentsSchema } from '../schemas/tableOfContents';
import { TitleConfigSchema, TitleTransformConfigSchema } from '../schemas/site-title';
import { BuiltInDefaultLocale } from './i18n';

const LocaleSchema = z.object({
Expand Down Expand Up @@ -191,11 +192,15 @@ const UserConfigSchema = z.object({
expressiveCode: ExpressiveCodeSchema(),

/**
* Define whether Starlight’s default site search provider Pagefind is enabled.
* Set to `false` to disable indexing your site with Pagefind.
* This will also hide the default search UI if in use.
* Configure Starlight’s default site search provider Pagefind. Set to `false` to disable indexing
* your site with Pagefind, which will also hide the default search UI if in use.
*/
pagefind: z.boolean().optional(),
pagefind: z
.boolean()
// Transform `true` to our default config object.
.transform((val) => val && PagefindConfigDefaults())
.or(PagefindConfigSchema())
.optional(),

/** Specify paths to components that should override Starlight’s default components */
components: ComponentConfigSchema(),
Expand Down Expand Up @@ -227,10 +232,13 @@ export const StarlightConfigSchema = UserConfigSchema.strict()
.transform((config) => ({
...config,
// Pagefind only defaults to true if prerender is also true.
pagefind: config.pagefind ?? config.prerender,
pagefind:
typeof config.pagefind === 'undefined'
? config.prerender && PagefindConfigDefaults()
: config.pagefind,
}))
.refine((config) => !(!config.prerender && config.pagefind), {
message: 'Pagefind search is not support with prerendering disabled.',
message: 'Pagefind search is not supported with prerendering disabled.',
})
.transform(({ title, locales, defaultLocale, ...config }, ctx) => {
const configuredLocales = Object.keys(locales ?? {});
Expand Down
6 changes: 6 additions & 0 deletions packages/starlight/virtual-internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ declare module 'virtual:starlight/collection-config' {
export const collections: import('astro:content').ContentConfig['collections'] | undefined;
}

declare module 'virtual:starlight/pagefind-config' {
export const pagefindUserConfig: Partial<
Extract<import('./types').StarlightConfig['pagefind'], object>
>;
}

declare module 'virtual:starlight/components/Banner' {
const Banner: typeof import('./components/Banner.astro').default;
export default Banner;
Expand Down
46 changes: 23 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading