From 8d5a4e8000d9e3a4bb9ca8178767cf3d8bc48773 Mon Sep 17 00:00:00 2001 From: HiDeoo Date: Fri, 13 Dec 2024 22:57:28 +0100 Subject: Astro 5 + collection loaders + legacy collections support (#2612) Co-authored-by: Chris Swithinbank Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com> Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- .changeset/green-suns-drive.md | 56 + .changeset/polite-snails-sip.md | 13 + .github/workflows/ci.yml | 7 +- .gitignore | 3 - CONTRIBUTING.md | 6 +- docs/astro.config.mjs | 1 + docs/package.json | 3 +- docs/src/content.config.ts | 18 + docs/src/content/config.ts | 14 - docs/src/content/docs/components/code.mdx | 8 +- .../content/docs/components/using-components.mdx | 4 +- docs/src/content/docs/de/components/code.mdx | 8 +- docs/src/content/docs/environmental-impact.md | 2 +- docs/src/content/docs/es/components/code.mdx | 8 +- docs/src/content/docs/fr/components/code.mdx | 8 +- docs/src/content/docs/guides/authoring-content.mdx | 2 +- docs/src/content/docs/guides/i18n.mdx | 21 +- .../content/docs/guides/overriding-components.mdx | 4 +- docs/src/content/docs/guides/project-structure.mdx | 7 +- docs/src/content/docs/guides/site-search.mdx | 11 +- docs/src/content/docs/ja/components/code.mdx | 8 +- docs/src/content/docs/ko/components/code.mdx | 8 +- docs/src/content/docs/manual-setup.mdx | 16 +- docs/src/content/docs/reference/configuration.mdx | 4 +- docs/src/content/docs/reference/frontmatter.md | 25 +- docs/src/content/docs/reference/overrides.md | 5 +- docs/src/content/docs/ru/components/code.mdx | 8 +- docs/src/content/docs/zh-cn/components/code.mdx | 8 +- docs/src/env.d.ts | 2 - examples/basics/README.md | 3 +- examples/basics/astro.config.mjs | 1 + examples/basics/package.json | 2 +- examples/basics/src/content.config.ts | 7 + examples/basics/src/content/config.ts | 6 - examples/basics/src/env.d.ts | 2 - examples/basics/tsconfig.json | 4 +- examples/markdoc/README.md | 3 +- examples/markdoc/astro.config.mjs | 1 + examples/markdoc/package.json | 4 +- examples/markdoc/src/content.config.ts | 7 + examples/markdoc/src/content/config.ts | 6 - examples/markdoc/src/env.d.ts | 1 - examples/markdoc/tsconfig.json | 4 +- examples/tailwind/README.md | 3 +- examples/tailwind/astro.config.mjs | 1 + examples/tailwind/package.json | 4 +- examples/tailwind/src/content.config.ts | 7 + examples/tailwind/src/content/config.ts | 6 - examples/tailwind/src/env.d.ts | 2 - examples/tailwind/tsconfig.json | 4 +- package.json | 7 +- packages/docsearch/package.json | 2 +- packages/docsearch/schema.ts | 7 +- packages/markdoc/package.json | 8 +- packages/starlight/__e2e__/.gitignore | 1 + .../__e2e__/fixtures/basics/astro.config.mjs | 1 + .../starlight/__e2e__/fixtures/basics/package.json | 2 +- .../__e2e__/fixtures/basics/src/content.config.ts | 7 + .../__e2e__/fixtures/basics/src/content/config.ts | 6 - .../fixtures/custom src-dir/astro.config.mjs | 1 + .../__e2e__/fixtures/custom src-dir/package.json | 2 +- .../fixtures/custom src-dir/www/content.config.ts | 7 + .../fixtures/custom src-dir/www/content/config.ts | 6 - .../__e2e__/fixtures/git/astro.config.mjs | 1 + .../starlight/__e2e__/fixtures/git/package.json | 2 +- .../__e2e__/fixtures/git/src/content.config.ts | 7 + .../__e2e__/fixtures/git/src/content/config.ts | 6 - .../legacy-collection-config-file/astro.config.mjs | 12 + .../legacy-collection-config-file/package.json | 9 + .../src/content/config.ts | 7 + .../src/pages/custom.astro | 7 + .../__e2e__/fixtures/ssr/astro.config.mjs | 1 + .../starlight/__e2e__/fixtures/ssr/package.json | 4 +- .../__e2e__/fixtures/ssr/src/content.config.ts | 7 + .../__e2e__/fixtures/ssr/src/content/config.ts | 6 - .../__e2e__/legacy-collection-config-file.test.ts | 15 + packages/starlight/__tests__/basics/git.test.ts | 10 +- packages/starlight/__tests__/basics/i18n.test.ts | 3 +- .../starlight/__tests__/basics/route-data.test.ts | 1 - .../starlight/__tests__/basics/routing.test.ts | 33 +- .../starlight/__tests__/basics/sorting.test.ts | 5 - .../starlight-page-route-data-extend.test.ts | 2 +- .../basics/starlight-page-route-data.test.ts | 2 +- .../__tests__/build-format-file/navigation.test.ts | 1 - .../starlight/__tests__/edit-url/edit-url.test.ts | 1 - packages/starlight/__tests__/git-utils.ts | 3 + .../i18n-non-root-single-locale/routing.test.ts | 6 +- .../__tests__/i18n-root-locale/routing.test.ts | 15 +- .../i18n-single-root-locale/routing.test.ts | 6 +- .../__tests__/i18n/navigation-order.test.ts | 8 - packages/starlight/__tests__/i18n/routing.test.ts | 11 +- .../starlight/__tests__/plugins/config.test.ts | 8 +- .../__tests__/remark-rehype/asides.test.ts | 8 +- .../remark-rehype/rehype-file-tree.test.ts | 16 +- .../sidebar/navigation-attributes.test.ts | 1 - .../__tests__/sidebar/navigation-badges.test.ts | 1 - .../__tests__/sidebar/navigation-hidden.test.ts | 1 - .../__tests__/sidebar/navigation-order.test.ts | 1 - .../__tests__/sidebar/navigation-unicode.test.ts | 1 - .../starlight/__tests__/sidebar/navigation.test.ts | 2 - packages/starlight/__tests__/test-config.ts | 3 + packages/starlight/__tests__/test-utils.ts | 37 +- packages/starlight/components/EmptyMarkdown.md | 0 packages/starlight/components/Page.astro | 14 +- packages/starlight/components/Search.astro | 8 +- packages/starlight/index.ts | 3 - .../starlight/integrations/shared/pathToLocale.ts | 8 +- .../starlight/integrations/virtual-user-config.ts | 25 +- packages/starlight/loaders.ts | 40 + packages/starlight/package.json | 14 +- packages/starlight/routes/common.astro | 3 +- packages/starlight/routes/static/404.astro | 22 +- packages/starlight/style/shiki.css | 4 +- packages/starlight/utils/collection.ts | 45 + packages/starlight/utils/git.ts | 10 +- packages/starlight/utils/navigation.ts | 4 +- packages/starlight/utils/plugins.ts | 9 - packages/starlight/utils/route-data.ts | 10 +- packages/starlight/utils/routing.ts | 44 +- packages/starlight/utils/slugs.ts | 2 +- packages/starlight/utils/starlight-page.ts | 9 +- packages/starlight/virtual-internal.d.ts | 1 + packages/starlight/vitest.config.ts | 6 +- packages/starlight/vitest.workspace.ts | 2 +- packages/tailwind/package.json | 8 +- packages/tailwind/vitest.config.ts | 5 +- patches/starlight-links-validator@0.13.2.patch | 28 + pnpm-lock.yaml | 2093 ++++++++++---------- tsconfig.json | 3 +- 129 files changed, 1757 insertions(+), 1356 deletions(-) create mode 100644 .changeset/green-suns-drive.md create mode 100644 .changeset/polite-snails-sip.md create mode 100644 docs/src/content.config.ts delete mode 100644 docs/src/content/config.ts delete mode 100644 docs/src/env.d.ts create mode 100644 examples/basics/src/content.config.ts delete mode 100644 examples/basics/src/content/config.ts delete mode 100644 examples/basics/src/env.d.ts create mode 100644 examples/markdoc/src/content.config.ts delete mode 100644 examples/markdoc/src/content/config.ts delete mode 100644 examples/markdoc/src/env.d.ts create mode 100644 examples/tailwind/src/content.config.ts delete mode 100644 examples/tailwind/src/content/config.ts delete mode 100644 examples/tailwind/src/env.d.ts create mode 100644 packages/starlight/__e2e__/fixtures/basics/src/content.config.ts delete mode 100644 packages/starlight/__e2e__/fixtures/basics/src/content/config.ts create mode 100644 packages/starlight/__e2e__/fixtures/custom src-dir/www/content.config.ts delete mode 100644 packages/starlight/__e2e__/fixtures/custom src-dir/www/content/config.ts create mode 100644 packages/starlight/__e2e__/fixtures/git/src/content.config.ts delete mode 100644 packages/starlight/__e2e__/fixtures/git/src/content/config.ts create mode 100644 packages/starlight/__e2e__/fixtures/legacy-collection-config-file/astro.config.mjs create mode 100644 packages/starlight/__e2e__/fixtures/legacy-collection-config-file/package.json create mode 100644 packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/content/config.ts create mode 100644 packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/pages/custom.astro create mode 100644 packages/starlight/__e2e__/fixtures/ssr/src/content.config.ts delete mode 100644 packages/starlight/__e2e__/fixtures/ssr/src/content/config.ts create mode 100644 packages/starlight/__e2e__/legacy-collection-config-file.test.ts delete mode 100644 packages/starlight/components/EmptyMarkdown.md create mode 100644 packages/starlight/loaders.ts create mode 100644 packages/starlight/utils/collection.ts create mode 100644 patches/starlight-links-validator@0.13.2.patch diff --git a/.changeset/green-suns-drive.md b/.changeset/green-suns-drive.md new file mode 100644 index 00000000..29f7dd15 --- /dev/null +++ b/.changeset/green-suns-drive.md @@ -0,0 +1,56 @@ +--- +"@astrojs/starlight": minor +--- + +Adds support for Astro v5, drops support for Astro v4. + +#### Upgrade Astro and dependencies + +⚠️ **BREAKING CHANGE:** Astro v4 is no longer supported. Make sure you [update Astro](https://docs.astro.build/en/guides/upgrade-to/v5/) and any other official integrations at the same time as updating Starlight: + +```sh +npx @astrojs/upgrade +``` + +_Community Starlight plugins and Astro integrations may also need to be manually updated to work with Astro v5. If you encounter any issues, please reach out to the plugin or integration author to see if it is a known issue or if an updated version is being worked on._ + +#### Update your collections + +⚠️ **BREAKING CHANGE:** Starlight's internal [content collections](https://docs.astro.build/en/guides/content-collections/), which organize, validate, and render your content, have been updated to use Astro's new Content Layer API and require configuration changes in your project. + +1. **Move the content config file.** This file no longer lives within the `src/content/config.ts` folder and should now exist at `src/content.config.ts`. + + +1. **Edit the collection definition(s).** To update the `docs` collection, a `loader` is now required: + + ```diff + // src/content.config.ts + import { defineCollection } from "astro:content"; + +import { docsLoader } from "@astrojs/starlight/loaders"; + import { docsSchema } from "@astrojs/starlight/schema"; + + export const collections = { + - docs: defineCollection({ schema: docsSchema() }), + + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), + }; + ``` + + If you are using the [`i18n` collection](https://starlight.astro.build/guides/i18n/#translate-starlights-ui) to provide translations for additional languages you support or override our default labels, you will need to update the collection definition in a similar way and remove the collection `type` which is no longer available: + + ```diff + // src/content.config.ts + import { defineCollection } from "astro:content"; + +import { docsLoader, i18nLoader } from "@astrojs/starlight/loaders"; + import { docsSchema, i18nSchema } from "@astrojs/starlight/schema"; + + export const collections = { + - docs: defineCollection({ schema: docsSchema() }), + + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), + - i18n: defineCollection({ type: 'data', schema: i18nSchema() }), + + i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }), + }; + ``` + +1. **Update other collections.** To update any other collections you may have, follow the [“Updating existing collections”](https://docs.astro.build/en/guides/upgrade-to/v5/#updating-existing-collections) section in the Astro 5 upgrade guide. + +If you are unable to make any changes to your collections at this time, including Starlight's default `docs` and `i18n` collections, you can enable the [`legacy.collections` flag](https://docs.astro.build/en/reference/legacy-flags/) to upgrade to v5 without updating your collections. This legacy flag exists to provide temporary backwards compatibility, and will allow you to keep your collections in their current state until the legacy flag is no longer supported. diff --git a/.changeset/polite-snails-sip.md b/.changeset/polite-snails-sip.md new file mode 100644 index 00000000..588ca325 --- /dev/null +++ b/.changeset/polite-snails-sip.md @@ -0,0 +1,13 @@ +--- +'@astrojs/starlight-docsearch': minor +'@astrojs/starlight-tailwind': major +'@astrojs/starlight-markdoc': minor +--- + +⚠️ **BREAKING CHANGE:** The minimum supported version of Starlight is now 0.30.0 + +Please use the `@astrojs/upgrade` command to upgrade your project: + +```sh +npx @astrojs/upgrade +``` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92f867eb..5dceb59f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,9 @@ jobs: - run: pnpm i - name: Test packages run: pnpm -r test:coverage + - name: Test legacy collections support + working-directory: packages/starlight + run: pnpm test:legacy e2e-test: name: 'Run E2E tests (${{ matrix.os }})' @@ -149,6 +152,4 @@ jobs: - name: Build docs site and check links working-directory: ./docs - run: pnpm build - env: - CHECK_LINKS: true + run: pnpm linkcheck diff --git a/.gitignore b/.gitignore index 035a7ad7..4f7bb9e9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,3 @@ test-results/ # Vercel output .vercel - -# Created by @astrojs/check -/src/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 33cd9c7e..2d98b28e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,11 +121,11 @@ You should then be able to open and see your changes. When adding or translating content in the Starlight docs site, you can check all internal links are valid. All GitHub PRs are checked this way automatically, but testing locally can help if you want to confirm changes are correct before committing them. -To do this, move into the `docs/` directory from the root of the repo and then build the site with the `CHECK_LINKS` environment variable: +To do this, move into the `docs/` directory from the root of the repo and then run `pnpm linkcheck`: ```sh cd docs -CHECK_LINKS=true pnpm build +pnpm linkcheck ``` If there are any broken links, the build will fail and log which pages need to be fixed. @@ -200,7 +200,7 @@ pnpm test:e2e #### Test fixtures -Each subdirectory of `packages/starlight/__e2e__/fixtures` should contain the basic files needed to run Starlight (`package.json`, `astro.config.mjs`, a content collection configuration in `src/content/config.ts` and some content to render in `src/content/docs/`). +Each subdirectory of `packages/starlight/__e2e__/fixtures` should contain the basic files needed to run Starlight (`package.json`, `astro.config.mjs`, a content collection configuration in `src/content.config.ts` and some content to render in `src/content/docs/`). The `testFactory()` helper can be used in a test file to define the fixture which will be built and loaded in a preview server during a set of tests. diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 3234f9c1..dda60459 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; import starlightLinksValidator from 'starlight-links-validator'; diff --git a/docs/package.json b/docs/package.json index 254dfc76..b522db4a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,6 +10,7 @@ "build": "astro build", "preview": "astro preview", "typecheck": "tsc --noEmit", + "linkcheck": "CHECK_LINKS=true pnpm build --force", "astro": "astro", "lunaria:build": "lunaria build", "grammars": "node grammars/generate.mjs" @@ -19,7 +20,7 @@ "@astrojs/starlight": "workspace:*", "@lunariajs/core": "^0.1.1", "@types/culori": "^2.1.1", - "astro": "^4.16.10", + "astro": "^5.0.2", "culori": "^4.0.1", "sharp": "^0.32.5" }, diff --git a/docs/src/content.config.ts b/docs/src/content.config.ts new file mode 100644 index 00000000..e47e819f --- /dev/null +++ b/docs/src/content.config.ts @@ -0,0 +1,18 @@ +import { defineCollection, z } from 'astro:content'; +import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; +import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ + loader: docsLoader(), + schema: docsSchema(), + }), + i18n: defineCollection({ + loader: i18nLoader(), + schema: i18nSchema({ + extend: z.object({ + 'component.preview': z.string().optional(), + }), + }), + }), +}; diff --git a/docs/src/content/config.ts b/docs/src/content/config.ts deleted file mode 100644 index e56c2a20..00000000 --- a/docs/src/content/config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { defineCollection, z } from 'astro:content'; -import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), - i18n: defineCollection({ - type: 'data', - schema: i18nSchema({ - extend: z.object({ - 'component.preview': z.string().optional(), - }), - }), - }), -}; diff --git a/docs/src/content/docs/components/code.mdx b/docs/src/content/docs/components/code.mdx index 3024d130..acd50b94 100644 --- a/docs/src/content/docs/components/code.mdx +++ b/docs/src/content/docs/components/code.mdx @@ -85,14 +85,14 @@ You can then pass this imported string to the `` component to include it o # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/components/using-components.mdx b/docs/src/content/docs/components/using-components.mdx index 0a16057c..76695eb0 100644 --- a/docs/src/content/docs/components/using-components.mdx +++ b/docs/src/content/docs/components/using-components.mdx @@ -9,7 +9,7 @@ Components let you easily reuse a piece of UI or styling consistently. Examples might include a link card or a YouTube embed. Starlight supports the use of components in [MDX](https://mdxjs.com/) and [Markdoc](https://markdoc.dev/) files and provides some common components for you to use. -[Learn more about building components in the Astro Docs](https://docs.astro.build/en/core-concepts/astro-components/). +[Learn more about building components in the Astro Docs](https://docs.astro.build/en/basics/astro-components/). ## Using a component in MDX @@ -30,7 +30,7 @@ import CustomCard from '../../components/CustomCard.astro'; Components can also contain **nested content**. ``` -Because Starlight is powered by Astro, you can add support for components built with any [supported UI framework (React, Preact, Svelte, Vue, Solid, and Alpine)](https://docs.astro.build/en/core-concepts/framework-components/) in your MDX files. +Because Starlight is powered by Astro, you can add support for components built with any [supported UI framework (React, Preact, Svelte, Vue, Solid, and Alpine)](https://docs.astro.build/en/guides/framework-components/) in your MDX files. Learn more about [using components in MDX](https://docs.astro.build/en/guides/integrations-guide/mdx/#using-components-in-mdx) in the Astro docs. ## Using a component in Markdoc diff --git a/docs/src/content/docs/de/components/code.mdx b/docs/src/content/docs/de/components/code.mdx index 3ad641e4..da5bfb57 100644 --- a/docs/src/content/docs/de/components/code.mdx +++ b/docs/src/content/docs/de/components/code.mdx @@ -85,14 +85,14 @@ Du kannst diese importierte Zeichenfolge dann an die Komponente `` überge # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/environmental-impact.md b/docs/src/content/docs/environmental-impact.md index 9e945b69..ae7c8246 100644 --- a/docs/src/content/docs/environmental-impact.md +++ b/docs/src/content/docs/environmental-impact.md @@ -137,6 +137,6 @@ These tests with the [Website Carbon Calculator][wcc] compare similar pages buil [sf]: https://www.sciencefocus.com/science/what-is-the-carbon-footprint-of-the-internet/ [bbc]: https://www.bbc.com/future/article/20200305-why-your-internet-habits-are-not-as-clean-as-you-think [http]: https://httparchive.org/reports/state-of-the-web -[assets]: https://docs.astro.build/en/guides/assets/ +[assets]: https://docs.astro.build/en/guides/images/ [islands]: https://docs.astro.build/en/concepts/islands/ [wcc]: https://www.websitecarbon.com/ diff --git a/docs/src/content/docs/es/components/code.mdx b/docs/src/content/docs/es/components/code.mdx index 5058cd6e..77fbd0df 100644 --- a/docs/src/content/docs/es/components/code.mdx +++ b/docs/src/content/docs/es/components/code.mdx @@ -85,14 +85,14 @@ Puedes pasar este string importado al componente `` para incluirlo en tu p # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/fr/components/code.mdx b/docs/src/content/docs/fr/components/code.mdx index 1e28c620..133c0a7c 100644 --- a/docs/src/content/docs/fr/components/code.mdx +++ b/docs/src/content/docs/fr/components/code.mdx @@ -85,14 +85,14 @@ Vous pouvez ensuite passer cette chaîne importée au composant `` pour l' # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/guides/authoring-content.mdx b/docs/src/content/docs/guides/authoring-content.mdx index 819e4f50..68f37472 100644 --- a/docs/src/content/docs/guides/authoring-content.mdx +++ b/docs/src/content/docs/guides/authoring-content.mdx @@ -45,7 +45,7 @@ You can highlight `inline code` with backticks. ## Images -Images in Starlight use [Astro’s built-in optimized asset support](https://docs.astro.build/en/guides/assets/). +Images in Starlight use [Astro’s built-in optimized asset support](https://docs.astro.build/en/guides/images/). Markdown and MDX support the Markdown syntax for displaying images that includes alt-text for screen readers and assistive technology. diff --git a/docs/src/content/docs/guides/i18n.mdx b/docs/src/content/docs/guides/i18n.mdx index 9844fefd..7591a534 100644 --- a/docs/src/content/docs/guides/i18n.mdx +++ b/docs/src/content/docs/guides/i18n.mdx @@ -188,16 +188,16 @@ You can provide translations for additional languages you support — or overrid -1. Configure the `i18n` data collection in `src/content/config.ts` if it isn’t configured already: +1. Configure the `i18n` data collection in `src/content.config.ts` if it isn’t configured already: - ```diff lang="js" ins=/, (i18nSchema)/ - // src/content/config.ts - import { defineCollection } from 'astro:content'; + ```diff lang="js" ins=/, (i18nLoader|i18nSchema)/ + // src/content.config.ts + import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; export const collections = { - docs: defineCollection({ schema: docsSchema() }), - + i18n: defineCollection({ type: 'data', schema: i18nSchema() }), + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), + + i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }), }; ``` @@ -257,14 +257,15 @@ Add custom keys to your site’s translation dictionaries by setting `extend` in In the following example, a new, optional `custom.label` key is added to the default keys: ```diff lang="js" -// src/content/config.ts +// src/content.config.ts import { defineCollection, z } from 'astro:content'; +import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; export const collections = { - docs: defineCollection({ schema: docsSchema() }), + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), i18n: defineCollection({ - type: 'data', + loader: i18nLoader(), schema: i18nSchema({ + extend: z.object({ + 'custom.label': z.string().optional(), @@ -274,7 +275,7 @@ export const collections = { }; ``` -Learn more about content collection schemas in [“Defining a collection schema”](https://docs.astro.build/en/guides/content-collections/#defining-a-collection-schema) in the Astro docs. +Learn more about content collection schemas in [“Defining a collection schema”](https://docs.astro.build/en/guides/content-collections/#defining-the-collection-schema) in the Astro docs. ## Using UI translations diff --git a/docs/src/content/docs/guides/overriding-components.mdx b/docs/src/content/docs/guides/overriding-components.mdx index a3b86778..edac98b2 100644 --- a/docs/src/content/docs/guides/overriding-components.mdx +++ b/docs/src/content/docs/guides/overriding-components.mdx @@ -84,7 +84,7 @@ import Default from '@astrojs/starlight/components/SocialIcons.astro'; When rendering a built-in component inside a custom component: - Spread `Astro.props` into it. This makes sure that it receives all the data it needs to render. -- Add a [``](https://docs.astro.build/en/core-concepts/astro-components/#slots) inside the default component. This makes sure that if the component is passed any child elements, Astro knows where to render them. +- Add a [``](https://docs.astro.build/en/basics/astro-components/#slots) inside the default component. This makes sure that if the component is passed any child elements, Astro knows where to render them. If you are reusing the [`PageFrame`](/reference/overrides/#pageframe) or [`TwoColumnContent`](/reference/overrides/#twocolumncontent) components which contain [named slots](https://docs.astro.build/en/basics/astro-components/#named-slots), you also need to [transfer](https://docs.astro.build/en/basics/astro-components/#transferring-slots) these slots as well. @@ -155,4 +155,4 @@ const isHomepage = Astro.props.slug === ''; } ``` -Learn more about conditional rendering in [Astro’s Template Syntax guide](https://docs.astro.build/en/core-concepts/astro-syntax/#dynamic-html). +Learn more about conditional rendering in [Astro’s Template Syntax guide](https://docs.astro.build/en/basics/astro-syntax/#dynamic-html). diff --git a/docs/src/content/docs/guides/project-structure.mdx b/docs/src/content/docs/guides/project-structure.mdx index f32bc16b..02dc4789 100644 --- a/docs/src/content/docs/guides/project-structure.mdx +++ b/docs/src/content/docs/guides/project-structure.mdx @@ -5,12 +5,12 @@ description: Learn how to organize files in your Starlight project. This guide will show you how a Starlight project is organized and what the different files in your project do. -Starlight projects generally follow the same file and directory structure as other Astro projects. See [Astro’s project structure documentation](https://docs.astro.build/en/core-concepts/project-structure/) for more detail. +Starlight projects generally follow the same file and directory structure as other Astro projects. See [Astro’s project structure documentation](https://docs.astro.build/en/basics/project-structure/) for more detail. ## Files and directories - `astro.config.mjs` — The Astro configuration file; includes the Starlight integration and configuration. -- `src/content/config.ts` — Content collections configuration file; adds Starlight’s frontmatter schemas to your project. +- `src/content.config.ts` — Content collections configuration file; adds Starlight’s frontmatter schemas to your project. - `src/content/docs/` — Content files. Starlight turns each `.md`, `.mdx` or `.mdoc` file in this directory into a page on your site. - `src/content/i18n/` (optional) — Translation data to support [internationalization](/guides/i18n/). - `src/` — Other source code and files (components, styles, images, etc.) for your project. @@ -39,8 +39,7 @@ import { FileTree } from '@astrojs/starlight/components'; - 01-getting-started.md - 02-advanced.md - index.mdx - - config.ts - - env.d.ts + - content.config.ts - astro.config.mjs - package.json - tsconfig.json diff --git a/docs/src/content/docs/guides/site-search.mdx b/docs/src/content/docs/guides/site-search.mdx index 083c245e..fe7ad701 100644 --- a/docs/src/content/docs/guides/site-search.mdx +++ b/docs/src/content/docs/guides/site-search.mdx @@ -124,18 +124,19 @@ Add translations of the modal UI for your language using Starlight’s built-in -1. Extend Starlight’s `i18n` content collection definition with the DocSearch schema in `src/content/config.ts`: +1. Extend Starlight’s `i18n` content collection definition with the DocSearch schema in `src/content.config.ts`: - ```js ins={4} ins=/{ extend: .+ }/ - // src/content/config.ts + ```js ins={5} ins=/{ extend: .+ }/ + // src/content.config.ts import { defineCollection } from 'astro:content'; + import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; import { docSearchI18nSchema } from '@astrojs/starlight-docsearch/schema'; export const collections = { - docs: defineCollection({ schema: docsSchema() }), + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), i18n: defineCollection({ - type: 'data', + loader: i18nLoader(), schema: i18nSchema({ extend: docSearchI18nSchema() }), }), }; diff --git a/docs/src/content/docs/ja/components/code.mdx b/docs/src/content/docs/ja/components/code.mdx index a9dc4674..245e03e1 100644 --- a/docs/src/content/docs/ja/components/code.mdx +++ b/docs/src/content/docs/ja/components/code.mdx @@ -85,14 +85,14 @@ MDXファイルやAstroコンポーネント内で、[Viteの`?raw`インポー # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/ko/components/code.mdx b/docs/src/content/docs/ko/components/code.mdx index 7c59999c..8e8ea630 100644 --- a/docs/src/content/docs/ko/components/code.mdx +++ b/docs/src/content/docs/ko/components/code.mdx @@ -85,14 +85,14 @@ MDX 파일 및 Astro 컴포넌트에서 [Vite의 `?raw` 가져오기 접미사]( # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/manual-setup.mdx b/docs/src/content/docs/manual-setup.mdx index 07465d9f..7848438a 100644 --- a/docs/src/content/docs/manual-setup.mdx +++ b/docs/src/content/docs/manual-setup.mdx @@ -62,20 +62,24 @@ Find all available options in the [Starlight configuration reference](/reference ### Configure content collections -Starlight is built on top of Astro’s [content collections](https://docs.astro.build/en/guides/content-collections/), which are configured in the `src/content/config.ts` file. +Starlight is built on top of Astro’s [content collections](https://docs.astro.build/en/guides/content-collections/), which are configured in the `src/content.config.ts` file. -Create or update the content config file, adding a `docs` collection that uses Starlight’s `docsSchema`: +Create or update the content config file, adding a `docs` collection that uses Starlight’s `docsLoader` and `docsSchema`: -```js ins={3,6} -// src/content/config.ts +```js ins={3-4,7} +// src/content.config.ts import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; import { docsSchema } from '@astrojs/starlight/schema'; export const collections = { - docs: defineCollection({ schema: docsSchema() }), + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), }; ``` +Starlight also supports the [`legacy.collections` flag](https://docs.astro.build/en/reference/legacy-flags/) where collections are handled using the legacy content collections implementation. +This is useful if you have an existing Astro project and are unable to make any changes to collections at this time to use a loader. + ### Add content Starlight is now configured and it’s time to add some content! @@ -125,6 +129,6 @@ In the future, we plan to support this use case better to avoid the need for the ### Use Starlight with SSR -To enable SSR, follow the [“On-demand Rendering Adapters”](https://docs.astro.build/en/guides/server-side-rendering/) guide in Astro’s docs to add a server adapter to your Starlight project. +To enable SSR, follow the [“On-demand Rendering Adapters”](https://docs.astro.build/en/guides/on-demand-rendering/) guide in Astro’s docs to add a server adapter to your Starlight project. Documentation pages generated by Starlight are pre-rendered by default regardless of your project's output mode. To opt out of pre-rendering your Starlight pages, set the [`prerender` config option](/reference/configuration/#prerender) to `false`. diff --git a/docs/src/content/docs/reference/configuration.mdx b/docs/src/content/docs/reference/configuration.mdx index c878141b..fc26406c 100644 --- a/docs/src/content/docs/reference/configuration.mdx +++ b/docs/src/content/docs/reference/configuration.mdx @@ -462,7 +462,7 @@ Pagefind cannot be enabled when the [`prerender`](#prerender) option is set to ` **type:** `boolean` **default:** `true` -Define whether Starlight pages should be pre-rendered to static HTML or on-demand rendered by an [SSR adapter](https://docs.astro.build/en/guides/server-side-rendering/). +Define whether Starlight pages should be pre-rendered to static HTML or on-demand rendered by an [SSR adapter](https://docs.astro.build/en/guides/on-demand-rendering/). Starlight pages are pre-rendered by default. If you are using an SSR adapter and want to render Starlight pages on demand, set `prerender: false`. @@ -568,7 +568,7 @@ For example, this page is titled “Configuration Reference” and this site is **type:** `boolean` **default:** `false` -Disables injecting Starlight's default [404 page](https://docs.astro.build/en/core-concepts/astro-pages/#custom-404-error-page). To use a custom `src/pages/404.astro` route in your project, set this option to `true`. +Disables injecting Starlight's default [404 page](https://docs.astro.build/en/basics/astro-pages/#custom-404-error-page). To use a custom `src/pages/404.astro` route in your project, set this option to `true`. ### `components` diff --git a/docs/src/content/docs/reference/frontmatter.md b/docs/src/content/docs/reference/frontmatter.md index 75b56444..5c0f0b44 100644 --- a/docs/src/content/docs/reference/frontmatter.md +++ b/docs/src/content/docs/reference/frontmatter.md @@ -33,7 +33,7 @@ The page description is used for page metadata and will be picked up by search e **type**: `string` -Override the slug of the page. See [“Defining custom slugs”](https://docs.astro.build/en/guides/content-collections/#defining-custom-slugs) in the Astro docs for more details. +Override the slug of the page. See [“Defining custom IDs”](https://docs.astro.build/en/guides/content-collections/#defining-custom-ids) in the Astro docs for more details. ### `editUrl` @@ -397,19 +397,20 @@ sidebar: ## Customize frontmatter schema -The frontmatter schema for Starlight’s `docs` content collection is configured in `src/content/config.ts` using the `docsSchema()` helper: +The frontmatter schema for Starlight’s `docs` content collection is configured in `src/content.config.ts` using the `docsSchema()` helper: -```ts {3,6} -// src/content/config.ts +```ts {4,7} +// src/content.config.ts import { defineCollection } from 'astro:content'; +import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; import { docsSchema } from '@astrojs/starlight/schema'; export const collections = { - docs: defineCollection({ schema: docsSchema() }), + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), }; ``` -Learn more about content collection schemas in [“Defining a collection schema”](https://docs.astro.build/en/guides/content-collections/#defining-a-collection-schema) in the Astro docs. +Learn more about content collection schemas in [“Defining a collection schema”](https://docs.astro.build/en/guides/content-collections/#defining-the-collection-schema) in the Astro docs. `docsSchema()` takes the following options: @@ -423,13 +424,15 @@ The value should be a [Zod schema](https://docs.astro.build/en/guides/content-co In the following example, we provide a stricter type for `description` to make it required and add a new optional `category` field: -```ts {8-13} -// src/content/config.ts +```ts {10-15} +// src/content.config.ts import { defineCollection, z } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; import { docsSchema } from '@astrojs/starlight/schema'; export const collections = { docs: defineCollection({ + loader: docsLoader(), schema: docsSchema({ extend: z.object({ // Make a built-in field required instead of optional. @@ -444,13 +447,15 @@ export const collections = { To take advantage of the [Astro `image()` helper](https://docs.astro.build/en/guides/images/#images-in-content-collections), use a function that returns your schema extension: -```ts {8-13} -// src/content/config.ts +```ts {10-15} +// src/content.config.ts import { defineCollection, z } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; import { docsSchema } from '@astrojs/starlight/schema'; export const collections = { docs: defineCollection({ + loader: docsLoader(), schema: docsSchema({ extend: ({ image }) => { return z.object({ diff --git a/docs/src/content/docs/reference/overrides.md b/docs/src/content/docs/reference/overrides.md index 5f47428d..f5773f86 100644 --- a/docs/src/content/docs/reference/overrides.md +++ b/docs/src/content/docs/reference/overrides.md @@ -69,11 +69,14 @@ For multilingual sites this will include the current locale, e.g. `/en/` or `/zh The slug for this page generated from the content filename. +This property is deprecated and will be removed in a future version of Starlight. +Migrate to the new Content Layer API by using [Starlight’s `docsLoader`](/manual-setup/#configure-content-collections) and use the [`id`](#id) property instead. + #### `id` **Type:** `string` -The unique ID for this page based on the content filename. +The slug for this page or the unique ID for this page based on the content filename if using the [`legacy.collections`](https://docs.astro.build/en/reference/legacy-flags/#collections) flag. #### `isFallback` diff --git a/docs/src/content/docs/ru/components/code.mdx b/docs/src/content/docs/ru/components/code.mdx index aa74ea97..6ddf4a05 100644 --- a/docs/src/content/docs/ru/components/code.mdx +++ b/docs/src/content/docs/ru/components/code.mdx @@ -85,14 +85,14 @@ export const highlights = ['файл', 'CMS']; # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/content/docs/zh-cn/components/code.mdx b/docs/src/content/docs/zh-cn/components/code.mdx index 7489f253..5c56e4e9 100644 --- a/docs/src/content/docs/zh-cn/components/code.mdx +++ b/docs/src/content/docs/zh-cn/components/code.mdx @@ -85,14 +85,14 @@ export const highlights = ['文件', 'CMS']; # src/content/docs/example.mdx import { Code } from '@astrojs/starlight/components'; -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '/tsconfig.json?raw'; - + ``` -import importedCode from '/src/env.d.ts?raw'; +import importedCode from '../../../../../../examples/basics/tsconfig.json?raw'; - + diff --git a/docs/src/env.d.ts b/docs/src/env.d.ts deleted file mode 100644 index acef35f1..00000000 --- a/docs/src/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/examples/basics/README.md b/examples/basics/README.md index e09bf55f..f9f6d31c 100644 --- a/examples/basics/README.md +++ b/examples/basics/README.md @@ -24,8 +24,7 @@ Inside of your Astro + Starlight project, you'll see the following folders and f │ ├── assets/ │ ├── content/ │ │ ├── docs/ -│ │ └── config.ts -│ └── env.d.ts +│ └── content.config.ts ├── astro.config.mjs ├── package.json └── tsconfig.json diff --git a/examples/basics/astro.config.mjs b/examples/basics/astro.config.mjs index 78078c32..1b393646 100644 --- a/examples/basics/astro.config.mjs +++ b/examples/basics/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; diff --git a/examples/basics/package.json b/examples/basics/package.json index 3d9ae8fe..d3c6bea0 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/starlight": "^0.29.3", - "astro": "^4.16.10", + "astro": "^5.0.2", "sharp": "^0.32.5" } } diff --git a/examples/basics/src/content.config.ts b/examples/basics/src/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/examples/basics/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/examples/basics/src/content/config.ts b/examples/basics/src/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/examples/basics/src/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/examples/basics/src/env.d.ts b/examples/basics/src/env.d.ts deleted file mode 100644 index acef35f1..00000000 --- a/examples/basics/src/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/examples/basics/tsconfig.json b/examples/basics/tsconfig.json index bcbf8b50..8bf91d3b 100644 --- a/examples/basics/tsconfig.json +++ b/examples/basics/tsconfig.json @@ -1,3 +1,5 @@ { - "extends": "astro/tsconfigs/strict" + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] } diff --git a/examples/markdoc/README.md b/examples/markdoc/README.md index 584fd88e..9dc25ffe 100644 --- a/examples/markdoc/README.md +++ b/examples/markdoc/README.md @@ -24,8 +24,7 @@ Inside of your Astro + Starlight project, you'll see the following folders and f │ ├── assets/ │ ├── content/ │ │ ├── docs/ -│ │ └── config.ts -│ └── env.d.ts +│ └── content.config.ts ├── astro.config.mjs ├── markdoc.config.mjs ├── package.json diff --git a/examples/markdoc/astro.config.mjs b/examples/markdoc/astro.config.mjs index 03155ce5..7f814cbb 100644 --- a/examples/markdoc/astro.config.mjs +++ b/examples/markdoc/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; import markdoc from '@astrojs/markdoc'; diff --git a/examples/markdoc/package.json b/examples/markdoc/package.json index a3700c89..550b5669 100644 --- a/examples/markdoc/package.json +++ b/examples/markdoc/package.json @@ -11,10 +11,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/markdoc": "^0.11.4", + "@astrojs/markdoc": "^0.12.1", "@astrojs/starlight": "^0.29.3", "@astrojs/starlight-markdoc": "^0.1.0", - "astro": "^4.16.10", + "astro": "^5.0.2", "sharp": "^0.32.5" } } diff --git a/examples/markdoc/src/content.config.ts b/examples/markdoc/src/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/examples/markdoc/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/examples/markdoc/src/content/config.ts b/examples/markdoc/src/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/examples/markdoc/src/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/examples/markdoc/src/env.d.ts b/examples/markdoc/src/env.d.ts deleted file mode 100644 index e16c13c6..00000000 --- a/examples/markdoc/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/examples/markdoc/tsconfig.json b/examples/markdoc/tsconfig.json index bcbf8b50..8bf91d3b 100644 --- a/examples/markdoc/tsconfig.json +++ b/examples/markdoc/tsconfig.json @@ -1,3 +1,5 @@ { - "extends": "astro/tsconfigs/strict" + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] } diff --git a/examples/tailwind/README.md b/examples/tailwind/README.md index 610da00f..bc54e6da 100644 --- a/examples/tailwind/README.md +++ b/examples/tailwind/README.md @@ -24,8 +24,7 @@ Inside of your Astro + Starlight project, you'll see the following folders and f │ ├── assets/ │ ├── content/ │ │ ├── docs/ -│ │ └── config.ts -│ └── env.d.ts +│ └── content.config.ts ├── astro.config.mjs ├── package.json ├── tailwind.config.mjs diff --git a/examples/tailwind/astro.config.mjs b/examples/tailwind/astro.config.mjs index 2a81ef78..a3a3ba5e 100644 --- a/examples/tailwind/astro.config.mjs +++ b/examples/tailwind/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; import tailwind from '@astrojs/tailwind'; diff --git a/examples/tailwind/package.json b/examples/tailwind/package.json index 3ae0d464..9918cc4f 100644 --- a/examples/tailwind/package.json +++ b/examples/tailwind/package.json @@ -13,8 +13,8 @@ "dependencies": { "@astrojs/starlight": "^0.29.3", "@astrojs/starlight-tailwind": "^2.0.3", - "@astrojs/tailwind": "^5.1.0", - "astro": "^4.16.10", + "@astrojs/tailwind": "^5.1.3", + "astro": "^5.0.2", "sharp": "^0.32.5", "tailwindcss": "^3.4.4" } diff --git a/examples/tailwind/src/content.config.ts b/examples/tailwind/src/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/examples/tailwind/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/examples/tailwind/src/content/config.ts b/examples/tailwind/src/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/examples/tailwind/src/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/examples/tailwind/src/env.d.ts b/examples/tailwind/src/env.d.ts deleted file mode 100644 index acef35f1..00000000 --- a/examples/tailwind/src/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/examples/tailwind/tsconfig.json b/examples/tailwind/tsconfig.json index bcbf8b50..8bf91d3b 100644 --- a/examples/tailwind/tsconfig.json +++ b/examples/tailwind/tsconfig.json @@ -1,3 +1,5 @@ { - "extends": "astro/tsconfigs/strict" + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] } diff --git a/package.json b/package.json index 7ccae44e..f63a9fd3 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,11 @@ }, "license": "MIT", "devDependencies": { - "@astrojs/check": "^0.7.0", + "@astrojs/check": "^0.9.4", "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.9", "@size-limit/file": "^11.1.6", - "astro": "^4.16.10", + "astro": "^5.0.2", "prettier": "^3.3.3", "prettier-plugin-astro": "^0.14.1", "size-limit": "^11.1.6", @@ -50,6 +50,9 @@ "playwright", "search-insights" ] + }, + "patchedDependencies": { + "starlight-links-validator@0.13.2": "patches/starlight-links-validator@0.13.2.patch" } } } diff --git a/packages/docsearch/package.json b/packages/docsearch/package.json index e80bc275..ca909d19 100644 --- a/packages/docsearch/package.json +++ b/packages/docsearch/package.json @@ -25,7 +25,7 @@ "./schema": "./schema.ts" }, "peerDependencies": { - "@astrojs/starlight": ">=0.28.0" + "@astrojs/starlight": ">=0.30.0" }, "dependencies": { "@docsearch/css": "^3.6.0", diff --git a/packages/docsearch/schema.ts b/packages/docsearch/schema.ts index 1ee920ee..b227946c 100644 --- a/packages/docsearch/schema.ts +++ b/packages/docsearch/schema.ts @@ -3,17 +3,18 @@ import { z } from 'astro/zod'; /** * Schema for the Algolia DocSearch modal’s strings. * - * Add this to your `src/content/config.ts`: + * Add this to your `src/content.config.ts`: * * ```js * import { defineCollection } from 'astro:content'; + * import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; * import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; * import { docSearchI18nSchema } from '@astrojs/starlight-docsearch/schema'; * * export const collections = { - * docs: defineCollection({ schema: docsSchema() }), + * docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), * i18n: defineCollection({ - * type: 'data', + * loader: i18nLoader(), * schema: i18nSchema({ extend: docSearchI18nSchema() }), * }), * }; diff --git a/packages/markdoc/package.json b/packages/markdoc/package.json index 0218a059..4a8f55a9 100644 --- a/packages/markdoc/package.json +++ b/packages/markdoc/package.json @@ -17,13 +17,13 @@ "./components": "./components.ts" }, "devDependencies": { - "@astrojs/markdoc": "^0.11.5", + "@astrojs/markdoc": "^0.12.1", "@astrojs/starlight": "workspace:*", - "vitest": "^1.6.0" + "vitest": "2.1.6" }, "peerDependencies": { - "@astrojs/markdoc": "^0.11.4", - "@astrojs/starlight": ">=0.23.0" + "@astrojs/markdoc": "^0.12.1", + "@astrojs/starlight": ">=0.30.0" }, "publishConfig": { "provenance": true diff --git a/packages/starlight/__e2e__/.gitignore b/packages/starlight/__e2e__/.gitignore index bde2931f..eed07661 100644 --- a/packages/starlight/__e2e__/.gitignore +++ b/packages/starlight/__e2e__/.gitignore @@ -1,3 +1,4 @@ # generated types .astro/ dist/ +build/ diff --git a/packages/starlight/__e2e__/fixtures/basics/astro.config.mjs b/packages/starlight/__e2e__/fixtures/basics/astro.config.mjs index 1279050d..ca9b813d 100644 --- a/packages/starlight/__e2e__/fixtures/basics/astro.config.mjs +++ b/packages/starlight/__e2e__/fixtures/basics/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import starlight from '@astrojs/starlight'; import { defineConfig } from 'astro/config'; diff --git a/packages/starlight/__e2e__/fixtures/basics/package.json b/packages/starlight/__e2e__/fixtures/basics/package.json index 09222111..cecfbf61 100644 --- a/packages/starlight/__e2e__/fixtures/basics/package.json +++ b/packages/starlight/__e2e__/fixtures/basics/package.json @@ -4,6 +4,6 @@ "private": true, "dependencies": { "@astrojs/starlight": "workspace:*", - "astro": "^4.16.10" + "astro": "^5.0.2" } } diff --git a/packages/starlight/__e2e__/fixtures/basics/src/content.config.ts b/packages/starlight/__e2e__/fixtures/basics/src/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/basics/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__e2e__/fixtures/basics/src/content/config.ts b/packages/starlight/__e2e__/fixtures/basics/src/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/packages/starlight/__e2e__/fixtures/basics/src/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/packages/starlight/__e2e__/fixtures/custom src-dir/astro.config.mjs b/packages/starlight/__e2e__/fixtures/custom src-dir/astro.config.mjs index 9e759d9e..68689f1b 100644 --- a/packages/starlight/__e2e__/fixtures/custom src-dir/astro.config.mjs +++ b/packages/starlight/__e2e__/fixtures/custom src-dir/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import starlight from '@astrojs/starlight'; import { defineConfig } from 'astro/config'; diff --git a/packages/starlight/__e2e__/fixtures/custom src-dir/package.json b/packages/starlight/__e2e__/fixtures/custom src-dir/package.json index c49d67f5..dd1a7765 100644 --- a/packages/starlight/__e2e__/fixtures/custom src-dir/package.json +++ b/packages/starlight/__e2e__/fixtures/custom src-dir/package.json @@ -4,6 +4,6 @@ "private": true, "dependencies": { "@astrojs/starlight": "workspace:*", - "astro": "^4.16.10" + "astro": "^5.0.2" } } diff --git a/packages/starlight/__e2e__/fixtures/custom src-dir/www/content.config.ts b/packages/starlight/__e2e__/fixtures/custom src-dir/www/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/custom src-dir/www/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__e2e__/fixtures/custom src-dir/www/content/config.ts b/packages/starlight/__e2e__/fixtures/custom src-dir/www/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/packages/starlight/__e2e__/fixtures/custom src-dir/www/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/packages/starlight/__e2e__/fixtures/git/astro.config.mjs b/packages/starlight/__e2e__/fixtures/git/astro.config.mjs index 0631c4f0..c3433485 100644 --- a/packages/starlight/__e2e__/fixtures/git/astro.config.mjs +++ b/packages/starlight/__e2e__/fixtures/git/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import starlight from '@astrojs/starlight'; import { defineConfig } from 'astro/config'; diff --git a/packages/starlight/__e2e__/fixtures/git/package.json b/packages/starlight/__e2e__/fixtures/git/package.json index ed68987e..a8b1645f 100644 --- a/packages/starlight/__e2e__/fixtures/git/package.json +++ b/packages/starlight/__e2e__/fixtures/git/package.json @@ -4,6 +4,6 @@ "private": true, "dependencies": { "@astrojs/starlight": "workspace:*", - "astro": "^4.16.10" + "astro": "^5.0.2" } } diff --git a/packages/starlight/__e2e__/fixtures/git/src/content.config.ts b/packages/starlight/__e2e__/fixtures/git/src/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/git/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__e2e__/fixtures/git/src/content/config.ts b/packages/starlight/__e2e__/fixtures/git/src/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/packages/starlight/__e2e__/fixtures/git/src/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/astro.config.mjs b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/astro.config.mjs new file mode 100644 index 00000000..02d3655e --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/astro.config.mjs @@ -0,0 +1,12 @@ +// @ts-check +import starlight from '@astrojs/starlight'; +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + integrations: [ + starlight({ + title: 'Legacy collection config file', + pagefind: false, + }), + ], +}); diff --git a/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/package.json b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/package.json new file mode 100644 index 00000000..5274567a --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/package.json @@ -0,0 +1,9 @@ +{ + "name": "@e2e/legacy-collection-config-file", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/starlight": "workspace:*", + "astro": "^5.0.2" + } +} diff --git a/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/content/config.ts b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/content/config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/content/config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/pages/custom.astro b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/pages/custom.astro new file mode 100644 index 00000000..680eaaef --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/legacy-collection-config-file/src/pages/custom.astro @@ -0,0 +1,7 @@ +--- +import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; +--- + + +

Hello

+
diff --git a/packages/starlight/__e2e__/fixtures/ssr/astro.config.mjs b/packages/starlight/__e2e__/fixtures/ssr/astro.config.mjs index 3faa2cd8..1b30d024 100644 --- a/packages/starlight/__e2e__/fixtures/ssr/astro.config.mjs +++ b/packages/starlight/__e2e__/fixtures/ssr/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; import node from '@astrojs/node'; diff --git a/packages/starlight/__e2e__/fixtures/ssr/package.json b/packages/starlight/__e2e__/fixtures/ssr/package.json index 986a991f..3890d6b9 100644 --- a/packages/starlight/__e2e__/fixtures/ssr/package.json +++ b/packages/starlight/__e2e__/fixtures/ssr/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@astrojs/node": "^8.3.2", + "@astrojs/node": "^9.0.0", "@astrojs/starlight": "workspace:*", - "astro": "^4.16.10" + "astro": "^5.0.2" } } diff --git a/packages/starlight/__e2e__/fixtures/ssr/src/content.config.ts b/packages/starlight/__e2e__/fixtures/ssr/src/content.config.ts new file mode 100644 index 00000000..d9ee8c9d --- /dev/null +++ b/packages/starlight/__e2e__/fixtures/ssr/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/packages/starlight/__e2e__/fixtures/ssr/src/content/config.ts b/packages/starlight/__e2e__/fixtures/ssr/src/content/config.ts deleted file mode 100644 index 45f60b01..00000000 --- a/packages/starlight/__e2e__/fixtures/ssr/src/content/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ schema: docsSchema() }), -}; diff --git a/packages/starlight/__e2e__/legacy-collection-config-file.test.ts b/packages/starlight/__e2e__/legacy-collection-config-file.test.ts new file mode 100644 index 00000000..71b67f41 --- /dev/null +++ b/packages/starlight/__e2e__/legacy-collection-config-file.test.ts @@ -0,0 +1,15 @@ +import { expect, testFactory } from './test-utils'; + +// This fixture uses a legacy collection config file (`src/content/config.ts`) instead of the new +// one (`src/content.config.ts`). +const test = testFactory('./fixtures/legacy-collection-config-file/'); + +test('builds a custom page using the `` component and a legacy collection config file', async ({ + page, + getProdServer, +}) => { + const starlight = await getProdServer(); + await starlight.goto('/custom'); + + await expect(page.getByText('Hello')).toBeVisible(); +}); diff --git a/packages/starlight/__tests__/basics/git.test.ts b/packages/starlight/__tests__/basics/git.test.ts index 28f6a97b..439eea33 100644 --- a/packages/starlight/__tests__/basics/git.test.ts +++ b/packages/starlight/__tests__/basics/git.test.ts @@ -87,7 +87,7 @@ describe('getNewestCommitDate', () => { }); describe('getAllNewestCommitDate', () => { - const { commitAllChanges, getFilePath, writeFile } = makeTestRepo(); + const { commitAllChanges, getRepoPath, getFilePath, writeFile } = makeTestRepo(); test('returns the newest commit date', () => { writeFile('added.md', 'content'); @@ -108,7 +108,7 @@ describe('getAllNewestCommitDate', () => { writeFile('updated-same-day.md', 'content 1'); commitAllChanges('update updated.md', '2023-06-25T14:22:35Z'); - const latestDates = new Map(getAllNewestCommitDate(getFilePath(''))); + const latestDates = new Map(getAllNewestCommitDate(getRepoPath(), getFilePath(''))); const expectedDates = new Map([ ['added.md', '2022-09-18'], @@ -130,7 +130,7 @@ describe('getAllNewestCommitDate', () => { }); test('returns the newest commit date from inlined API', () => { - const api = makeInlineGitAPI(getAllNewestCommitDate(getFilePath(''))); + const api = makeInlineGitAPI(getAllNewestCommitDate(getRepoPath(), getFilePath(''))); const expectedDates = new Map([ ['added.md', '2022-09-18'], @@ -146,7 +146,9 @@ describe('getAllNewestCommitDate', () => { }); test('returns an empty list when the git history for the directory cannot be retrieved', () => { - expect(getAllNewestCommitDate(getFilePath('../not-a-starlight-test-repo'))).toStrictEqual([]); + expect( + getAllNewestCommitDate(getRepoPath(), getFilePath('../not-a-starlight-test-repo')) + ).toStrictEqual([]); }); }); diff --git a/packages/starlight/__tests__/basics/i18n.test.ts b/packages/starlight/__tests__/basics/i18n.test.ts index 7c0af56a..916fe8d9 100644 --- a/packages/starlight/__tests__/basics/i18n.test.ts +++ b/packages/starlight/__tests__/basics/i18n.test.ts @@ -1,8 +1,7 @@ import { assert, describe, expect, test, vi } from 'vitest'; import config from 'virtual:starlight/user-config'; import { processI18nConfig, pickLang } from '../../utils/i18n'; -import type { AstroConfig } from 'astro'; -import type { AstroUserConfig } from 'astro/config'; +import type { AstroConfig, AstroUserConfig } from 'astro'; describe('pickLang', () => { const dictionary = { en: 'Hello', fr: 'Bonjour' }; diff --git a/packages/starlight/__tests__/basics/route-data.test.ts b/packages/starlight/__tests__/basics/route-data.test.ts index f3293259..39d19fab 100644 --- a/packages/starlight/__tests__/basics/route-data.test.ts +++ b/packages/starlight/__tests__/basics/route-data.test.ts @@ -8,7 +8,6 @@ vi.mock('astro:content', async () => docs: [ ['index.mdx', { title: 'Home Page' }], ['getting-started.mdx', { title: 'Splash', template: 'splash' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['showcase.mdx', { title: 'ToC Disabled', tableOfContents: false }], ['environmental-impact.md', { title: 'Explicit update date', lastUpdated: new Date() }], ], diff --git a/packages/starlight/__tests__/basics/routing.test.ts b/packages/starlight/__tests__/basics/routing.test.ts index c94e4895..60f98256 100644 --- a/packages/starlight/__tests__/basics/routing.test.ts +++ b/packages/starlight/__tests__/basics/routing.test.ts @@ -1,8 +1,9 @@ import { type GetStaticPathsResult } from 'astro'; import { getCollection } from 'astro:content'; import config from 'virtual:starlight/user-config'; +import project from 'virtual:starlight/project-context'; import { expect, test, vi } from 'vitest'; -import { routes, paths, getRouteBySlugParam } from '../../utils/routing'; +import { routes, paths, getRouteBySlugParam, type Route } from '../../utils/routing'; import { slugToParam } from '../../utils/slugs'; vi.mock('astro:content', async () => @@ -20,19 +21,33 @@ test('test suite is using correct env', () => { }); test('route slugs are normalized', () => { - const indexRoute = routes.find((route) => route.id.startsWith('index.md')); + const indexRoute = routes.find( + (route) => route.id === (project.legacyCollections ? 'index.mdx' : '') + ); expect(indexRoute?.slug).toBe(''); }); test('routes contain copy of original doc as entry', async () => { const docs = await getCollection('docs'); for (const route of routes) { - const doc = docs.find((doc) => doc.id === route.id); + const doc = docs.find((doc) => doc.id === route.id || (doc.id === 'index' && route.id === '')); if (!doc) throw new Error('Expected to find doc for route ' + route.id); // Compare without slug as slugs can be normalized. const { slug: _, ...entry } = route.entry; - const { slug: __, ...input } = doc; - expect(entry).toEqual(input); + if (project.legacyCollections) { + // When using legacy collections, the `filePath` property is added to the route entry. + expect(entry.filePath).toBeDefined(); + const { filePath: _, ...legacyEntry } = entry; + // @ts-expect-error - When using legacy collections, the `slug` property is available but can + // be normalized. + const { slug: __, ...legacyInput } = doc; + expect(legacyEntry).toEqual(legacyInput); + } else { + // Compare without ids as ids can be normalized when using loaders. + const { id: _, ...loaderEntry } = entry; + const { id: __, ...loaderInput } = doc; + expect(loaderEntry).toEqual(loaderInput); + } } }); @@ -73,7 +88,11 @@ test('routes can be retrieved from their path parameters', () => { }); test('routes includes drafts except in production', async () => { - expect(routes.find((route) => route.id === 'guides/authoring-content.mdx')).toBeTruthy(); + const routeMatcher = (route: Route) => + route.id === + (project.legacyCollections ? 'guides/authoring-content.mdx' : 'guides/authoring-content'); + + expect(routes.find(routeMatcher)).toBeTruthy(); // Reset the modules registry so that re-importing `utils/routing.ts` re-evaluates the module and // re-computes the routes. Re-importing the module is necessary because top-level imports cannot @@ -84,7 +103,7 @@ test('routes includes drafts except in production', async () => { // Re-import the module to re-evaluate it. const { routes: prodRoutes } = await import('../../utils/routing'); - expect(prodRoutes.find((route) => route.id === 'guides/authoring-content.mdx')).toBeFalsy(); + expect(prodRoutes.find(routeMatcher)).toBeFalsy(); vi.unstubAllEnvs(); vi.resetModules(); diff --git a/packages/starlight/__tests__/basics/sorting.test.ts b/packages/starlight/__tests__/basics/sorting.test.ts index 1129928b..978ebd24 100644 --- a/packages/starlight/__tests__/basics/sorting.test.ts +++ b/packages/starlight/__tests__/basics/sorting.test.ts @@ -5,15 +5,10 @@ vi.mock('astro:content', async () => (await import('../test-utils')).mockedAstroContent({ docs: [ ['index.mdx', { title: 'first' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['guides/example.md', { title: 'second' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['reference/example.md', { title: 'third' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['reference/rod/foo.md', { title: 'fourth' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['reference/rod/zip.md', { title: 'fifth' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['reference/zoo.md', { title: 'sixth' }], ], }) diff --git a/packages/starlight/__tests__/basics/starlight-page-route-data-extend.test.ts b/packages/starlight/__tests__/basics/starlight-page-route-data-extend.test.ts index 23438c7a..24616330 100644 --- a/packages/starlight/__tests__/basics/starlight-page-route-data-extend.test.ts +++ b/packages/starlight/__tests__/basics/starlight-page-route-data-extend.test.ts @@ -23,7 +23,7 @@ const starlightPageProps: StarlightPageProps = { test('throws a validation error if a built-in field required by the user schema is not passed down', async () => { // The first line should be a user-friendly error message describing the exact issue and the second line should be // the missing description field. - expect(() => + await expect(() => generateStarlightPageRouteData({ props: starlightPageProps, url: new URL('https://example.com/test-slug'), diff --git a/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts b/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts index 91310f84..7f55bd22 100644 --- a/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts +++ b/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts @@ -250,7 +250,7 @@ test('uses provided sidebar if any', async () => { }); test('throws error if sidebar is malformated', async () => { - expect(() => + await expect(() => generateStarlightPageRouteData({ props: { ...starlightPageProps, diff --git a/packages/starlight/__tests__/build-format-file/navigation.test.ts b/packages/starlight/__tests__/build-format-file/navigation.test.ts index 30d3d105..16445cb6 100644 --- a/packages/starlight/__tests__/build-format-file/navigation.test.ts +++ b/packages/starlight/__tests__/build-format-file/navigation.test.ts @@ -8,7 +8,6 @@ vi.mock('astro:content', async () => ['environmental-impact.md', { title: 'Eco-friendly docs' }], ['reference/configuration.mdx', { title: 'Config Reference' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/users.md', { title: 'Users API' }], ['guides/project-structure.mdx', { title: 'Project Structure' }], ], diff --git a/packages/starlight/__tests__/edit-url/edit-url.test.ts b/packages/starlight/__tests__/edit-url/edit-url.test.ts index c77aa93d..25ab98aa 100644 --- a/packages/starlight/__tests__/edit-url/edit-url.test.ts +++ b/packages/starlight/__tests__/edit-url/edit-url.test.ts @@ -8,7 +8,6 @@ vi.mock('astro:content', async () => ['index.mdx', { title: 'Home Page' }], ['getting-started.mdx', { title: 'Getting Started' }], [ - // @ts-expect-error — Using a slug not present in Starlight docs site 'showcase.mdx', { title: 'Custom edit link', editUrl: 'https://example.com/custom-edit?link' }, ], diff --git a/packages/starlight/__tests__/git-utils.ts b/packages/starlight/__tests__/git-utils.ts index 81999931..75f0054b 100644 --- a/packages/starlight/__tests__/git-utils.ts +++ b/packages/starlight/__tests__/git-utils.ts @@ -42,6 +42,9 @@ export function makeTestRepo(onPath?: string) { // This sets both the author and committer dates to the provided date. runInRepo('git', ['commit', '-m', message, '--date', date], { GIT_COMMITTER_DATE: date }); }, + getRepoPath() { + return repoPath; + }, getFilePath(name: string) { return join(repoPath, name); }, diff --git a/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts b/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts index fae14a98..216b17b5 100644 --- a/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts +++ b/packages/starlight/__tests__/i18n-non-root-single-locale/routing.test.ts @@ -1,11 +1,11 @@ import { expect, test, vi } from 'vitest'; +import project from 'virtual:starlight/project-context'; import { routes } from '../../utils/routing'; vi.mock('astro:content', async () => (await import('../test-utils')).mockedAstroContent({ docs: [ ['fr/index.mdx', { title: 'Accueil' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Home page' }], ['404.md', { title: '404' }], ], @@ -13,7 +13,9 @@ vi.mock('astro:content', async () => ); test('route slugs are normalized', () => { - const indexRoute = routes.find((route) => route.id.startsWith('fr/index.md')); + const indexRoute = routes.find( + (route) => route.entry.id === (project.legacyCollections ? 'fr/index.mdx' : 'fr') + ); expect(indexRoute?.slug).toBe('fr'); }); diff --git a/packages/starlight/__tests__/i18n-root-locale/routing.test.ts b/packages/starlight/__tests__/i18n-root-locale/routing.test.ts index 32654f3a..f23be463 100644 --- a/packages/starlight/__tests__/i18n-root-locale/routing.test.ts +++ b/packages/starlight/__tests__/i18n-root-locale/routing.test.ts @@ -1,3 +1,4 @@ +import project from 'virtual:starlight/project-context'; import config from 'virtual:starlight/user-config'; import { assert, expect, test, vi } from 'vitest'; import { routes } from '../../utils/routing'; @@ -9,9 +10,7 @@ vi.mock('astro:content', async () => docs: [ ['404.md', { title: 'Page introuvable' }], ['index.mdx', { title: 'Accueil' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Home page' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['ar/index.mdx', { title: 'الصفحة الرئيسية' }], [ 'guides/authoring-content.mdx', @@ -61,7 +60,13 @@ test('fallback routes have fallback locale data in entryMeta', () => { }); test('fallback routes use their own locale data', () => { - const enGuide = routes.find((route) => route.id === 'en/guides/authoring-content.mdx'); + const enGuide = routes.find( + (route) => + route.id === + (project.legacyCollections + ? 'en/guides/authoring-content.mdx' + : 'en/guides/authoring-content') + ); if (!enGuide) throw new Error('Expected to find English fallback route for authoring-content.mdx'); expect(enGuide.locale).toBe('en'); @@ -83,8 +88,8 @@ test('fallback routes use fallback entry last updated dates', () => { expect(getNewestCommitDate).toHaveBeenCalledOnce(); expect(getNewestCommitDate).toHaveBeenCalledWith( - 'guides/authoring-content.mdx' - //^ no `en/` prefix + 'src/content/docs/guides/authoring-content.mdx' + // ^ no `en/` prefix ); getNewestCommitDate.mockRestore(); diff --git a/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts b/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts index 64e482e7..a356dd4b 100644 --- a/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts +++ b/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts @@ -1,4 +1,5 @@ import { expect, test, vi } from 'vitest'; +import project from 'virtual:starlight/project-context'; import { routes } from '../../utils/routing'; vi.mock('astro:content', async () => @@ -6,14 +7,15 @@ vi.mock('astro:content', async () => docs: [ ['index.mdx', { title: 'Accueil' }], ['guides/authoring-content.mdx', { title: 'Authoring content' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Not the home page' }], ], }) ); test('route slugs are normalized', () => { - const indexRoute = routes.find((route) => route.id.startsWith('index.md')); + const indexRoute = routes.find( + (route) => route.id === (project.legacyCollections ? 'index.mdx' : '') + ); expect(indexRoute?.slug).toBe(''); }); diff --git a/packages/starlight/__tests__/i18n/navigation-order.test.ts b/packages/starlight/__tests__/i18n/navigation-order.test.ts index fb37ca62..96e60f9c 100644 --- a/packages/starlight/__tests__/i18n/navigation-order.test.ts +++ b/packages/starlight/__tests__/i18n/navigation-order.test.ts @@ -5,21 +5,13 @@ vi.mock('astro:content', async () => (await import('../test-utils')).mockedAstroContent({ docs: [ ['fr/index.mdx', { title: 'Accueil' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Home page', sidebar: { order: 1 } }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['ar/index.mdx', { title: 'الصفحة الرئيسية' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/guides/authoring-content.md', { title: 'Authoring Markdown' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/404.md', { title: 'Not found' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['fr/route/distribuer.mdx', { title: 'Distribuer' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['fr/route/décoder.mdx', { title: 'Décoder' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['fr/référence/bricolage.mdx', { title: 'Bricolage' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['fr/référence/bénéfice.mdx', { title: 'Bénéfice' }], ], }) diff --git a/packages/starlight/__tests__/i18n/routing.test.ts b/packages/starlight/__tests__/i18n/routing.test.ts index 8c025e2c..7e9f254a 100644 --- a/packages/starlight/__tests__/i18n/routing.test.ts +++ b/packages/starlight/__tests__/i18n/routing.test.ts @@ -1,4 +1,5 @@ import config from 'virtual:starlight/user-config'; +import project from 'virtual:starlight/project-context'; import { expect, test, vi } from 'vitest'; import { routes } from '../../utils/routing'; @@ -6,13 +7,9 @@ vi.mock('astro:content', async () => (await import('../test-utils')).mockedAstroContent({ docs: [ ['fr/index.mdx', { title: 'Accueil' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/index.mdx', { title: 'Home page' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['ar/index.mdx', { title: 'الصفحة الرئيسية' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/guides/authoring-content.md', { title: 'Création de contenu en Markdown' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['en/404.md', { title: 'Page introuvable' }], ['it/index.mdx', { title: 'Pagina iniziale' }], ['404.md', { title: '404' }], @@ -68,7 +65,11 @@ test('fallback routes have fallback locale data in entryMeta', () => { }); test('fallback routes use their own locale data', () => { - const arGuide = routes.find((route) => route.id === 'ar/guides/authoring-content.md'); + const arGuide = routes.find( + (route) => + route.id === + (project.legacyCollections ? 'ar/guides/authoring-content.md' : 'ar/guides/authoring-content') + ); if (!arGuide) throw new Error('Expected to find Arabic fallback route for authoring-content.md'); expect(arGuide.locale).toBe('ar'); expect(arGuide.lang).toBe('ar'); diff --git a/packages/starlight/__tests__/plugins/config.test.ts b/packages/starlight/__tests__/plugins/config.test.ts index 948c0726..8848e349 100644 --- a/packages/starlight/__tests__/plugins/config.test.ts +++ b/packages/starlight/__tests__/plugins/config.test.ts @@ -52,7 +52,7 @@ test('receives the user provided configuration including the plugins list', asyn describe('validation', () => { test('validates starlight configuration before running plugins', async () => { - expect( + await expect( async () => await runPlugins( // @ts-expect-error - invalid sidebar config. @@ -64,7 +64,7 @@ describe('validation', () => { }); test('validates plugins configuration before running them', async () => { - expect( + await expect( async () => await runPlugins( { title: 'Test Docs' }, @@ -76,7 +76,7 @@ describe('validation', () => { }); test('validates configuration updates from plugins do not update the `plugins` config key', async () => { - expect( + await expect( async () => await runPlugins( { title: 'Test Docs' }, @@ -99,7 +99,7 @@ describe('validation', () => { }); test('validates configuration updates from plugins', async () => { - expect( + await expect( async () => await runPlugins( { title: 'Test Docs' }, diff --git a/packages/starlight/__tests__/remark-rehype/asides.test.ts b/packages/starlight/__tests__/remark-rehype/asides.test.ts index 8ece4c12..456540b6 100644 --- a/packages/starlight/__tests__/remark-rehype/asides.test.ts +++ b/packages/starlight/__tests__/remark-rehype/asides.test.ts @@ -38,7 +38,7 @@ test('generates aside', async () => { Some text ::: `); - expect(res.code).toMatchFileSnapshot('./snapshots/generates-aside.html'); + await expect(res.code).toMatchFileSnapshot('./snapshots/generates-aside.html'); }); describe('default labels', () => { @@ -128,7 +128,7 @@ More. ::: `); - expect(res.code).toMatchFileSnapshot('./snapshots/handles-complex-children.html'); + await expect(res.code).toMatchFileSnapshot('./snapshots/handles-complex-children.html'); }); test('nested asides', async () => { @@ -142,7 +142,7 @@ Nested tip. :::: `); - expect(res.code).toMatchFileSnapshot('./snapshots/nested-asides.html'); + await expect(res.code).toMatchFileSnapshot('./snapshots/nested-asides.html'); }); test('nested asides with custom titles', async () => { @@ -171,7 +171,7 @@ Nested tip. "Tip with a custom title", ] `); - expect(res.code).toMatchFileSnapshot('./snapshots/nested-asides-custom-titles.html'); + await expect(res.code).toMatchFileSnapshot('./snapshots/nested-asides-custom-titles.html'); }); describe('translated labels in French', () => { diff --git a/packages/starlight/__tests__/remark-rehype/rehype-file-tree.test.ts b/packages/starlight/__tests__/remark-rehype/rehype-file-tree.test.ts index dcbe62f5..36e8cb41 100644 --- a/packages/starlight/__tests__/remark-rehype/rehype-file-tree.test.ts +++ b/packages/starlight/__tests__/remark-rehype/rehype-file-tree.test.ts @@ -51,7 +51,7 @@ describe('validation', () => { }); describe('processor', () => { - test('processes a basic tree', () => { + test('processes a basic tree', async () => { const html = processTestFileTree(`
  • root_file
  • root_directory/ @@ -61,7 +61,7 @@ describe('processor', () => {
`); - expect(extractFileTree(html)).toMatchFileSnapshot('./snapshots/file-tree-basic.html'); + await expect(extractFileTree(html)).toMatchFileSnapshot('./snapshots/file-tree-basic.html'); }); test('does not add a comment node with no comments', () => { @@ -70,18 +70,22 @@ describe('processor', () => { expect(extractFileTree(html)).not.toContain(''); }); - test('processes text comments following the file name', () => { + test('processes text comments following the file name', async () => { const html = processTestFileTree(`
  • file this is a comment
`); - expect(extractFileTree(html)).toMatchFileSnapshot('./snapshots/file-tree-comment-text.html'); + await expect(extractFileTree(html)).toMatchFileSnapshot( + './snapshots/file-tree-comment-text.html' + ); }); - test('processes comment nodes', () => { + test('processes comment nodes', async () => { const html = processTestFileTree( `
  • file this is an important comment
` ); - expect(extractFileTree(html)).toMatchFileSnapshot('./snapshots/file-tree-comment-nodes.html'); + await expect(extractFileTree(html)).toMatchFileSnapshot( + './snapshots/file-tree-comment-nodes.html' + ); }); test('identifies directory with either a file name ending with a slash or a nested list', () => { diff --git a/packages/starlight/__tests__/sidebar/navigation-attributes.test.ts b/packages/starlight/__tests__/sidebar/navigation-attributes.test.ts index b613eda6..3ce50a76 100644 --- a/packages/starlight/__tests__/sidebar/navigation-attributes.test.ts +++ b/packages/starlight/__tests__/sidebar/navigation-attributes.test.ts @@ -13,7 +13,6 @@ vi.mock('astro:content', async () => sidebar: { attrs: { class: 'advanced', ping: 'https://example.com' } }, }, ], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/users.md', { title: 'Users API' }], ], }) diff --git a/packages/starlight/__tests__/sidebar/navigation-badges.test.ts b/packages/starlight/__tests__/sidebar/navigation-badges.test.ts index c54546ba..2f48330d 100644 --- a/packages/starlight/__tests__/sidebar/navigation-badges.test.ts +++ b/packages/starlight/__tests__/sidebar/navigation-badges.test.ts @@ -19,7 +19,6 @@ vi.mock('astro:content', async () => }, ], ['reference/frontmatter.md', { title: 'Frontmatter Reference', sidebar: { badge: 'New' } }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/users.md', { title: 'Users API' }], ['guides/project-structure.mdx', { title: 'Project Structure' }], ], diff --git a/packages/starlight/__tests__/sidebar/navigation-hidden.test.ts b/packages/starlight/__tests__/sidebar/navigation-hidden.test.ts index 631daae1..dc46686c 100644 --- a/packages/starlight/__tests__/sidebar/navigation-hidden.test.ts +++ b/packages/starlight/__tests__/sidebar/navigation-hidden.test.ts @@ -8,7 +8,6 @@ vi.mock('astro:content', async () => ['environmental-impact.md', { title: 'Eco-friendly docs' }], ['reference/configuration.mdx', { title: 'Config Reference' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference', sidebar: { hidden: true } }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/users.md', { title: 'Users API' }], ['guides/project-structure.mdx', { title: 'Project Structure' }], ], diff --git a/packages/starlight/__tests__/sidebar/navigation-order.test.ts b/packages/starlight/__tests__/sidebar/navigation-order.test.ts index 5b754f60..aa1396c5 100644 --- a/packages/starlight/__tests__/sidebar/navigation-order.test.ts +++ b/packages/starlight/__tests__/sidebar/navigation-order.test.ts @@ -8,7 +8,6 @@ vi.mock('astro:content', async () => ['environmental-impact.md', { title: 'Eco-friendly docs' }], ['reference/configuration.mdx', { title: 'Config Reference' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference', sidebar: { order: 1 } }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/users.md', { title: 'Users API' }], ['guides/project-structure.mdx', { title: 'Project Structure' }], ], diff --git a/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts b/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts index f3026d4e..e74f7f6c 100644 --- a/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts +++ b/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts @@ -8,7 +8,6 @@ vi.mock('astro:content', async () => ['environmental-impact.md', { title: 'Eco-friendly docs' }], ['reference/configuration.mdx', { title: 'Config Reference' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/用户.md', { title: 'Path with non-ASCII characters' }], ['guides/project-structure.mdx', { title: 'Project Structure' }], ], diff --git a/packages/starlight/__tests__/sidebar/navigation.test.ts b/packages/starlight/__tests__/sidebar/navigation.test.ts index 2ae254a5..bda1c680 100644 --- a/packages/starlight/__tests__/sidebar/navigation.test.ts +++ b/packages/starlight/__tests__/sidebar/navigation.test.ts @@ -8,9 +8,7 @@ vi.mock('astro:content', async () => ['environmental-impact.md', { title: 'Eco-friendly docs' }], ['reference/configuration.mdx', { title: 'Config Reference' }], ['reference/frontmatter.md', { title: 'Frontmatter Reference' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['reference/frontmatter/foo.mdx', { title: 'Foo' }], - // @ts-expect-error — Using a slug not present in Starlight docs site ['api/v1/users.md', { title: 'Users API' }], ['guides/project-structure.mdx', { title: 'Project Structure' }], ], diff --git a/packages/starlight/__tests__/test-config.ts b/packages/starlight/__tests__/test-config.ts index 47ab267d..73ae958c 100644 --- a/packages/starlight/__tests__/test-config.ts +++ b/packages/starlight/__tests__/test-config.ts @@ -6,6 +6,8 @@ import { vitePluginStarlightUserConfig } from '../integrations/virtual-user-conf import { runPlugins, type StarlightUserConfigWithPlugins } from '../utils/plugins'; import { createTestPluginContext } from './test-plugin-utils'; +const testLegacyCollections = process.env.LEGACY_COLLECTIONS === 'true'; + export async function defineVitestConfig( { plugins, ...config }: StarlightUserConfigWithPlugins, opts?: { @@ -35,6 +37,7 @@ export async function defineVitestConfig( srcDir, build, trailingSlash, + legacy: { collections: testLegacyCollections }, }, pluginTranslations ), diff --git a/packages/starlight/__tests__/test-utils.ts b/packages/starlight/__tests__/test-utils.ts index 81faadf6..45dbde66 100644 --- a/packages/starlight/__tests__/test-utils.ts +++ b/packages/starlight/__tests__/test-utils.ts @@ -1,6 +1,7 @@ import { z } from 'astro/zod'; +import project from 'virtual:starlight/project-context'; import { docsSchema, i18nSchema } from '../schema'; -import type { StarlightDocsEntry } from '../utils/routing'; +import type { StarlightDocsCollectionEntry } from '../utils/routing'; import { vi } from 'vitest'; const frontmatterSchema = docsSchema()({ @@ -23,18 +24,26 @@ const frontmatterSchema = docsSchema()({ }); function mockDoc( - id: StarlightDocsEntry['id'], + docsFilePath: string, data: z.input, body = '' -): StarlightDocsEntry { - return { - id, - slug: id.replace(/\.[^\.]+$/, '').replace(/\/index$/, ''), +): StarlightDocsCollectionEntry { + const slug = docsFilePath.replace(/\.[^\.]+$/, '').replace(/\/index$/, ''); + + const doc: StarlightDocsCollectionEntry = { + id: project.legacyCollections ? docsFilePath : slug, body, collection: 'docs', data: frontmatterSchema.parse(data), - render: (() => {}) as StarlightDocsEntry['render'], }; + + if (project.legacyCollections) { + doc.slug = slug; + } else { + doc.filePath = `src/content/docs/${docsFilePath}`; + } + + return doc; } function mockDict(id: string, data: z.input>) { @@ -69,10 +78,20 @@ export async function mockedAstroContent({ export async function mockedCollectionConfig(docsUserSchema?: Parameters[0]) { const content = await vi.importActual('astro:content'); const schemas = await vi.importActual('../schema'); + const loaders = await vi.importActual('../loaders'); + return { collections: { - docs: content.defineCollection({ schema: schemas.docsSchema(docsUserSchema) }), - i18n: content.defineCollection({ type: 'data', schema: schemas.i18nSchema() }), + docs: content.defineCollection( + project.legacyCollections + ? { schema: schemas.docsSchema(docsUserSchema) } + : { loader: loaders.docsLoader(), schema: schemas.docsSchema(docsUserSchema) } + ), + i18n: content.defineCollection( + project.legacyCollections + ? { type: 'data', schema: schemas.i18nSchema() } + : { loader: loaders.i18nLoader(), schema: schemas.i18nSchema() } + ), }, }; } diff --git a/packages/starlight/components/EmptyMarkdown.md b/packages/starlight/components/EmptyMarkdown.md deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/starlight/components/Page.astro b/packages/starlight/components/Page.astro index 0ab90d1b..c1c7406f 100644 --- a/packages/starlight/components/Page.astro +++ b/packages/starlight/components/Page.astro @@ -35,16 +35,14 @@ const pagefindEnabled = Astro.props.entry.slug !== '404' && !Astro.props.entry.slug.endsWith('/404') && Astro.props.entry.data.pagefind !== false; + +const dataAttributes: DOMStringMap = { 'data-theme': 'dark' }; +if (Boolean(Astro.props.toc)) dataAttributes['data-has-toc'] = ''; +if (Astro.props.hasSidebar) dataAttributes['data-has-sidebar'] = ''; +if (Boolean(Astro.props.entry.data.hero)) dataAttributes['data-has-hero'] = ''; --- - +