diff --git a/.changeset/kind-boats-train.md b/.changeset/kind-boats-train.md
new file mode 100644
index 00000000000..83267d880ed
--- /dev/null
+++ b/.changeset/kind-boats-train.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/starlight': patch
+---
+
+Add Slack social link icon
diff --git a/.changeset/polite-colts-turn.md b/.changeset/polite-colts-turn.md
deleted file mode 100644
index 0e46da7f828..00000000000
--- a/.changeset/polite-colts-turn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@astrojs/starlight': patch
----
-
-Internal: fix import issue in translation string loading mechanism
diff --git a/.changeset/quiet-humans-lie.md b/.changeset/quiet-humans-lie.md
deleted file mode 100644
index 08611098bcc..00000000000
--- a/.changeset/quiet-humans-lie.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@astrojs/starlight': patch
----
-
-Fix last updated dates for pages displaying fallback content
diff --git a/.prettierignore b/.prettierignore
index 8b16453a2c2..871a65eb470 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -10,4 +10,7 @@
.changeset
# Files
-pnpm-lock.yaml
\ No newline at end of file
+pnpm-lock.yaml
+
+# Test snapshots
+**/__tests__/**/snapshots
diff --git a/docs/src/content/docs/reference/overrides.md b/docs/src/content/docs/reference/overrides.md
index b3d95be95dd..a9938ad7f0d 100644
--- a/docs/src/content/docs/reference/overrides.md
+++ b/docs/src/content/docs/reference/overrides.md
@@ -342,6 +342,8 @@ The default implementation shows a large title, tagline, and call-to-action link
Component rendered around each page’s main content.
The default implementation sets up basic styles to apply to Markdown content.
+The Markdown content styles are also exposed in `@astrojs/starlight/style/markdown.css` and scoped to the `.sl-markdown-content` CSS class.
+
---
### Footer
diff --git a/examples/basics/package.json b/examples/basics/package.json
index b7a528788f1..926d71d4b80 100644
--- a/examples/basics/package.json
+++ b/examples/basics/package.json
@@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
- "@astrojs/starlight": "^0.12.0",
+ "@astrojs/starlight": "^0.12.1",
"astro": "^3.2.3",
"sharp": "^0.32.5"
}
diff --git a/examples/tailwind/package.json b/examples/tailwind/package.json
index 25851c56001..35727482b5b 100644
--- a/examples/tailwind/package.json
+++ b/examples/tailwind/package.json
@@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
- "@astrojs/starlight": "^0.12.0",
+ "@astrojs/starlight": "^0.12.1",
"@astrojs/starlight-tailwind": "^2.0.1",
"@astrojs/tailwind": "^5.0.0",
"astro": "^3.2.3",
diff --git a/packages/starlight/CHANGELOG.md b/packages/starlight/CHANGELOG.md
index 901e1a813cb..01931083f14 100644
--- a/packages/starlight/CHANGELOG.md
+++ b/packages/starlight/CHANGELOG.md
@@ -1,5 +1,17 @@
# @astrojs/starlight
+## 0.12.1
+
+### Patch Changes
+
+- [#1069](https://github.com/withastro/starlight/pull/1069) [`b86f360`](https://github.com/withastro/starlight/commit/b86f3608f03be9455ec1d5ba11820c9bf601ad1e) Thanks [@Genteure](https://github.com/Genteure)! - Fix sidebar highlighting and navigation buttons for pages with path containing non-ASCII characters
+
+- [#1025](https://github.com/withastro/starlight/pull/1025) [`0d1e75e`](https://github.com/withastro/starlight/commit/0d1e75e17269ddac3eb15b7dfb4480da1bb01c6c) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Internal: fix import issue in translation string loading mechanism
+
+- [#1044](https://github.com/withastro/starlight/pull/1044) [`a5a9754`](https://github.com/withastro/starlight/commit/a5a9754f111b97abfd277d99759e9857aa0fb22b) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fix last updated dates for pages displaying fallback content
+
+- [#1049](https://github.com/withastro/starlight/pull/1049) [`c27495d`](https://github.com/withastro/starlight/commit/c27495da61f9376236519ed3f08a169f245a189c) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Expose Markdown content styles in `@astrojs/starlight/style/markdown.css`
+
## 0.12.0
### Minor Changes
diff --git a/packages/starlight/__tests__/basics/sitemap.test.ts b/packages/starlight/__tests__/basics/sitemap.test.ts
new file mode 100644
index 00000000000..d33820402be
--- /dev/null
+++ b/packages/starlight/__tests__/basics/sitemap.test.ts
@@ -0,0 +1,40 @@
+import { describe, expect, test } from 'vitest';
+import { getSitemapConfig, starlightSitemap } from '../../integrations/sitemap';
+import type { StarlightConfig } from '../../types';
+import { StarlightConfigSchema, type StarlightUserConfig } from '../../utils/user-config';
+
+describe('starlightSitemap', () => {
+ test('returns @astrojs/sitemap integration', () => {
+ const integration = starlightSitemap({} as StarlightConfig);
+ expect(integration.name).toBe('@astrojs/sitemap');
+ });
+});
+
+describe('getSitemapConfig', () => {
+ test('configures i18n config', () => {
+ const config = getSitemapConfig(
+ StarlightConfigSchema.parse({
+ title: 'i18n test',
+ locales: { root: { lang: 'en', label: 'English' }, fr: { label: 'French' } },
+ } satisfies StarlightUserConfig)
+ );
+ expect(config).toMatchInlineSnapshot(`
+ {
+ "i18n": {
+ "defaultLocale": "root",
+ "locales": {
+ "fr": "fr",
+ "root": "en",
+ },
+ },
+ }
+ `);
+ });
+
+ test('no config for monolingual sites', () => {
+ const config = getSitemapConfig(
+ StarlightConfigSchema.parse({ title: 'i18n test' } satisfies StarlightUserConfig)
+ );
+ expect(config).toMatchInlineSnapshot('{}');
+ });
+});
diff --git a/packages/starlight/__tests__/remark-rehype/asides.test.ts b/packages/starlight/__tests__/remark-rehype/asides.test.ts
new file mode 100644
index 00000000000..7d1da5a6781
--- /dev/null
+++ b/packages/starlight/__tests__/remark-rehype/asides.test.ts
@@ -0,0 +1,87 @@
+import { createMarkdownProcessor } from '@astrojs/markdown-remark';
+import { describe, expect, test } from 'vitest';
+import { starlightAsides } from '../../integrations/asides';
+
+const processor = await createMarkdownProcessor({
+ remarkPlugins: [...starlightAsides()],
+});
+
+test('generates
`);
+ });
+});
+
+describe('custom labels', () => {
+ test.each(['note', 'tip', 'caution', 'danger'])('%s with custom label', async (type) => {
+ const label = 'Custom Label';
+ const res = await processor.render(`
+:::${type}[${label}]
+Some text
+:::
+ `);
+ expect(res.code).includes(`aria-label="${label}"`);
+ expect(res.code).includes(`${label}`);
+ });
+});
+
+test('ignores unknown directive variants', async () => {
+ const res = await processor.render(`
+:::unknown
+Some text
+:::
+`);
+ expect(res.code).toMatchInlineSnapshot('""');
+});
+
+test('handles complex children', async () => {
+ const res = await processor.render(`
+:::note
+Paragraph [link](/href/).
+
+
+
+
+See more
+
+More.
+
+
+:::
+`);
+ expect(res.code).toMatchFileSnapshot('./snapshots/handles-complex-children.html');
+});
+
+test('nested asides', async () => {
+ const res = await processor.render(`
+::::note
+Note contents.
+
+:::tip
+Nested tip.
+:::
+
+::::
+`);
+ expect(res.code).toMatchFileSnapshot('./snapshots/nested-asides.html');
+});
diff --git a/packages/starlight/__tests__/remark-rehype/rehype-tabs.test.ts b/packages/starlight/__tests__/remark-rehype/rehype-tabs.test.ts
new file mode 100644
index 00000000000..f1f3b1c3155
--- /dev/null
+++ b/packages/starlight/__tests__/remark-rehype/rehype-tabs.test.ts
@@ -0,0 +1,91 @@
+import { expect, test } from 'vitest';
+import { processPanels, TabItemTagname } from '../../user-components/rehype-tabs';
+
+const TabItem = ({ label, slot }: { label: string; slot: string }) =>
+ `<${TabItemTagname} data-label="${label}">${slot}${TabItemTagname}>`;
+
+/** Get an array of HTML strings, one for each `` created by rehype-tabs for each tab item. */
+const extractSections = (html: string) =>
+ [...html.matchAll(//g)].map(([section]) => section);
+
+test('empty component returns no html or panels', () => {
+ const { panels, html } = processPanels('');
+ expect(html).toEqual('');
+ expect(panels).toEqual([]);
+});
+
+test('non-tab-item content is passed unchanged', () => {
+ const input = 'Random paragraph
';
+ const { panels, html } = processPanels(input);
+ expect(html).toEqual(input);
+ expect(panels).toEqual([]);
+});
+
+test('tab items are processed', () => {
+ const label = 'Test';
+ const slot = 'Random paragraph
';
+ const input = TabItem({ label, slot });
+ const { panels, html } = processPanels(input);
+
+ expect(html).toMatchInlineSnapshot(
+ '""'
+ );
+ expect(panels).toHaveLength(1);
+ expect(panels?.[0]?.label).toBe(label);
+ expect(panels?.[0]?.panelId).toMatchInlineSnapshot('"tab-panel-0"');
+ expect(panels?.[0]?.tabId).toMatchInlineSnapshot('"tab-0"');
+});
+
+test('only first item is not hidden', () => {
+ const labels = ['One', 'Two', 'Three'];
+ const input = labels.map((label) => TabItem({ label, slot: `${label}
` })).join('');
+ const { panels, html } = processPanels(input);
+
+ expect(panels).toHaveLength(3);
+ expect(html).toMatchInlineSnapshot(
+ '""'
+ );
+ const sections = extractSections(html);
+ expect(sections).toMatchInlineSnapshot(`
+ [
+ "",
+ "",
+ "",
+ ]
+ `);
+ expect(sections.map((section) => section.includes('hidden'))).toEqual([false, true, true]);
+});
+
+test('applies incrementing ID and aria-labelledby to each tab item', () => {
+ const labels = ['One', 'Two', 'Three'];
+ const input = labels.map((label) => TabItem({ label, slot: `${label}
` })).join('');
+ const { panels, html } = processPanels(input);
+
+ // IDs are incremented globally to ensure they are unique, so we need to extract from the panel data.
+ const firstTabIdMatches = panels?.[0]?.tabId.match(/^tab-(\d)+$/);
+ const firstTabId = parseInt(firstTabIdMatches![1]!, 10);
+
+ extractSections(html).forEach((section, index) => {
+ expect(section).includes(`id="tab-panel-${firstTabId + index}"`);
+ expect(section).includes(`aria-labelledby="tab-${firstTabId + index}"`);
+ });
+});
+
+test('applies tabindex="0" to tab items without focusable content', () => {
+ const input = [
+ TabItem({ label: 'Focusable', slot: `` }),
+ TabItem({ label: 'Not Focusable', slot: `Plain text
` }),
+ TabItem({
+ label: 'Focusable Nested',
+ slot: ``,
+ }),
+ ].join('');
+ const { html } = processPanels(input);
+ expect(html).toMatchInlineSnapshot(
+ '""'
+ );
+ const sections = extractSections(html);
+ expect(sections[0]).not.includes('tabindex="0"');
+ expect(sections[1]).includes('tabindex="0"');
+ expect(sections[2]).not.includes('tabindex="0"');
+});
diff --git a/packages/starlight/__tests__/remark-rehype/snapshots/generates-aside.html b/packages/starlight/__tests__/remark-rehype/snapshots/generates-aside.html
new file mode 100644
index 00000000000..fb95a152382
--- /dev/null
+++ b/packages/starlight/__tests__/remark-rehype/snapshots/generates-aside.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/starlight/__tests__/remark-rehype/snapshots/handles-complex-children.html b/packages/starlight/__tests__/remark-rehype/snapshots/handles-complex-children.html
new file mode 100644
index 00000000000..8cb4524903b
--- /dev/null
+++ b/packages/starlight/__tests__/remark-rehype/snapshots/handles-complex-children.html
@@ -0,0 +1,2 @@
+
\ No newline at end of file
diff --git a/packages/starlight/__tests__/remark-rehype/snapshots/nested-asides.html b/packages/starlight/__tests__/remark-rehype/snapshots/nested-asides.html
new file mode 100644
index 00000000000..51da5fcc4b3
--- /dev/null
+++ b/packages/starlight/__tests__/remark-rehype/snapshots/nested-asides.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts b/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts
new file mode 100644
index 00000000000..5e280af7ddf
--- /dev/null
+++ b/packages/starlight/__tests__/sidebar/navigation-unicode.test.ts
@@ -0,0 +1,117 @@
+import { describe, expect, test, vi } from 'vitest';
+import { getSidebar } from '../../utils/navigation';
+
+vi.mock('astro:content', async () =>
+ (await import('../test-utils')).mockedAstroContent({
+ docs: [
+ ['index.mdx', { title: 'Home Page' }],
+ ['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/components.mdx', { title: 'Components' }],
+ ],
+ })
+);
+
+describe('getSidebar', () => {
+ test('matches current page when path contains non-ascii characters', () => {
+ expect(getSidebar('/api/v1/%E7%94%A8%E6%88%B7', undefined)).toMatchInlineSnapshot(`
+ [
+ {
+ "attrs": {},
+ "badge": undefined,
+ "href": "/",
+ "isCurrent": false,
+ "label": "Home",
+ "type": "link",
+ },
+ {
+ "badge": undefined,
+ "collapsed": false,
+ "entries": [
+ {
+ "attrs": {},
+ "badge": {
+ "text": "New",
+ "variant": "success",
+ },
+ "href": "/intro/",
+ "isCurrent": false,
+ "label": "Introduction",
+ "type": "link",
+ },
+ {
+ "attrs": {},
+ "badge": {
+ "text": "Deprecated",
+ "variant": "default",
+ },
+ "href": "/next-steps/",
+ "isCurrent": false,
+ "label": "Next Steps",
+ "type": "link",
+ },
+ {
+ "attrs": {
+ "class": "showcase-link",
+ "target": "_blank",
+ },
+ "badge": undefined,
+ "href": "/showcase/",
+ "isCurrent": false,
+ "label": "Showcase",
+ "type": "link",
+ },
+ ],
+ "label": "Start Here",
+ "type": "group",
+ },
+ {
+ "badge": {
+ "text": "Experimental",
+ "variant": "default",
+ },
+ "collapsed": false,
+ "entries": [
+ {
+ "attrs": {},
+ "badge": undefined,
+ "href": "/reference/configuration/",
+ "isCurrent": false,
+ "label": "Config Reference",
+ "type": "link",
+ },
+ {
+ "attrs": {},
+ "badge": undefined,
+ "href": "/reference/frontmatter/",
+ "isCurrent": false,
+ "label": "Frontmatter Reference",
+ "type": "link",
+ },
+ ],
+ "label": "Reference",
+ "type": "group",
+ },
+ {
+ "badge": undefined,
+ "collapsed": false,
+ "entries": [
+ {
+ "attrs": {},
+ "badge": undefined,
+ "href": "/api/v1/用户/",
+ "isCurrent": true,
+ "label": "Path with non-ASCII characters",
+ "type": "link",
+ },
+ ],
+ "label": "API v1",
+ "type": "group",
+ },
+ ]
+ `);
+ });
+});
diff --git a/packages/starlight/components/Icons.ts b/packages/starlight/components/Icons.ts
index f6910737782..6446a5ae8a0 100644
--- a/packages/starlight/components/Icons.ts
+++ b/packages/starlight/components/Icons.ts
@@ -99,4 +99,6 @@ export const Icons = {
'',
patreon:
'',
+ slack:
+ '',
};
diff --git a/packages/starlight/components/MarkdownContent.astro b/packages/starlight/components/MarkdownContent.astro
index ffb0108a6d0..0d40cd47ed2 100644
--- a/packages/starlight/components/MarkdownContent.astro
+++ b/packages/starlight/components/MarkdownContent.astro
@@ -1,127 +1,6 @@
---
import type { Props } from '../props';
+import '../style/markdown.css';
---
-
-
-
+
diff --git a/packages/starlight/integrations/sitemap.ts b/packages/starlight/integrations/sitemap.ts
index ba18af034f1..3b63370ec23 100644
--- a/packages/starlight/integrations/sitemap.ts
+++ b/packages/starlight/integrations/sitemap.ts
@@ -1,19 +1,23 @@
import sitemap, { type SitemapOptions } from '@astrojs/sitemap';
import type { StarlightConfig } from '../types';
-/**
- * A wrapped version of the `@astrojs/sitemap` integration configured based
- * on Starlight i18n config.
- */
-export function starlightSitemap(opts: StarlightConfig) {
+export function getSitemapConfig(opts: StarlightConfig): SitemapOptions {
const sitemapConfig: SitemapOptions = {};
if (opts.isMultilingual) {
sitemapConfig.i18n = {
- defaultLocale: opts.defaultLocale.locale! || 'root',
+ defaultLocale: opts.defaultLocale.locale || 'root',
locales: Object.fromEntries(
Object.entries(opts.locales).map(([locale, config]) => [locale, config?.lang!])
),
};
}
- return sitemap(sitemapConfig);
+ return sitemapConfig;
+}
+
+/**
+ * A wrapped version of the `@astrojs/sitemap` integration configured based
+ * on Starlight i18n config.
+ */
+export function starlightSitemap(opts: StarlightConfig) {
+ return sitemap(getSitemapConfig(opts));
}
diff --git a/packages/starlight/package.json b/packages/starlight/package.json
index 946dc1eb4df..3ff8403eaf0 100644
--- a/packages/starlight/package.json
+++ b/packages/starlight/package.json
@@ -1,6 +1,6 @@
{
"name": "@astrojs/starlight",
- "version": "0.12.0",
+ "version": "0.12.1",
"description": "Build beautiful, high-performance documentation websites with Astro",
"scripts": {
"test": "vitest",
@@ -158,12 +158,14 @@
"./schema": "./schema.ts",
"./types": "./types.ts",
"./index.astro": "./index.astro",
- "./404.astro": "./404.astro"
+ "./404.astro": "./404.astro",
+ "./style/markdown.css": "./style/markdown.css"
},
"peerDependencies": {
"astro": "^3.2.0"
},
"devDependencies": {
+ "@astrojs/markdown-remark": "^3.2.1",
"@types/node": "^18.16.19",
"@vitest/coverage-v8": "^0.33.0",
"astro": "^3.2.3",
diff --git a/packages/starlight/schemas/social.ts b/packages/starlight/schemas/social.ts
index b8aac4b60d0..6882f9f8a36 100644
--- a/packages/starlight/schemas/social.ts
+++ b/packages/starlight/schemas/social.ts
@@ -24,6 +24,7 @@ export const socialLinks = [
'email',
'reddit',
'patreon',
+ 'slack',
] as const;
export const SocialLinksSchema = () =>
@@ -63,6 +64,7 @@ export const SocialLinksSchema = () =>
email: 'Email',
reddit: 'Reddit',
patreon: 'Patreon',
+ slack: 'Slack',
}[key];
labelledLinks[key] = { label, url };
}
diff --git a/packages/starlight/style/markdown.css b/packages/starlight/style/markdown.css
new file mode 100644
index 00000000000..c4f522eb5eb
--- /dev/null
+++ b/packages/starlight/style/markdown.css
@@ -0,0 +1,115 @@
+.sl-markdown-content
+ :not(a, strong, em, del, span, input, code)
+ + :not(a, strong, em, del, span, input, code, :where(.not-content *)) {
+ margin-top: 1.5rem;
+}
+
+/* Headings after non-headings have more spacing. */
+.sl-markdown-content
+ :not(h1, h2, h3, h4, h5, h6)
+ + :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *)) {
+ margin-top: 2.5rem;
+}
+
+.sl-markdown-content li + li:not(:where(.not-content *)),
+.sl-markdown-content dt + dt:not(:where(.not-content *)),
+.sl-markdown-content dt + dd:not(:where(.not-content *)),
+.sl-markdown-content dd + dd:not(:where(.not-content *)) {
+ margin-top: 0.25rem;
+}
+
+.sl-markdown-content
+ li
+ > :last-child:not(li, ul, ol):not(a, strong, em, del, span, input, :where(.not-content *)) {
+ margin-bottom: 1.25rem;
+}
+
+.sl-markdown-content dt:not(:where(.not-content *)) {
+ font-weight: 700;
+}
+.sl-markdown-content dd:not(:where(.not-content *)) {
+ padding-inline-start: 1rem;
+}
+
+.sl-markdown-content :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *)) {
+ color: var(--sl-color-white);
+ line-height: var(--sl-line-height-headings);
+ font-weight: 600;
+}
+
+.sl-markdown-content :is(img, picture, video, canvas, svg, iframe):not(:where(.not-content *)) {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+.sl-markdown-content h1:not(:where(.not-content *)) {
+ font-size: var(--sl-text-h1);
+}
+.sl-markdown-content h2:not(:where(.not-content *)) {
+ font-size: var(--sl-text-h2);
+}
+.sl-markdown-content h3:not(:where(.not-content *)) {
+ font-size: var(--sl-text-h3);
+}
+.sl-markdown-content h4:not(:where(.not-content *)) {
+ font-size: var(--sl-text-h4);
+}
+.sl-markdown-content h5:not(:where(.not-content *)) {
+ font-size: var(--sl-text-h5);
+}
+.sl-markdown-content h6:not(:where(.not-content *)) {
+ font-size: var(--sl-text-h6);
+}
+
+.sl-markdown-content a:not(:where(.not-content *)) {
+ color: var(--sl-color-text-accent);
+}
+.sl-markdown-content a:hover:not(:where(.not-content *)) {
+ color: var(--sl-color-white);
+}
+
+.sl-markdown-content code:not(:where(.not-content *)) {
+ background-color: var(--sl-color-bg-inline-code);
+ margin-block: -0.125rem;
+ padding: 0.125rem 0.375rem;
+ font-size: var(--sl-text-code-sm);
+}
+.sl-markdown-content :is(h1, h2, h3, h4, h5, h6) code {
+ font-size: inherit;
+}
+
+.sl-markdown-content pre:not(:where(.not-content *)) {
+ border: 1px solid var(--sl-color-gray-5);
+ padding: 0.75rem 1rem;
+ font-size: var(--sl-text-code);
+ tab-size: 2;
+}
+
+.sl-markdown-content pre code:not(:where(.not-content *)) {
+ all: unset;
+ font-family: var(--__sl-font-mono);
+}
+
+.sl-markdown-content blockquote:not(:where(.not-content *)) {
+ border-inline-start: 1px solid var(--sl-color-gray-5);
+ padding-inline-start: 1rem;
+}
+
+.sl-markdown-content table:not(:where(.not-content *)) {
+ display: block;
+ overflow: auto;
+ border-collapse: collapse;
+}
+.sl-markdown-content tr:nth-child(2n):not(:where(.not-content *)) {
+ background-color: var(--sl-color-gray-7, var(--sl-color-gray-6));
+}
+.sl-markdown-content :is(th, td):not(:where(.not-content *)) {
+ border: 1px solid var(--sl-color-hairline-light);
+ padding: 0.375rem 0.8125rem;
+}
+
+.sl-markdown-content hr:not(:where(.not-content *)) {
+ border: 0;
+ border-bottom: 1px solid var(--sl-color-hairline);
+}
diff --git a/packages/starlight/utils/navigation.ts b/packages/starlight/utils/navigation.ts
index 5710f553206..1e74932f56e 100644
--- a/packages/starlight/utils/navigation.ts
+++ b/packages/starlight/utils/navigation.ts
@@ -135,7 +135,7 @@ function makeLink(
attrs?: LinkHTMLAttributes
): Link {
if (!isAbsolute(href)) href = pathWithBase(href);
- const isCurrent = href === ensureTrailingSlash(currentPathname);
+ const isCurrent = encodeURI(href) === ensureTrailingSlash(currentPathname);
return { type: 'link', label, href, isCurrent, badge, attrs: attrs ?? {} };
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c6035741368..9946589d184 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -103,7 +103,7 @@ importers:
examples/basics:
dependencies:
'@astrojs/starlight':
- specifier: ^0.12.0
+ specifier: ^0.12.1
version: link:../../packages/starlight
astro:
specifier: ^3.2.3
@@ -115,7 +115,7 @@ importers:
examples/tailwind:
dependencies:
'@astrojs/starlight':
- specifier: ^0.12.0
+ specifier: ^0.12.1
version: link:../../packages/starlight
'@astrojs/starlight-tailwind':
specifier: ^2.0.1
@@ -181,6 +181,9 @@ importers:
specifier: ^5.3.7
version: 5.3.7
devDependencies:
+ '@astrojs/markdown-remark':
+ specifier: ^3.2.1
+ version: 3.2.1(astro@3.2.3)
'@types/node':
specifier: ^18.16.19
version: 18.16.19