diff --git a/.changeset/humble-friends-clean.md b/.changeset/humble-friends-clean.md
new file mode 100644
index 00000000000..d863d03c17e
--- /dev/null
+++ b/.changeset/humble-friends-clean.md
@@ -0,0 +1,13 @@
+---
+'@astrojs/starlight': minor
+---
+
+Updates internal `@astrojs/mdx`, `@astrojs/markdown-satteri`, and `satteri` dependencies.
+
+⚠️ **BREAKING CHANGE:** The minimum supported version of Astro is now v7.2.5.
+
+Please update Starlight and Astro together:
+
+```sh
+npx @astrojs/upgrade
+```
diff --git a/docs/package.json b/docs/package.json
index ee8b8b3dcee..8efdb5b2949 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -21,7 +21,7 @@
"@astrojs/starlight": "workspace:*",
"@lunariajs/core": "^0.1.1",
"@types/culori": "^4.0.1",
- "astro": "^7.1.6",
+ "astro": "^7.2.5",
"culori": "^4.0.2",
"sharp": "^0.35.3"
},
diff --git a/examples/basics/package.json b/examples/basics/package.json
index 61086fcd9b7..f80e660f888 100644
--- a/examples/basics/package.json
+++ b/examples/basics/package.json
@@ -12,7 +12,7 @@
},
"dependencies": {
"@astrojs/starlight": "^0.41.11",
- "astro": "^7.1.6",
+ "astro": "^7.2.5",
"sharp": "^0.35.3"
}
}
diff --git a/examples/markdoc/package.json b/examples/markdoc/package.json
index c71bd2e111e..4e0b6706699 100644
--- a/examples/markdoc/package.json
+++ b/examples/markdoc/package.json
@@ -14,7 +14,7 @@
"@astrojs/markdoc": "^2.0.6",
"@astrojs/starlight": "^0.41.11",
"@astrojs/starlight-markdoc": "^0.7.0",
- "astro": "^7.1.6",
+ "astro": "^7.2.5",
"sharp": "^0.35.3"
}
}
diff --git a/examples/tailwind/package.json b/examples/tailwind/package.json
index ad78d2ab7e3..8deae6d27e2 100644
--- a/examples/tailwind/package.json
+++ b/examples/tailwind/package.json
@@ -14,7 +14,7 @@
"@astrojs/starlight": "^0.41.11",
"@astrojs/starlight-tailwind": "^5.0.0",
"@tailwindcss/vite": "^4.2.4",
- "astro": "^7.1.6",
+ "astro": "^7.2.5",
"sharp": "^0.35.3",
"tailwindcss": "^4.2.4"
}
diff --git a/package.json b/package.json
index d1b2e08a0f7..b523e622eaa 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"@changesets/cli": "^3.0.1",
"@eslint/js": "^10.0.1",
"@size-limit/file": "^12.1.0",
- "astro": "^7.1.6",
+ "astro": "^7.2.5",
"eslint": "^10.3.0",
"eslint-config-prettier": "^10.1.8",
"globals": "^17.6.0",
diff --git a/packages/file-icons-generator/config.ts b/packages/file-icons-generator/config.ts
index 7563a7ca978..e0bbc0f9b28 100644
--- a/packages/file-icons-generator/config.ts
+++ b/packages/file-icons-generator/config.ts
@@ -1,4 +1,4 @@
-import type { Definitions } from '../starlight/src/user-components/rehype-file-tree';
+import type { Definitions } from '../starlight/src/user-components/file-tree-processor';
export const seti = {
/** The GitHub repository containing the Seti UI theme using the `username/repo` format. */
diff --git a/packages/file-icons-generator/utils/file.ts b/packages/file-icons-generator/utils/file.ts
index eea3edcd610..c4af596cff8 100644
--- a/packages/file-icons-generator/utils/file.ts
+++ b/packages/file-icons-generator/utils/file.ts
@@ -2,7 +2,7 @@ import { spawn } from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
import { starlight } from '../config.ts';
-import type { Definitions } from '../../starlight/src/user-components/rehype-file-tree.ts';
+import type { Definitions } from '../../starlight/src/user-components/file-tree-processor.ts';
const copyrightNotice = `/**
* Based on https://github.com/elviswolcott/seti-icons which
@@ -42,7 +42,7 @@ export async function writeDefinitionsAndSVGs(
) {
const content = `${generatedFileHeader}
-import type { Definitions } from './rehype-file-tree.ts';
+import type { Definitions } from './file-tree-processor.ts';
${copyrightNotice}
export const definitions: Definitions = ${JSON.stringify(definitions)};
diff --git a/packages/file-icons-generator/utils/font.ts b/packages/file-icons-generator/utils/font.ts
index fdf14b89985..7e659975769 100644
--- a/packages/file-icons-generator/utils/font.ts
+++ b/packages/file-icons-generator/utils/font.ts
@@ -1,6 +1,6 @@
import opentype, { type Font, Glyph } from 'opentype.js';
import { seti, starlight } from '../config.ts';
-import type { Definitions } from '../../starlight/src/user-components/rehype-file-tree.ts';
+import type { Definitions } from '../../starlight/src/user-components/file-tree-processor.ts';
import { getFont, getSetiIconName } from './seti.ts';
// This matches the default precision used by the SVGO default preset.
diff --git a/packages/file-icons-generator/utils/seti.ts b/packages/file-icons-generator/utils/seti.ts
index 164b88a8b8f..a687270e53f 100644
--- a/packages/file-icons-generator/utils/seti.ts
+++ b/packages/file-icons-generator/utils/seti.ts
@@ -3,7 +3,7 @@ import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { seti, starlight } from '../config.ts';
-import type { Definitions } from '../../starlight/src/user-components/rehype-file-tree.ts';
+import type { Definitions } from '../../starlight/src/user-components/file-tree-processor.ts';
// https://github.com/jesseweed/seti-ui/blob/master/styles/components/icons/mapping.less
// .icon-set(".bsl", "bsl", @red);
diff --git a/packages/starlight/__e2e__/fixtures/basics/package.json b/packages/starlight/__e2e__/fixtures/basics/package.json
index ca8d4bb11d1..c12304e3606 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": "^7.1.6"
+ "astro": "^7.2.5"
}
}
diff --git a/packages/starlight/__e2e__/fixtures/custom src-dir/package.json b/packages/starlight/__e2e__/fixtures/custom src-dir/package.json
index 8a4f0e2394d..62e30de3f79 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": "^7.1.6"
+ "astro": "^7.2.5"
}
}
diff --git a/packages/starlight/__e2e__/fixtures/git/package.json b/packages/starlight/__e2e__/fixtures/git/package.json
index b739822e8d6..bc616e88a6e 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": "^7.1.6"
+ "astro": "^7.2.5"
}
}
diff --git a/packages/starlight/__e2e__/fixtures/legacy-collections-backwards-compat/package.json b/packages/starlight/__e2e__/fixtures/legacy-collections-backwards-compat/package.json
index 65d218a901a..9b97592c1a4 100644
--- a/packages/starlight/__e2e__/fixtures/legacy-collections-backwards-compat/package.json
+++ b/packages/starlight/__e2e__/fixtures/legacy-collections-backwards-compat/package.json
@@ -4,6 +4,6 @@
"private": true,
"dependencies": {
"@astrojs/starlight": "workspace:*",
- "astro": "^7.1.6"
+ "astro": "^7.2.5"
}
}
diff --git a/packages/starlight/__e2e__/fixtures/no-mdx-optimization/package.json b/packages/starlight/__e2e__/fixtures/no-mdx-optimization/package.json
index 27df071a410..94140f936d0 100644
--- a/packages/starlight/__e2e__/fixtures/no-mdx-optimization/package.json
+++ b/packages/starlight/__e2e__/fixtures/no-mdx-optimization/package.json
@@ -4,6 +4,6 @@
"private": true,
"dependencies": {
"@astrojs/starlight": "workspace:*",
- "astro": "^7.1.6"
+ "astro": "^7.2.5"
}
}
diff --git a/packages/starlight/__e2e__/fixtures/ssr/package.json b/packages/starlight/__e2e__/fixtures/ssr/package.json
index adc96bea694..e509598039f 100644
--- a/packages/starlight/__e2e__/fixtures/ssr/package.json
+++ b/packages/starlight/__e2e__/fixtures/ssr/package.json
@@ -5,6 +5,6 @@
"dependencies": {
"@astrojs/node": "^11.0.0",
"@astrojs/starlight": "workspace:*",
- "astro": "^7.1.6"
+ "astro": "^7.2.5"
}
}
diff --git a/packages/starlight/__tests__/markdown-processor/code-rtl-support.test.ts b/packages/starlight/__tests__/markdown-processor/code-rtl-support.test.ts
index 36988474cc8..697e02d9932 100644
--- a/packages/starlight/__tests__/markdown-processor/code-rtl-support.test.ts
+++ b/packages/starlight/__tests__/markdown-processor/code-rtl-support.test.ts
@@ -34,16 +34,10 @@ describeEachProcessor('code RTL support', (ctx, name) => {
expect(res.code).not.includes('dir="auto"');
});
- test('handles `dir="ltr"` on raw `
` HTML per processor', async () => {
+ test('does not apply `dir="ltr"` on raw `` HTML', async () => {
const res = await ctx().render('manual
', { processor: plain });
- // Since Astro's Sätteri implementation for Shiki returns raw nodes, it, by accident, applies
- // `dir="ltr"` to raw `` blocks even if they're not coming from a plugin generating HAST.
- if (name === 'satteri') {
- expect(res.code).includes('manual
');
- } else {
- expect(res.code).includes('manual
');
- }
+ expect(res.code).includes('manual
');
});
test('does not override an existing `dir` on inline code', async () => {
diff --git a/packages/starlight/__tests__/markdown-processor/rehype-file-tree.test.ts b/packages/starlight/__tests__/markdown-processor/file-tree-processor.test.ts
similarity index 98%
rename from packages/starlight/__tests__/markdown-processor/rehype-file-tree.test.ts
rename to packages/starlight/__tests__/markdown-processor/file-tree-processor.test.ts
index e5401f163ee..25d9215509c 100644
--- a/packages/starlight/__tests__/markdown-processor/rehype-file-tree.test.ts
+++ b/packages/starlight/__tests__/markdown-processor/file-tree-processor.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test, vi } from 'vitest';
-import { processFileTree } from '../../src/user-components/rehype-file-tree';
+import { processFileTree } from '../../src/user-components/file-tree-processor';
import { Icons, type StarlightIcon } from '../../src/components-internals/Icons';
describe('validation', () => {
diff --git a/packages/starlight/__tests__/markdown-processor/plugin-registration.test.ts b/packages/starlight/__tests__/markdown-processor/plugin-registration.test.ts
index a35bc00904d..5da6776e127 100644
--- a/packages/starlight/__tests__/markdown-processor/plugin-registration.test.ts
+++ b/packages/starlight/__tests__/markdown-processor/plugin-registration.test.ts
@@ -66,8 +66,8 @@ describe('registerDirectivesRestoration', () => {
test('registers the mdast restoration plugin on a Sätteri processor', () => {
const processor = satteri();
registerDirectivesRestoration(processor, unifiedIntegration);
- expect(processor.options.mdastPlugins.map((plugin) => plugin.name)).toContain(
- 'starlight-directives-restoration'
+ expect(processor.options.mdastPlugins).toContainEqual(
+ expect.objectContaining({ name: 'starlight-directives-restoration' })
);
});
diff --git a/packages/starlight/__tests__/markdown-processor/rehype-steps.test.ts b/packages/starlight/__tests__/markdown-processor/steps-processor.test.ts
similarity index 97%
rename from packages/starlight/__tests__/markdown-processor/rehype-steps.test.ts
rename to packages/starlight/__tests__/markdown-processor/steps-processor.test.ts
index a6c413f173e..980d7675997 100644
--- a/packages/starlight/__tests__/markdown-processor/rehype-steps.test.ts
+++ b/packages/starlight/__tests__/markdown-processor/steps-processor.test.ts
@@ -1,5 +1,5 @@
import { expect, test } from 'vitest';
-import { processSteps } from '../../src/user-components/rehype-steps';
+import { processSteps } from '../../src/user-components/steps-processor';
test('empty component throws an error', () => {
expect(() => processSteps('')).toThrowErrorMatchingInlineSnapshot(
@@ -63,7 +63,7 @@ test('component with multiple children throws an error', () => {
});
// This tests a workaround added for https://github.com/withastro/astro/issues/15627
-// See rehype-steps.ts for more details.
+// See steps-processor.ts for more details.
test('component with top-level script child is processed successfully', () => {
const { html } = processSteps(
'- List item
'
diff --git a/packages/starlight/__tests__/markdown-processor/rehype-tabs.test.ts b/packages/starlight/__tests__/markdown-processor/tabs-processor.test.ts
similarity index 92%
rename from packages/starlight/__tests__/markdown-processor/rehype-tabs.test.ts
rename to packages/starlight/__tests__/markdown-processor/tabs-processor.test.ts
index 02b2c5d8488..eaf0deda731 100644
--- a/packages/starlight/__tests__/markdown-processor/rehype-tabs.test.ts
+++ b/packages/starlight/__tests__/markdown-processor/tabs-processor.test.ts
@@ -1,21 +1,19 @@
import { expect, test } from 'vitest';
-import { fromHtml } from 'hast-util-from-html';
+import { toHtml } from 'hast-util-to-html';
import { selectAll } from 'hast-util-select';
-import { rehype } from 'rehype';
-import { processPanels, TabItemTagname } from '../../src/user-components/rehype-tabs';
-
-const processor = rehype().data('settings', { fragment: true });
+import { htmlToHast } from 'satteri';
+import { processPanels, TabItemTagname } from '../../src/user-components/tabs-processor';
const TabItem = ({ label, slot, icon }: { label: string; slot: string; icon?: string }) => {
const iconAttr = icon ? ` data-icon="${icon}"` : '';
return `<${TabItemTagname} data-label="${label}"${iconAttr}>${slot}${TabItemTagname}>`;
};
-/** Get an array of HTML strings, one for each `` created by rehype-tabs for each tab item. */
+/** Get an array of HTML strings, one for each `
` created by tabs-processor for each tab item. */
const extractTabPanels = (html: string) => {
- const tree = fromHtml(html, { fragment: true });
+ const tree = htmlToHast(html, { fragment: true });
const tabPanels = selectAll('div[role="tabpanel"]', tree);
- return tabPanels.map((tabPanel) => processor.stringify({ type: 'root', children: [tabPanel] }));
+ return tabPanels.map((tabPanel) => toHtml(tabPanel));
};
test('empty component returns no html or panels', () => {
diff --git a/packages/starlight/__tests__/test-utils.ts b/packages/starlight/__tests__/test-utils.ts
index 34285a20661..f87ef8f21f7 100644
--- a/packages/starlight/__tests__/test-utils.ts
+++ b/packages/starlight/__tests__/test-utils.ts
@@ -62,6 +62,7 @@ const frontmatterSchema = docsSchema()({
z.literal('gif'),
z.literal('svg'),
z.literal('avif'),
+ z.literal('apng'),
]),
}),
});
diff --git a/packages/starlight/package.json b/packages/starlight/package.json
index 41a129c19f1..5f17a199c89 100644
--- a/packages/starlight/package.json
+++ b/packages/starlight/package.json
@@ -48,7 +48,7 @@
},
"peerDependencies": {
"@astrojs/markdown-remark": "^7.2.0",
- "astro": "^7.0.2"
+ "astro": "^7.2.5"
},
"peerDependenciesMeta": {
"@astrojs/markdown-remark": {
@@ -56,27 +56,28 @@
}
},
"devDependencies": {
- "@astrojs/markdown-remark": "^7.2.2",
+ "@astrojs/markdown-remark": "^7.2.4",
"@playwright/test": "^1.61.1",
"@codspeed/vitest-plugin": "^5.7.1",
"@types/node": "^22.19.17",
"@vitest/coverage-v8": "^4.1.5",
- "astro": "^7.1.6",
+ "astro": "^7.2.5",
"linkedom": "^0.18.12",
"vitest": "^4.1.5"
},
"dependencies": {
- "@astrojs/markdown-satteri": "^0.3.5",
- "@astrojs/mdx": "^7.0.5",
+ "@astrojs/markdown-satteri": "^0.3.8",
+ "@astrojs/mdx": "^7.0.8",
"@astrojs/sitemap": "^3.7.3",
"@pagefind/default-ui": "^1.3.0",
- "@types/hast": "^3.0.4",
+ "@types/hast": "^3.0.5",
"@types/js-yaml": "^4.0.9",
"@types/mdast": "^4.0.4",
"astro-expressive-code": "^0.44.0",
"bcp-47": "^2.1.0",
- "hast-util-from-html": "^2.0.3",
+ "hast-util-format": "^1.1.0",
"hast-util-select": "^6.0.4",
+ "hast-util-to-html": "^9.0.5",
"hast-util-to-string": "^3.0.1",
"hastscript": "^9.0.1",
"i18next": "^26.0.7",
@@ -87,10 +88,8 @@
"mdast-util-to-markdown": "^2.1.2",
"mdast-util-to-string": "^4.0.0",
"pagefind": "^1.5.2",
- "rehype": "^13.0.2",
- "rehype-format": "^5.0.1",
"remark-directive": "^4.0.0",
- "satteri": "^0.9.1",
+ "satteri": "^0.10.3",
"ultrahtml": "^1.6.0",
"unified": "^11.0.5",
"unist-util-visit": "^5.1.0",
diff --git a/packages/starlight/src/integrations/markdown-icon.ts b/packages/starlight/src/integrations/markdown-icon.ts
index 9bcf8eb075c..11bfd6c12c8 100644
--- a/packages/starlight/src/integrations/markdown-icon.ts
+++ b/packages/starlight/src/integrations/markdown-icon.ts
@@ -1,5 +1,5 @@
-import type { Element, ElementContent } from 'hast';
-import { fromHtml } from 'hast-util-from-html';
+import type { ElementContent, Root } from 'hast';
+import { htmlToHast } from 'satteri';
import { Icons } from '../components-internals/Icons';
export const headingLinkIconSvgChildrenHtml = Icons['link-alt'];
@@ -7,7 +7,6 @@ export const headingLinkIconChildren = parseIconChildren(headingLinkIconSvgChild
/** Parse a Starlight icon SVG fragment as children of an `