summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiDeoo2024-09-07 00:19:29 +0200
committerGitHub2024-09-07 00:19:29 +0200
commit20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7 (patch)
tree9b2fa0ab6b62df74078f295dd43d684f390f6db4
parent756e85e8e814657c42c4a6f9c299b5bef32aee22 (diff)
downloadIT.starlight-20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7.tar.gz
IT.starlight-20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7.tar.bz2
IT.starlight-20cbf3b6a4d1598a62fdb176ebaa849bc7b978f7.zip
Add Markdoc preset and example (#2249)
Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com> Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
-rw-r--r--.changeset/selfish-chefs-tie.md7
-rw-r--r--.github/labeler.yml3
-rw-r--r--docs/src/content/docs/guides/authoring-content.mdx (renamed from docs/src/content/docs/guides/authoring-content.md)147
-rw-r--r--docs/src/content/docs/guides/pages.mdx2
-rw-r--r--examples/markdoc/.gitignore21
-rw-r--r--examples/markdoc/.vscode/extensions.json4
-rw-r--r--examples/markdoc/.vscode/launch.json11
-rw-r--r--examples/markdoc/README.md56
-rw-r--r--examples/markdoc/astro.config.mjs29
-rw-r--r--examples/markdoc/markdoc.config.mjs7
-rw-r--r--examples/markdoc/package.json20
-rw-r--r--examples/markdoc/public/favicon.svg1
-rw-r--r--examples/markdoc/src/assets/houston.webpbin0 -> 98506 bytes
-rw-r--r--examples/markdoc/src/content/config.ts6
-rw-r--r--examples/markdoc/src/content/docs/guides/example.mdoc11
-rw-r--r--examples/markdoc/src/content/docs/index.mdoc35
-rw-r--r--examples/markdoc/src/content/docs/reference/example.mdoc11
-rw-r--r--examples/markdoc/src/env.d.ts1
-rw-r--r--examples/markdoc/tsconfig.json3
-rw-r--r--packages/markdoc/.npmignore1
-rw-r--r--packages/markdoc/Code.astro16
-rw-r--r--packages/markdoc/README.md18
-rw-r--r--packages/markdoc/__tests__/markdoc.test-d.ts127
-rw-r--r--packages/markdoc/components.ts1
-rw-r--r--packages/markdoc/html.mjs44
-rw-r--r--packages/markdoc/index.mjs264
-rw-r--r--packages/markdoc/package.json26
-rw-r--r--packages/starlight/__tests__/basics/navigation-labels.test.ts2
-rw-r--r--packages/starlight/__tests__/basics/navigation-order.test.ts2
-rw-r--r--packages/starlight/__tests__/basics/navigation.test.ts2
-rw-r--r--packages/starlight/__tests__/basics/pagination-with-base.test.ts2
-rw-r--r--packages/starlight/__tests__/basics/routing.test.ts6
-rw-r--r--packages/starlight/__tests__/basics/starlight-page-route-data.test.ts2
-rw-r--r--packages/starlight/__tests__/i18n-root-locale/routing.test.ts11
-rw-r--r--packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts2
-rw-r--r--packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts2
-rw-r--r--packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts2
-rw-r--r--packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts2
-rw-r--r--pnpm-lock.yaml101
39 files changed, 970 insertions, 38 deletions
diff --git a/.changeset/selfish-chefs-tie.md b/.changeset/selfish-chefs-tie.md
new file mode 100644
index 00000000..f8869194
--- /dev/null
+++ b/.changeset/selfish-chefs-tie.md
@@ -0,0 +1,7 @@
+---
+'@astrojs/starlight-markdoc': minor
+---
+
+Adds Starlight Markdoc preset.
+
+See the [“Markdoc”](https://starlight.astro.build/guides/authoring-content/#markdoc) guide to learn more on how to use this preset in a new or existing project.
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 6049ae3c..4913a2e0 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -26,5 +26,8 @@ i18n:
'🌟 tailwind':
- packages/tailwind/**
+'🌟 markdoc':
+ - packages/markdoc/**
+
'📚 docs':
- docs/**
diff --git a/docs/src/content/docs/guides/authoring-content.md b/docs/src/content/docs/guides/authoring-content.mdx
index 2fe84815..58c6f081 100644
--- a/docs/src/content/docs/guides/authoring-content.md
+++ b/docs/src/content/docs/guides/authoring-content.mdx
@@ -203,8 +203,8 @@ A code block is indicated by a block with three backticks <code>```</code> at th
```js
// Javascript code with syntax highlighting.
var fun = function lang(l) {
- dateformat.i18n = require('./lang/' + l);
- return true;
+ dateformat.i18n = require('./lang/' + l);
+ return true;
};
```
@@ -212,8 +212,8 @@ var fun = function lang(l) {
```js
// Javascript code with syntax highlighting.
var fun = function lang(l) {
- dateformat.i18n = require('./lang/' + l);
- return true;
+ dateformat.i18n = require('./lang/' + l);
+ return true;
};
```
````
@@ -241,16 +241,16 @@ Some of the most common examples are shown below:
```js {2-3}
function demo() {
- // This line (#2) and the next one are highlighted
- return 'This is line #3 of this snippet';
+ // This line (#2) and the next one are highlighted
+ return 'This is line #3 of this snippet';
}
```
````md
```js {2-3}
function demo() {
- // This line (#2) and the next one are highlighted
- return 'This is line #3 of this snippet';
+ // This line (#2) and the next one are highlighted
+ return 'This is line #3 of this snippet';
}
```
````
@@ -260,7 +260,7 @@ Some of the most common examples are shown below:
```js "Individual terms" /Even.*supported/
// Individual terms can be highlighted, too
function demo() {
- return 'Even regular expressions are supported';
+ return 'Even regular expressions are supported';
}
```
@@ -268,7 +268,7 @@ Some of the most common examples are shown below:
```js "Individual terms" /Even.*supported/
// Individual terms can be highlighted, too
function demo() {
- return 'Even regular expressions are supported';
+ return 'Even regular expressions are supported';
}
```
````
@@ -277,18 +277,18 @@ Some of the most common examples are shown below:
```js "return true;" ins="inserted" del="deleted"
function demo() {
- console.log('These are inserted and deleted marker types');
- // The return statement uses the default marker type
- return true;
+ console.log('These are inserted and deleted marker types');
+ // The return statement uses the default marker type
+ return true;
}
```
````md
```js "return true;" ins="inserted" del="deleted"
function demo() {
- console.log('These are inserted and deleted marker types');
- // The return statement uses the default marker type
- return true;
+ console.log('These are inserted and deleted marker types');
+ // The return statement uses the default marker type
+ return true;
}
```
````
@@ -393,3 +393,118 @@ Starlight supports all other Markdown authoring syntax, such as lists and tables
## Advanced Markdown and MDX configuration
Starlight uses Astro’s Markdown and MDX renderer built on remark and rehype. You can add support for custom syntax and behavior by adding `remarkPlugins` or `rehypePlugins` in your Astro config file. See [“Configuring Markdown and MDX”](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown-and-mdx) in the Astro docs to learn more.
+
+## Markdoc
+
+Starlight supports authoring content in Markdoc using the experimental [Astro Markdoc integration](https://docs.astro.build/en/guides/integrations-guide/markdoc/) and the Starlight Markdoc preset.
+
+### Create a new project with Markdoc
+
+Start a new Starlight project with Markdoc pre-configured using `create astro`:
+
+import { Tabs, TabItem, Steps } from '@astrojs/starlight/components';
+
+<Tabs syncKey="pkg">
+<TabItem label="npm">
+
+```sh
+npm create astro@latest -- --template starlight/markdoc
+```
+
+</TabItem>
+<TabItem label="pnpm">
+
+```sh
+pnpm create astro --template starlight/markdoc
+```
+
+</TabItem>
+<TabItem label="Yarn">
+
+```sh
+yarn create astro --template starlight/markdoc
+```
+
+</TabItem>
+</Tabs>
+
+### Add Markdoc to an existing project
+
+If you already have a Starlight site and want to add Markdoc, follow these steps.
+
+<Steps>
+
+1. Add Astro’s Markdoc integration:
+
+ <Tabs syncKey="pkg">
+
+ <TabItem label="npm">
+
+ ```sh
+ npx astro add markdoc
+ ```
+
+ </TabItem>
+
+ <TabItem label="pnpm">
+
+ ```sh
+ pnpm astro add markdoc
+ ```
+
+ </TabItem>
+
+ <TabItem label="Yarn">
+
+ ```sh
+ yarn astro add markdoc
+ ```
+
+ </TabItem>
+
+ </Tabs>
+
+2. Install the Starlight Markdoc preset:
+
+ <Tabs syncKey="pkg">
+
+ <TabItem label="npm">
+
+ ```sh
+ npm install @astrojs/starlight-markdoc
+ ```
+
+ </TabItem>
+
+ <TabItem label="pnpm">
+
+ ```sh
+ pnpm add @astrojs/starlight-markdoc
+ ```
+
+ </TabItem>
+
+ <TabItem label="Yarn">
+
+ ```sh
+ yarn add @astrojs/starlight-markdoc
+ ```
+
+ </TabItem>
+
+ </Tabs>
+
+3. Create a Markdoc configuration file at `markdoc.config.mjs` and use the Starlight Markdoc preset:
+
+ ```js
+ import { defineMarkdocConfig } from '@astrojs/markdoc/config';
+ import starlightMarkdoc from '@astrojs/starlight-markdoc';
+
+ export default defineMarkdocConfig({
+ extends: [starlightMarkdoc()],
+ });
+ ```
+
+</Steps>
+
+To learn more about the Markdoc syntax and features, see the [Markdoc documentation](https://markdoc.dev/docs/syntax) or the [Astro Markdoc integration guide](https://docs.astro.build/en/guides/integrations-guide/markdoc/).
diff --git a/docs/src/content/docs/guides/pages.mdx b/docs/src/content/docs/guides/pages.mdx
index f112a572..663bea68 100644
--- a/docs/src/content/docs/guides/pages.mdx
+++ b/docs/src/content/docs/guides/pages.mdx
@@ -14,7 +14,7 @@ This guide shows how page generation works in Starlight.
### File formats
Starlight supports authoring content in Markdown and MDX with no configuration required.
-You can add support for Markdoc by installing the experimental [Astro Markdoc integration](https://docs.astro.build/en/guides/integrations-guide/markdoc/).
+You can add support for Markdoc by following the [“Markdoc” guide](/guides/authoring-content/#markdoc).
### Add pages
diff --git a/examples/markdoc/.gitignore b/examples/markdoc/.gitignore
new file mode 100644
index 00000000..6240da8b
--- /dev/null
+++ b/examples/markdoc/.gitignore
@@ -0,0 +1,21 @@
+# build output
+dist/
+# generated types
+.astro/
+
+# dependencies
+node_modules/
+
+# logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+
+# environment variables
+.env
+.env.production
+
+# macOS-specific files
+.DS_Store
diff --git a/examples/markdoc/.vscode/extensions.json b/examples/markdoc/.vscode/extensions.json
new file mode 100644
index 00000000..a83595b1
--- /dev/null
+++ b/examples/markdoc/.vscode/extensions.json
@@ -0,0 +1,4 @@
+{
+ "recommendations": ["astro-build.astro-vscode", "stripe.markdoc-language-support"],
+ "unwantedRecommendations": []
+}
diff --git a/examples/markdoc/.vscode/launch.json b/examples/markdoc/.vscode/launch.json
new file mode 100644
index 00000000..d6422097
--- /dev/null
+++ b/examples/markdoc/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "command": "./node_modules/.bin/astro dev",
+ "name": "Development server",
+ "request": "launch",
+ "type": "node-terminal"
+ }
+ ]
+}
diff --git a/examples/markdoc/README.md b/examples/markdoc/README.md
new file mode 100644
index 00000000..584fd88e
--- /dev/null
+++ b/examples/markdoc/README.md
@@ -0,0 +1,56 @@
+# Starlight Starter Kit: Markdoc
+
+[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build)
+
+```
+npm create astro@latest -- --template starlight/markdoc
+```
+
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/markdoc)
+[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/markdoc)
+[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/markdoc)
+[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fmarkdoc&project-name=my-starlight-docs&repository-name=my-starlight-docs)
+
+> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
+
+## 🚀 Project Structure
+
+Inside of your Astro + Starlight project, you'll see the following folders and files:
+
+```
+.
+├── public/
+├── src/
+│ ├── assets/
+│ ├── content/
+│ │ ├── docs/
+│ │ └── config.ts
+│ └── env.d.ts
+├── astro.config.mjs
+├── markdoc.config.mjs
+├── package.json
+└── tsconfig.json
+```
+
+Starlight looks for `.md`, `.mdx` or `.mdoc` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
+
+Images can be added to `src/assets/` and embedded in Markdown with a relative link.
+
+Static assets, like favicons, can be placed in the `public/` directory.
+
+## 🧞 Commands
+
+All commands are run from the root of the project, from a terminal:
+
+| Command | Action |
+| :------------------------ | :----------------------------------------------- |
+| `npm install` | Installs dependencies |
+| `npm run dev` | Starts local dev server at `localhost:4321` |
+| `npm run build` | Build your production site to `./dist/` |
+| `npm run preview` | Preview your build locally, before deploying |
+| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
+| `npm run astro -- --help` | Get help using the Astro CLI |
+
+## 👀 Want to learn more?
+
+Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
diff --git a/examples/markdoc/astro.config.mjs b/examples/markdoc/astro.config.mjs
new file mode 100644
index 00000000..03155ce5
--- /dev/null
+++ b/examples/markdoc/astro.config.mjs
@@ -0,0 +1,29 @@
+import { defineConfig } from 'astro/config';
+import starlight from '@astrojs/starlight';
+import markdoc from '@astrojs/markdoc';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [
+ markdoc(),
+ starlight({
+ title: 'My Docs',
+ social: {
+ github: 'https://github.com/withastro/starlight',
+ },
+ sidebar: [
+ {
+ label: 'Guides',
+ items: [
+ // Each item here is one entry in the navigation menu.
+ { label: 'Example Guide', slug: 'guides/example' },
+ ],
+ },
+ {
+ label: 'Reference',
+ autogenerate: { directory: 'reference' },
+ },
+ ],
+ }),
+ ],
+});
diff --git a/examples/markdoc/markdoc.config.mjs b/examples/markdoc/markdoc.config.mjs
new file mode 100644
index 00000000..ecda158d
--- /dev/null
+++ b/examples/markdoc/markdoc.config.mjs
@@ -0,0 +1,7 @@
+import { defineMarkdocConfig } from '@astrojs/markdoc/config';
+import starlightMarkdoc from '@astrojs/starlight-markdoc';
+
+// https://docs.astro.build/en/guides/integrations-guide/markdoc/
+export default defineMarkdocConfig({
+ extends: [starlightMarkdoc()],
+});
diff --git a/examples/markdoc/package.json b/examples/markdoc/package.json
new file mode 100644
index 00000000..d87a8ac6
--- /dev/null
+++ b/examples/markdoc/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "@example/starlight-markdoc",
+ "type": "module",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "dev": "astro dev",
+ "start": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview",
+ "astro": "astro"
+ },
+ "dependencies": {
+ "@astrojs/markdoc": "^0.11.4",
+ "@astrojs/starlight": "^0.26.1",
+ "@astrojs/starlight-markdoc": "^0.0.1",
+ "astro": "^4.15.3",
+ "sharp": "^0.32.5"
+ }
+}
diff --git a/examples/markdoc/public/favicon.svg b/examples/markdoc/public/favicon.svg
new file mode 100644
index 00000000..cba5ac14
--- /dev/null
+++ b/examples/markdoc/public/favicon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg> \ No newline at end of file
diff --git a/examples/markdoc/src/assets/houston.webp b/examples/markdoc/src/assets/houston.webp
new file mode 100644
index 00000000..930c1649
--- /dev/null
+++ b/examples/markdoc/src/assets/houston.webp
Binary files differ
diff --git a/examples/markdoc/src/content/config.ts b/examples/markdoc/src/content/config.ts
new file mode 100644
index 00000000..45f60b01
--- /dev/null
+++ b/examples/markdoc/src/content/config.ts
@@ -0,0 +1,6 @@
+import { defineCollection } from 'astro:content';
+import { docsSchema } from '@astrojs/starlight/schema';
+
+export const collections = {
+ docs: defineCollection({ schema: docsSchema() }),
+};
diff --git a/examples/markdoc/src/content/docs/guides/example.mdoc b/examples/markdoc/src/content/docs/guides/example.mdoc
new file mode 100644
index 00000000..ebd0f3bc
--- /dev/null
+++ b/examples/markdoc/src/content/docs/guides/example.mdoc
@@ -0,0 +1,11 @@
+---
+title: Example Guide
+description: A guide in my new Starlight docs site.
+---
+
+Guides lead a user through a specific task they want to accomplish, often with a sequence of steps.
+Writing a good guide requires thinking about what your users are trying to do.
+
+## Further reading
+
+- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework
diff --git a/examples/markdoc/src/content/docs/index.mdoc b/examples/markdoc/src/content/docs/index.mdoc
new file mode 100644
index 00000000..814dc120
--- /dev/null
+++ b/examples/markdoc/src/content/docs/index.mdoc
@@ -0,0 +1,35 @@
+---
+title: Welcome to Starlight
+description: Get started building your docs site with Starlight.
+template: splash
+hero:
+ title: Welcome to Starlight with Markdoc
+ tagline: Congrats on setting up a new Starlight project!
+ image:
+ file: ../../assets/houston.webp
+ actions:
+ - text: Example Guide
+ link: /guides/example/
+ icon: right-arrow
+ - text: Read the Starlight docs
+ link: https://starlight.astro.build
+ icon: external
+ variant: minimal
+---
+
+## Next steps
+
+{% cardgrid stagger=true %}
+{% card title="Update content" icon="pencil" %}
+Edit `src/content/docs/index.mdoc` to see this page change.
+{% /card %}
+{% card title="Add new content" icon="add-document" %}
+Add Markdoc files to `src/content/docs` to create new pages.
+{% /card %}
+{% card title="Configure your site" icon="setting" %}
+Edit your `sidebar` and other config in `astro.config.mjs`.
+{% /card %}
+{% card title="Read the docs" icon="open-book" %}
+Learn more in [the Starlight Docs](https://starlight.astro.build/).
+{% /card %}
+{% /cardgrid %}
diff --git a/examples/markdoc/src/content/docs/reference/example.mdoc b/examples/markdoc/src/content/docs/reference/example.mdoc
new file mode 100644
index 00000000..0224f096
--- /dev/null
+++ b/examples/markdoc/src/content/docs/reference/example.mdoc
@@ -0,0 +1,11 @@
+---
+title: Example Reference
+description: A reference page in my new Starlight docs site.
+---
+
+Reference pages are ideal for outlining how things work in terse and clear terms.
+Less concerned with telling a story or addressing a specific use case, they should give a comprehensive outline of what you're documenting.
+
+## Further reading
+
+- Read [about reference](https://diataxis.fr/reference/) in the Diátaxis framework
diff --git a/examples/markdoc/src/env.d.ts b/examples/markdoc/src/env.d.ts
new file mode 100644
index 00000000..e16c13c6
--- /dev/null
+++ b/examples/markdoc/src/env.d.ts
@@ -0,0 +1 @@
+/// <reference path="../.astro/types.d.ts" />
diff --git a/examples/markdoc/tsconfig.json b/examples/markdoc/tsconfig.json
new file mode 100644
index 00000000..bcbf8b50
--- /dev/null
+++ b/examples/markdoc/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "astro/tsconfigs/strict"
+}
diff --git a/packages/markdoc/.npmignore b/packages/markdoc/.npmignore
new file mode 100644
index 00000000..c8740c5e
--- /dev/null
+++ b/packages/markdoc/.npmignore
@@ -0,0 +1 @@
+__tests__/
diff --git a/packages/markdoc/Code.astro b/packages/markdoc/Code.astro
new file mode 100644
index 00000000..8c8a0609
--- /dev/null
+++ b/packages/markdoc/Code.astro
@@ -0,0 +1,16 @@
+---
+import { Code as Default } from '@astrojs/starlight/components';
+
+interface Props {
+ code: string;
+ lang?: string;
+}
+
+/**
+ * This component is a basic wrapper for the `<Code>` component from Starlight used for Markdoc
+ * fenced code blocks that ensures that we do not pass any child content to the `<Code>` component
+ * which is an usage not supported by Expressive Code and would throw an error.
+ */
+---
+
+<Default {...Astro.props} />
diff --git a/packages/markdoc/README.md b/packages/markdoc/README.md
new file mode 100644
index 00000000..8141a004
--- /dev/null
+++ b/packages/markdoc/README.md
@@ -0,0 +1,18 @@
+# <img src="https://github.com/withastro/starlight/assets/357379/494fcd83-42aa-4891-87e0-87402fa0b6f3" alt="" align="left" width="40" height="40"> @astrojs/starlight-markdoc
+
+Markdoc preset for the [Starlight][starlight] documentation theme for [Astro][astro].
+
+## Documentation
+
+See the [Starlight Markdoc docs][docs] for how to use this preset.
+
+## License
+
+MIT
+
+Copyright (c) 2024–present [Starlight contributors][contributors]
+
+[starlight]: https://starlight.astro.build/
+[astro]: https://astro.build/
+[docs]: https://starlight.astro.build/guides/authoring-content/#markdoc
+[contributors]: https://github.com/withastro/starlight/graphs/contributors
diff --git a/packages/markdoc/__tests__/markdoc.test-d.ts b/packages/markdoc/__tests__/markdoc.test-d.ts
new file mode 100644
index 00000000..868f2c97
--- /dev/null
+++ b/packages/markdoc/__tests__/markdoc.test-d.ts
@@ -0,0 +1,127 @@
+import type { ComponentProps, HTMLAttributes } from 'astro/types';
+import { expectTypeOf, test } from 'vitest';
+
+import {
+ Aside,
+ Badge,
+ Card,
+ CardGrid,
+ Code,
+ FileTree,
+ Icon,
+ LinkButton,
+ LinkCard,
+ Steps,
+ TabItem,
+ Tabs,
+} from '@astrojs/starlight/components';
+
+type UserComponents = keyof typeof import('@astrojs/starlight/components');
+type UserComponentProps<T extends (args: any) => any> = keyof RemoveIndexSignature<
+ ComponentProps<T>
+>;
+
+type MarkdocPreset = typeof import('../index.mjs').StarlightMarkdocPreset;
+type MarkdocTags = keyof MarkdocPreset['tags'];
+type MarkdocTagAttributes<T extends MarkdocTags> = keyof MarkdocPreset['tags'][T]['attributes'];
+
+test('defines a tag for each user components', () => {
+ expectTypeOf<MarkdocTags>().toEqualTypeOf<Lowercase<UserComponents>>();
+});
+
+test('defines all `<Aside>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'aside'>>().toEqualTypeOf<UserComponentProps<typeof Aside>>();
+});
+
+test('defines all `<Badge>` component attributes', () => {
+ /**
+ * Only supports a list of well-known `<span>` attributes.
+ * @see {@link file://./../html.mjs}
+ */
+ type UnsupportedBadgeProps = Exclude<keyof HTMLAttributes<'span'>, WellKnownElementAttributes>;
+
+ expectTypeOf<MarkdocTagAttributes<'badge'>>().toEqualTypeOf<
+ Exclude<UserComponentProps<typeof Badge>, UnsupportedBadgeProps>
+ >();
+});
+
+test('defines all `<Card>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'card'>>().toEqualTypeOf<UserComponentProps<typeof Card>>();
+});
+
+test('defines all `<CardGrid>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'cardgrid'>>().toEqualTypeOf<
+ UserComponentProps<typeof CardGrid>
+ >();
+});
+
+test('defines all `<Code>` component attributes', () => {
+ /** @see {@link file://./../index.mjs} */
+ type UnsupportedCodeProps = 'mark' | 'ins' | 'del';
+
+ expectTypeOf<MarkdocTagAttributes<'code'>>().toEqualTypeOf<
+ Exclude<UserComponentProps<typeof Code>, UnsupportedCodeProps>
+ >();
+});
+
+test('defines all `<FileTree>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'filetree'>>().toEqualTypeOf<
+ UserComponentProps<typeof FileTree>
+ >();
+});
+
+test('defines all `<Icon>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'icon'>>().toEqualTypeOf<UserComponentProps<typeof Icon>>();
+});
+
+test('defines all `<LinkButton>` component attributes', () => {
+ /**
+ * Only supports a list of well-known `<a>` attributes.
+ * @see {@link file://./../html.mjs}
+ */
+ type UnsupportedLinkButtonProps = Exclude<keyof HTMLAttributes<'a'>, WellKnownAnchorAttributes>;
+
+ expectTypeOf<MarkdocTagAttributes<'linkbutton'>>().toEqualTypeOf<
+ Exclude<UserComponentProps<typeof LinkButton>, UnsupportedLinkButtonProps>
+ >();
+});
+
+test('defines all `<LinkCard>` component attributes', () => {
+ /**
+ * Only supports a list of well-known `<a>` attributes.
+ * @see {@link file://./../html.mjs}
+ */
+ type UnsupportedLinkCardProps = Exclude<keyof HTMLAttributes<'a'>, WellKnownAnchorAttributes>;
+
+ expectTypeOf<MarkdocTagAttributes<'linkcard'>>().toEqualTypeOf<
+ Exclude<UserComponentProps<typeof LinkCard>, UnsupportedLinkCardProps>
+ >();
+});
+
+test('defines all `<Steps>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'steps'>>().toEqualTypeOf<UserComponentProps<typeof Steps>>();
+});
+
+test('defines all `<TabItem>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'tabitem'>>().toEqualTypeOf<
+ UserComponentProps<typeof TabItem>
+ >();
+});
+
+test('defines all `<Tabs>` component attributes', () => {
+ expectTypeOf<MarkdocTagAttributes<'tabs'>>().toEqualTypeOf<UserComponentProps<typeof Tabs>>();
+});
+
+type WellKnownElementAttributes = keyof typeof import('../html.mjs').WellKnownElementAttributes;
+type WellKnownAnchorAttributes = keyof typeof import('../html.mjs').WellKnownAnchorAttributes;
+
+// https://stackoverflow.com/a/66252656/1945960
+type RemoveIndexSignature<T> = {
+ [K in keyof T as string extends K
+ ? never
+ : number extends K
+ ? never
+ : symbol extends K
+ ? never
+ : K]: T[K];
+};
diff --git a/packages/markdoc/components.ts b/packages/markdoc/components.ts
new file mode 100644
index 00000000..62b21695
--- /dev/null
+++ b/packages/markdoc/components.ts
@@ -0,0 +1 @@
+export { default as Code } from './Code.astro';
diff --git a/packages/markdoc/html.mjs b/packages/markdoc/html.mjs
new file mode 100644
index 00000000..259471a7
--- /dev/null
+++ b/packages/markdoc/html.mjs
@@ -0,0 +1,44 @@
+/**
+ * A list of well-known HTML element global attributes that can be used on any HTML element.
+ *
+ * @satisfies {HTMLElementTagAttributes<'span'>}
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
+ */
+export const WellKnownElementAttributes = {
+ class: { type: String },
+ dir: { type: String, matches: ['ltr', 'rtl', 'auto'] },
+ hidden: { type: String, matches: ['', 'hidden', 'until-found'] },
+ id: { type: String },
+ lang: { type: String },
+ role: { type: String },
+ style: { type: String },
+ title: { type: String },
+};
+
+/**
+ * A list of well-known HTML attributes that can be used on an `<a>` element.
+ *
+ * @satisfies {HTMLElementTagAttributes<'a'>}
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
+ */
+export const WellKnownAnchorAttributes = {
+ ...WellKnownElementAttributes,
+ download: { type: String },
+ href: { type: String },
+ hreflang: { type: String },
+ media: { type: String },
+ ping: { type: String },
+ rel: { type: String },
+ target: { type: String, matches: ['_self', '_blank', '_parent', '_top'] },
+};
+
+/**
+ * The configuration of a tag attribute.
+ * @typedef {NonNullable<NonNullable<import('@astrojs/markdoc/config').AstroMarkdocConfig['tags']>[string]['attributes']>[string]} TagAttributeConfig
+ */
+
+/**
+ * A map of HTML attributes for a specific HTML element with their associated attribute configuration.
+ * @typedef {Partial<Record<keyof import('astro/types').HTMLAttributes<T>, TagAttributeConfig>>} HTMLElementTagAttributes
+ * @template {import('astro/types').HTMLTag} T
+ */
diff --git a/packages/markdoc/index.mjs b/packages/markdoc/index.mjs
new file mode 100644
index 00000000..8c959b5e
--- /dev/null
+++ b/packages/markdoc/index.mjs
@@ -0,0 +1,264 @@
+import { component } from '@astrojs/markdoc/config';
+import { WellKnownElementAttributes, WellKnownAnchorAttributes } from './html.mjs';
+
+/**
+ * The Markdoc preset for Starlight mapping Starlight components to Markdoc nodes and tags.
+ *
+ * - The icons are not using a `matches` to provide a list of supported icons as it is not possible
+ * to import a TypeScript file in this file (which can also not be a TypeScript file). When
+ * Starlight is bundled, this could be refactored to provide a list of supported icons.
+ * - Some components (`<Badge>`, `<LinkButton>`, and `<LinkCard>`) support extra attributes, e.g.
+ * all the attributes supported by the `<a>` tag. As Markdoc requires type definitions for each
+ * attribute, only some well-known attributes are supported in these tags.
+ *
+ * @satisfies {import('@astrojs/markdoc/config').AstroMarkdocConfig}
+ */
+export const StarlightMarkdocPreset = {
+ nodes: {
+ fence: {
+ render: component('@astrojs/starlight-markdoc/components', 'Code'),
+ attributes: {
+ content: {
+ type: String,
+ required: true,
+ render: 'code',
+ },
+ language: {
+ type: String,
+ required: false,
+ render: 'lang',
+ },
+ /**
+ * Markdoc ignores meta attributes (markers) after a fence block (e.g.
+ * ```js title="example.js" del={2} ins={3-4} {6} ).
+ * This means that Expressive Code markers defined after the fence block are ignored and
+ * users would need to use the `code` tag instead.
+ *
+ * @see https://github.com/withastro/astro/blob/9f943c1344671b569a0d1ddba683b3cca0068adc/packages/integrations/markdoc/src/extensions/shiki.ts#L15-L17
+ */
+ },
+ },
+ },
+ tags: {
+ aside: {
+ render: component('@astrojs/starlight/components', 'Aside'),
+ attributes: {
+ title: {
+ type: String,
+ required: false,
+ },
+ type: {
+ type: String,
+ required: false,
+ default: 'note',
+ matches: ['note', 'danger', 'caution', 'tip'],
+ },
+ },
+ },
+ badge: {
+ render: component('@astrojs/starlight/components', 'Badge'),
+ attributes: {
+ ...WellKnownElementAttributes,
+ text: {
+ type: String,
+ required: true,
+ },
+ size: {
+ type: String,
+ required: false,
+ default: 'small',
+ matches: ['small', 'medium', 'large'],
+ },
+ variant: {
+ type: String,
+ required: false,
+ matches: ['note', 'tip', 'danger', 'caution', 'success'],
+ },
+ },
+ },
+ card: {
+ render: component('@astrojs/starlight/components', 'Card'),
+ attributes: {
+ icon: {
+ type: String,
+ required: false,
+ },
+ title: {
+ type: String,
+ required: true,
+ },
+ },
+ },
+ cardgrid: {
+ render: component('@astrojs/starlight/components', 'CardGrid'),
+ attributes: {
+ stagger: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ },
+ code: {
+ render: component('@astrojs/starlight/components', 'Code'),
+ attributes: {
+ class: {
+ type: String,
+ required: false,
+ },
+ code: {
+ type: String,
+ required: true,
+ },
+ lang: {
+ type: String,
+ required: false,
+ },
+ meta: {
+ type: String,
+ required: false,
+ },
+ locale: {
+ type: String,
+ required: false,
+ },
+ frame: {
+ type: String,
+ required: false,
+ default: 'auto',
+ matches: ['auto', 'code', 'terminal', 'none'],
+ },
+ preserveIndent: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ title: {
+ type: String,
+ required: false,
+ },
+ useDiffSyntax: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ wrap: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ /**
+ * `mark`, `ins`, and `del` are not supported as the Markdoc attribute validation syntax
+ * does not allow to describe properly all the possible values.
+ * Users should use the `meta` attribute instead.
+ *
+ * @see https://expressive-code.com/key-features/code-component/#mark--ins--del
+ */
+ },
+ },
+ filetree: {
+ render: component('@astrojs/starlight/components', 'FileTree'),
+ attributes: {},
+ },
+ icon: {
+ render: component('@astrojs/starlight/components', 'Icon'),
+ attributes: {
+ class: {
+ type: String,
+ required: false,
+ },
+ color: {
+ type: String,
+ required: false,
+ },
+ label: {
+ type: String,
+ required: false,
+ },
+ name: {
+ type: String,
+ required: true,
+ },
+ size: {
+ type: String,
+ required: false,
+ },
+ },
+ },
+ linkbutton: {
+ render: component('@astrojs/starlight/components', 'LinkButton'),
+ attributes: {
+ ...WellKnownAnchorAttributes,
+ href: {
+ type: String,
+ required: true,
+ },
+ icon: {
+ type: String,
+ required: false,
+ },
+ iconPlacement: {
+ type: String,
+ required: false,
+ default: 'end',
+ matches: ['start', 'end'],
+ },
+ variant: {
+ type: String,
+ required: false,
+ default: 'primary',
+ matches: ['primary', 'secondary', 'minimal'],
+ },
+ },
+ },
+ linkcard: {
+ render: component('@astrojs/starlight/components', 'LinkCard'),
+ attributes: {
+ ...WellKnownAnchorAttributes,
+ description: {
+ type: String,
+ required: false,
+ },
+ href: {
+ type: String,
+ required: true,
+ },
+ title: {
+ type: String,
+ required: true,
+ },
+ },
+ },
+ steps: {
+ render: component('@astrojs/starlight/components', 'Steps'),
+ attributes: {},
+ },
+ tabitem: {
+ render: component('@astrojs/starlight/components', 'TabItem'),
+ attributes: {
+ icon: {
+ type: String,
+ required: false,
+ },
+ label: {
+ type: String,
+ required: true,
+ },
+ },
+ },
+ tabs: {
+ render: component('@astrojs/starlight/components', 'Tabs'),
+ attributes: {
+ syncKey: {
+ type: String,
+ required: false,
+ },
+ },
+ },
+ },
+};
+
+/** @return {import('@astrojs/markdoc/config').AstroMarkdocConfig} */
+export default function starlightMarkdoc() {
+ return StarlightMarkdocPreset;
+}
diff --git a/packages/markdoc/package.json b/packages/markdoc/package.json
new file mode 100644
index 00000000..355c776c
--- /dev/null
+++ b/packages/markdoc/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "@astrojs/starlight-markdoc",
+ "version": "0.0.1",
+ "description": "Markdoc preset for the Starlight documentation theme for Astro",
+ "author": "Chris Swithinbank <swithinbank@gmail.com>",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/withastro/starlight",
+ "directory": "packages/markdoc"
+ },
+ "bugs": "https://github.com/withastro/starlight/issues",
+ "homepage": "https://starlight.astro.build",
+ "type": "module",
+ "exports": {
+ ".": "./index.mjs",
+ "./components": "./components.ts"
+ },
+ "devDependencies": {
+ "vitest": "^1.6.0"
+ },
+ "peerDependencies": {
+ "@astrojs/markdoc": "^0.11.4",
+ "@astrojs/starlight": ">=0.23.0"
+ }
+}
diff --git a/packages/starlight/__tests__/basics/navigation-labels.test.ts b/packages/starlight/__tests__/basics/navigation-labels.test.ts
index a85b48cb..5e070d83 100644
--- a/packages/starlight/__tests__/basics/navigation-labels.test.ts
+++ b/packages/starlight/__tests__/basics/navigation-labels.test.ts
@@ -9,7 +9,7 @@ vi.mock('astro:content', async () =>
'environmental-impact.md',
{ title: 'Eco-friendly docs', sidebar: { label: 'Environmental impact' } },
],
- ['guides/authoring-content.md', { title: 'Authoring Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }],
['guides/components.mdx', { title: 'Using components', sidebar: { label: 'Components' } }],
],
})
diff --git a/packages/starlight/__tests__/basics/navigation-order.test.ts b/packages/starlight/__tests__/basics/navigation-order.test.ts
index 6bcd2186..39850e03 100644
--- a/packages/starlight/__tests__/basics/navigation-order.test.ts
+++ b/packages/starlight/__tests__/basics/navigation-order.test.ts
@@ -6,7 +6,7 @@ vi.mock('astro:content', async () =>
docs: [
['index.mdx', { title: 'Home Page' }],
['environmental-impact.md', { title: 'Eco-friendly docs', sidebar: { order: 1 } }],
- ['guides/authoring-content.md', { title: 'Authoring Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }],
['guides/components.mdx', { title: 'Components', sidebar: { order: 0 } }],
],
})
diff --git a/packages/starlight/__tests__/basics/navigation.test.ts b/packages/starlight/__tests__/basics/navigation.test.ts
index 4492c95c..fb4d5110 100644
--- a/packages/starlight/__tests__/basics/navigation.test.ts
+++ b/packages/starlight/__tests__/basics/navigation.test.ts
@@ -6,7 +6,7 @@ vi.mock('astro:content', async () =>
docs: [
['index.mdx', { title: 'Home Page' }],
['environmental-impact.md', { title: 'Eco-friendly docs' }],
- ['guides/authoring-content.md', { title: 'Authoring Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }],
['reference/frontmatter.md', { title: 'Frontmatter Reference', sidebar: { hidden: true } }],
['guides/components.mdx', { title: 'Components' }],
],
diff --git a/packages/starlight/__tests__/basics/pagination-with-base.test.ts b/packages/starlight/__tests__/basics/pagination-with-base.test.ts
index 6619a57b..031964dd 100644
--- a/packages/starlight/__tests__/basics/pagination-with-base.test.ts
+++ b/packages/starlight/__tests__/basics/pagination-with-base.test.ts
@@ -9,7 +9,7 @@ vi.mock('astro:content', async () =>
docs: [
['index.mdx', { title: 'Home Page' }],
['environmental-impact.md', { title: 'Eco-friendly docs' }],
- ['guides/authoring-content.md', { title: 'Authoring Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }],
['guides/components.mdx', { title: 'Components' }],
['reference/frontmatter.md', { title: 'Frontmatter Reference' }],
],
diff --git a/packages/starlight/__tests__/basics/routing.test.ts b/packages/starlight/__tests__/basics/routing.test.ts
index 9805362f..37c3f9b0 100644
--- a/packages/starlight/__tests__/basics/routing.test.ts
+++ b/packages/starlight/__tests__/basics/routing.test.ts
@@ -8,7 +8,7 @@ vi.mock('astro:content', async () =>
docs: [
['404.md', { title: 'Not found' }],
['index.mdx', { title: 'Home page' }],
- ['guides/authoring-content.md', { title: 'Authoring content', draft: true }],
+ ['guides/authoring-content.mdx', { title: 'Authoring content', draft: true }],
],
})
);
@@ -43,7 +43,7 @@ test('routes have locale data added', () => {
});
test('routes includes drafts except in production', async () => {
- expect(routes.find((route) => route.id === 'guides/authoring-content.md')).toBeTruthy();
+ expect(routes.find((route) => route.id === 'guides/authoring-content.mdx')).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
@@ -54,7 +54,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.md')).toBeFalsy();
+ expect(prodRoutes.find((route) => route.id === 'guides/authoring-content.mdx')).toBeFalsy();
vi.unstubAllEnvs();
vi.resetModules();
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 3592f09b..63ac6efd 100644
--- a/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts
+++ b/packages/starlight/__tests__/basics/starlight-page-route-data.test.ts
@@ -15,7 +15,7 @@ vi.mock('astro:content', async () =>
docs: [
['index.mdx', { title: 'Home Page' }],
['getting-started.mdx', { title: 'Getting Started' }],
- ['guides/authoring-content.md', { title: 'Authoring Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Markdown' }],
['guides/components.mdx', { title: 'Components' }],
['reference/frontmatter.md', { title: 'Frontmatter Reference' }],
],
diff --git a/packages/starlight/__tests__/i18n-root-locale/routing.test.ts b/packages/starlight/__tests__/i18n-root-locale/routing.test.ts
index dd5b4505..824eebe3 100644
--- a/packages/starlight/__tests__/i18n-root-locale/routing.test.ts
+++ b/packages/starlight/__tests__/i18n-root-locale/routing.test.ts
@@ -14,7 +14,7 @@ vi.mock('astro:content', async () =>
// @ts-expect-error — Using a slug not present in Starlight docs site
['ar/index.mdx', { title: 'الصفحة الرئيسية' }],
[
- 'guides/authoring-content.md',
+ 'guides/authoring-content.mdx',
{ title: 'Création de contenu en Markdown', lastUpdated: true },
],
],
@@ -61,8 +61,9 @@ 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.md');
- if (!enGuide) throw new Error('Expected to find English fallback route for authoring-content.md');
+ const enGuide = routes.find((route) => route.id === 'en/guides/authoring-content.mdx');
+ if (!enGuide)
+ throw new Error('Expected to find English fallback route for authoring-content.mdx');
expect(enGuide.locale).toBe('en');
expect(enGuide.lang).toBe('en-US');
});
@@ -70,7 +71,7 @@ test('fallback routes use their own locale data', () => {
test('fallback routes use fallback entry last updated dates', () => {
const getNewestCommitDate = vi.spyOn(git, 'getNewestCommitDate');
const route = routes.find((route) => route.entry.id === routes[4]!.id && route.locale === 'en');
- assert(route, 'Expected to find English fallback route for `guides/authoring-content.md`.');
+ assert(route, 'Expected to find English fallback route for `guides/authoring-content.mdx`.');
generateRouteData({
props: {
@@ -82,7 +83,7 @@ test('fallback routes use fallback entry last updated dates', () => {
expect(getNewestCommitDate).toHaveBeenCalledOnce();
expect(getNewestCommitDate.mock.lastCall?.[0]).toMatch(
- /src[/\\]content[/\\]docs[/\\]guides[/\\]authoring-content.md$/
+ /src[/\\]content[/\\]docs[/\\]guides[/\\]authoring-content.mdx$/
// ^ no `en/` prefix
);
diff --git a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts
index e67e558e..d6496d42 100644
--- a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts
+++ b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar-fallback-slug.test.ts
@@ -9,7 +9,7 @@ vi.mock('astro:content', async () =>
['manual-setup.mdx', { title: 'Manual Setup' }],
['environmental-impact.md', { title: 'Eco-friendly docs' }],
['guides/pages.mdx', { title: 'Pages' }],
- ['guides/authoring-content.md', { title: 'Authoring Content in Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Content in Markdown' }],
['resources/plugins.mdx', { title: 'Plugins and Integrations' }],
],
})
diff --git a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts
index dad2b413..f70e4f1b 100644
--- a/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts
+++ b/packages/starlight/__tests__/i18n-sidebar/i18n-sidebar.test.ts
@@ -14,7 +14,7 @@ vi.mock('astro:content', async () =>
['fr/environmental-impact.md', { title: 'Documents écologiques' }],
['guides/pages.mdx', { title: 'Pages' }],
['fr/guides/pages.mdx', { title: 'Pages' }],
- ['guides/authoring-content.md', { title: 'Authoring Content in Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Content in Markdown' }],
['fr/guides/authoring-content.md', { title: 'Création de contenu en Markdown' }],
['resources/plugins.mdx', { title: 'Plugins and Integrations' }],
['fr/resources/plugins.mdx', { title: "Modules d'extension et outils" }],
diff --git a/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts b/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts
index 9489830b..8fda7600 100644
--- a/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts
+++ b/packages/starlight/__tests__/i18n-sidebar/sidebar-internal-link-error.test.ts
@@ -12,7 +12,7 @@ vi.mock('astro:content', async () =>
['fr/environmental-impact.md', { title: 'Documents écologiques' }],
['guides/pages.mdx', { title: 'Pages' }],
['fr/guides/pages.mdx', { title: 'Pages' }],
- ['guides/authoring-content.md', { title: 'Authoring Content in Markdown' }],
+ ['guides/authoring-content.mdx', { title: 'Authoring Content in Markdown' }],
['fr/guides/authoring-content.md', { title: 'Création de contenu en Markdown' }],
['resources/plugins.mdx', { title: 'Plugins and Integrations' }],
['fr/resources/plugins.mdx', { title: "Modules d'extension et outils" }],
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 002b7de5..64e482e7 100644
--- a/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts
+++ b/packages/starlight/__tests__/i18n-single-root-locale/routing.test.ts
@@ -5,7 +5,7 @@ vi.mock('astro:content', async () =>
(await import('../test-utils')).mockedAstroContent({
docs: [
['index.mdx', { title: 'Accueil' }],
- ['guides/authoring-content.md', { title: 'Authoring content' }],
+ ['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' }],
],
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6d304172..c2911151 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -82,6 +82,24 @@ importers:
specifier: ^0.32.5
version: 0.32.6
+ examples/markdoc:
+ dependencies:
+ '@astrojs/markdoc':
+ specifier: ^0.11.4
+ version: 0.11.4(astro@4.15.3)
+ '@astrojs/starlight':
+ specifier: ^0.26.1
+ version: link:../../packages/starlight
+ '@astrojs/starlight-markdoc':
+ specifier: ^0.0.1
+ version: link:../../packages/markdoc
+ astro:
+ specifier: ^4.15.3
+ version: 4.15.3(@types/node@18.16.19)(typescript@5.4.5)
+ sharp:
+ specifier: ^0.32.5
+ version: 0.32.6
+
examples/tailwind:
dependencies:
'@astrojs/starlight':
@@ -128,6 +146,19 @@ importers:
specifier: ^1.3.8
version: 1.3.8
+ packages/markdoc:
+ dependencies:
+ '@astrojs/markdoc':
+ specifier: ^0.11.4
+ version: 0.11.4(astro@4.15.3)
+ '@astrojs/starlight':
+ specifier: '>=0.23.0'
+ version: link:../starlight
+ devDependencies:
+ vitest:
+ specifier: ^1.6.0
+ version: 1.6.0(@types/node@18.16.19)
+
packages/starlight:
dependencies:
'@astrojs/mdx':
@@ -471,6 +502,27 @@ packages:
- typescript
dev: true
+ /@astrojs/markdoc@0.11.4(astro@4.15.3):
+ resolution: {integrity: sha512-6s60ZpsODsEvws57TEpUPXq5Uo+eSHsTVUUAQbbkSL+nQHIy1tR7tI6vbbO2y/VOLj214kATAc18/iRjFp2TbQ==}
+ engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0}
+ peerDependencies:
+ astro: ^3.0.0 || ^4.0.0
+ dependencies:
+ '@astrojs/internal-helpers': 0.4.1
+ '@astrojs/markdown-remark': 5.2.0
+ '@astrojs/prism': 3.1.0
+ '@markdoc/markdoc': 0.4.0
+ astro: 4.15.3(@types/node@18.16.19)(typescript@5.4.5)
+ esbuild: 0.21.5
+ github-slugger: 2.0.0
+ gray-matter: 4.0.3
+ htmlparser2: 9.1.0
+ transitivePeerDependencies:
+ - '@types/react'
+ - react
+ - supports-color
+ dev: false
+
/@astrojs/markdown-remark@5.2.0:
resolution: {integrity: sha512-vWGM24KZXz11jR3JO+oqYU3T2qpuOi4uGivJ9SQLCAI01+vEkHC60YJMRvHPc+hwd60F7euNs1PeOEixIIiNQw==}
dependencies:
@@ -1563,6 +1615,21 @@ packages:
read-yaml-file: 1.1.0
dev: true
+ /@markdoc/markdoc@0.4.0:
+ resolution: {integrity: sha512-fSh4P3Y4E7oaKYc2oNzSIJVPDto7SMzAuQN1Iyx53UxzleA6QzRdNWRxmiPqtVDaDi5dELd2yICoG91csrGrAw==}
+ engines: {node: '>=14.7.0'}
+ peerDependencies:
+ '@types/react': '*'
+ react: '*'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ optionalDependencies:
+ '@types/markdown-it': 12.2.3
+ dev: false
+
/@mdx-js/mdx@3.0.1:
resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==}
dependencies:
@@ -1889,11 +1956,32 @@ packages:
dependencies:
'@types/unist': 3.0.0
+ /@types/linkify-it@5.0.0:
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@types/markdown-it@12.2.3:
+ resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==}
+ requiresBuild: true
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+ dev: false
+ optional: true
+
/@types/mdast@4.0.4:
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
dependencies:
'@types/unist': 3.0.0
+ /@types/mdurl@2.0.0:
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+ requiresBuild: true
+ dev: false
+ optional: true
+
/@types/mdx@2.0.5:
resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==}
dev: false
@@ -3019,18 +3107,15 @@ packages:
domelementtype: 2.3.0
domhandler: 5.0.3
entities: 4.5.0
- dev: true
/domelementtype@2.3.0:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
- dev: true
/domhandler@5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
dependencies:
domelementtype: 2.3.0
- dev: true
/domutils@3.1.0:
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
@@ -3038,7 +3123,6 @@ packages:
dom-serializer: 2.0.0
domelementtype: 2.3.0
domhandler: 5.0.3
- dev: true
/dotenv@8.6.0:
resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==}
@@ -3990,6 +4074,15 @@ packages:
entities: 4.5.0
dev: true
+ /htmlparser2@9.1.0:
+ resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.1.0
+ entities: 4.5.0
+ dev: false
+
/http-cache-semantics@4.1.1:
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}