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/.changeset/thick-boxes-fail.md b/.changeset/thick-boxes-fail.md
new file mode 100644
index 00000000000..18b7aa870b6
--- /dev/null
+++ b/.changeset/thick-boxes-fail.md
@@ -0,0 +1,5 @@
+---
+"@astrojs/starlight": minor
+---
+
+Add i18n support for default aside labels
diff --git a/.gitignore b/.gitignore
index 9f880cb7098..e790eb4de4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,6 @@ pnpm-debug.log*
# Vitest
__coverage__/
+
+# Vercel output
+.vercel
\ No newline at end of file
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/astro.config.mjs b/docs/astro.config.mjs
index 37ecec8bd16..2405fd09de4 100644
--- a/docs/astro.config.mjs
+++ b/docs/astro.config.mjs
@@ -16,7 +16,13 @@ export const locales = {
ru: { label: 'Русский', lang: 'ru' },
};
-const site = 'https://starlight.astro.build/';
+/* https://vercel.com/docs/projects/environment-variables/system-environment-variables#system-environment-variables */
+const VERCEL_PREVIEW_SITE =
+ process.env.VERCEL_ENV !== 'production' &&
+ process.env.VERCEL_URL &&
+ `https://${process.env.VERCEL_URL}`;
+
+const site = VERCEL_PREVIEW_SITE || 'https://starlight.astro.build/';
export default defineConfig({
site,
@@ -175,7 +181,6 @@ export default defineConfig({
autogenerate: { directory: 'reference' },
},
],
- lastUpdated: true,
}),
],
});
diff --git a/docs/public/_headers b/docs/public/_headers
deleted file mode 100644
index aaa51ef2a6e..00000000000
--- a/docs/public/_headers
+++ /dev/null
@@ -1,4 +0,0 @@
-/_astro/*
- Cache-Control: public
- Cache-Control: max-age=604800
- Cache-Control: immutable
diff --git a/docs/public/_redirects b/docs/public/_redirects
deleted file mode 100644
index a7aa40820f3..00000000000
--- a/docs/public/_redirects
+++ /dev/null
@@ -1,3 +0,0 @@
-/ph/* https://astro-houston-ph.pages.dev/ph/:splat 200
-/zh/* /zh-cn/:splat
-/:lang/* /:lang/404/ 404
diff --git a/docs/src/assets/showcase/docs.ethfollow.xyz.png b/docs/src/assets/showcase/docs.ethfollow.xyz.png
new file mode 100644
index 00000000000..c62f659b0b4
Binary files /dev/null and b/docs/src/assets/showcase/docs.ethfollow.xyz.png differ
diff --git a/docs/src/components/showcase-sites.astro b/docs/src/components/showcase-sites.astro
index 6301da3453f..50f606f050f 100644
--- a/docs/src/components/showcase-sites.astro
+++ b/docs/src/components/showcase-sites.astro
@@ -70,4 +70,9 @@ import FluidGrid from './fluid-grid.astro';
href="https://react-awesome-reveal.morello.dev/"
thumbnail="react-awesome-reveal.morello.dev.png"
/>
+
diff --git a/docs/src/content/docs/de/guides/authoring-content.md b/docs/src/content/docs/de/guides/authoring-content.md
index e376af0fa08..88ffcf85b6f 100644
--- a/docs/src/content/docs/de/guides/authoring-content.md
+++ b/docs/src/content/docs/de/guides/authoring-content.md
@@ -207,3 +207,7 @@ Lange, einzeilige Codeblöcke sollten nicht umgebrochen werden. Sie sollten hori
## Andere allgemeine Markdown-Funktionen
Starlight unterstützt alle anderen Markdown-Autorensyntaxen, wie Listen und Tabellen. Einen schnellen Überblick über alle Markdown-Syntaxelemente findest du im [Markdown Cheat Sheet von The Markdown Guide](https://www.markdownguide.org/cheat-sheet/).
+
+## Erweiterte Markdown- und MDX-Konfiguration
+
+Starlight verwendet Astros Markdown- und MDX-Renderer, der auf remark und rehype aufbaut. Du kannst eine Unterstützung für eigene Syntax und Verhalten hinzufügen, indem du `remarkPlugins` oder `rehypePlugins` in deiner Astro-Konfigurationsdatei hinzufügst. Weitere Informationen findest du unter ["Markdown konfigurieren"] (https://docs.astro.build/de/guides/markdown-content/#markdown-konfigurieren) in der Astro-Dokumentation.
diff --git a/docs/src/content/docs/de/guides/i18n.mdx b/docs/src/content/docs/de/guides/i18n.mdx
index 46478e5d25b..40ffae09356 100644
--- a/docs/src/content/docs/de/guides/i18n.mdx
+++ b/docs/src/content/docs/de/guides/i18n.mdx
@@ -143,7 +143,7 @@ Wenn für eine Sprache noch keine Übersetzung verfügbar ist, zeigt Starlight d
Starlight bietet nicht nur übersetzte Inhaltsdateien, sondern auch die Möglichkeit, die Standard-Benutzeroberfläche zu übersetzen (z.B. die Überschrift "Auf dieser Seite" im Inhaltsverzeichnis), so dass deine Leser deine Website vollständig in der ausgewählten Sprache erleben können.
-Englisch, Tschechisch, Französisch, Deutsch, Italienisch, Japanisch, Portugiesisch, Niederländisch, Dänisch, Spanisch, Türkisch, Arabisch, Norwegisch, Farsi, Hebräisch, Chinesisch (vereinfacht), Koreanisch, Indonesisch, Russisch, Schwedisch, Ukrainisch und Vietnamesisch werden standardmäßig übersetzt, und wir freuen uns über [Beiträge zur Aufnahme weiterer Standardsprachen](https://github.com/withastro/starlight/blob/main/CONTRIBUTING.md).
+Englisch, Tschechisch, Französisch, Deutsch, Italienisch, Japanisch, Portugiesisch, Niederländisch, Dänisch, Spanisch, Türkisch, Arabisch, Norwegisch, Farsi, Hebräisch, Chinesisch (vereinfacht), Koreanisch, Indonesisch, Russisch, Schwedisch, Ukrainisch, Vietnamesisch und Galizisch werden standardmäßig übersetzt, und wir freuen uns über [Beiträge zur Aufnahme weiterer Standardsprachen](https://github.com/withastro/starlight/blob/main/CONTRIBUTING.md).
Du kannst Übersetzungen für zusätzliche Sprachen, die du unterstützt, über die `i18n` Datensammlung zur Verfügung stellen - oder unsere Standardbezeichnungen überschreiben.
diff --git a/docs/src/content/docs/de/reference/configuration.mdx b/docs/src/content/docs/de/reference/configuration.mdx
index 306ed7dce4b..abc6711b866 100644
--- a/docs/src/content/docs/de/reference/configuration.mdx
+++ b/docs/src/content/docs/de/reference/configuration.mdx
@@ -181,10 +181,10 @@ sidebar: [
type SidebarItem = {
label: string;
translations?: Record;
+ badge?: string | BadgeConfig;
} & (
| {
link: string;
- badge?: string | BadgeConfig;
attrs?: Record;
}
| { items: SidebarItem[]; collapsed?: boolean }
diff --git a/docs/src/content/docs/es/guides/i18n.mdx b/docs/src/content/docs/es/guides/i18n.mdx
index 0a359b4ef5a..7274ab75045 100644
--- a/docs/src/content/docs/es/guides/i18n.mdx
+++ b/docs/src/content/docs/es/guides/i18n.mdx
@@ -140,7 +140,11 @@ Si no hay una traducción disponible para un idioma, Starlight mostrará a los l
## Traduce la UI de Starlight
-Starlight proporciona de forma predeterminada traducciones para los textos utilizados en la UI al inglés, checo, francés, alemán, italiano, japonés, holandés, portugués, danés, español, turco, árabe, noruego, farsi, hebreo, chino simplificado, coreano, indonesio, ruso, sueco, ucraniano y vietnamita. También damos la bienvenida a [contribuciones para agregar más idiomas predeterminados](https://github.com/withastro/starlight/blob/main/CONTRIBUTING.md).
+Además de alojar archivos de contenido traducidos, Starlight te permite traducir las etiquetas de UI predeterminadas (p. ej. el encabezado "En esta página" en la tabla de contenidos) para que tus lectores puedan experimentar tu sitio completamente en el idioma seleccionado.
+
+Inglés, checo, francés, alemán, italiano, japonés, portugués, holandés, danés, español, turco, árabe, noruego, farsi, hebreo, chino simplificado, coreano, indonesio, ruso, sueco, ucraniano, vietnamita y gallego se proporcionan de forma predeterminada, y damos la bienvenida a [contribuciones para agregar más idiomas predeterminados](https://github.com/withastro/starlight/blob/main/CONTRIBUTING.md).
+
+Puedes proprocionar traducciones para idiomas adicionales, o editar nuestras etiquetas predeterminadas, a través de la colección de datos `i18n`.
1. Configura la colección de datos `i18n` en `src/content/config.ts` si aún no está configurada:
diff --git a/docs/src/content/docs/es/reference/frontmatter.md b/docs/src/content/docs/es/reference/frontmatter.md
index 61a528327ec..b2a8cb6581b 100644
--- a/docs/src/content/docs/es/reference/frontmatter.md
+++ b/docs/src/content/docs/es/reference/frontmatter.md
@@ -111,20 +111,44 @@ hero:
---
```
+Puedes mostrar diferentes versiones de la imagen hero en los modos claro y oscuro.
+
+```md
+---
+hero:
+ image:
+ alt: Un logotipo brillante, de colores brillantes
+ dark: ../../assets/logo-dark.png
+ light: ../../assets/logo-light.png
+---
+```
+
#### `HeroConfig`
```ts
interface HeroConfig {
title?: string;
tagline?: string;
- image?: {
- alt?: string;
- // Ruta relativa a una imagen en tu repositorio.
- file?: string;
- // HTML crudo para usar en el espacio de la imagen.
- // Podría ser una etiqueta ` ` personalizada o un `` en línea.
- html?: string;
- };
+ image?:
+ | {
+ // Ruta relativa a una imagen en tu repositorio.
+ file: string;
+ // Texto alternativo para hacer que la imagen sea accesible a la tecnología de asistencia
+ alt?: string;
+ }
+ | {
+ // Ruta relativa a una imagen en tu repositorio para usar en el modo oscuro.
+ dark: string;
+ // Ruta relativa a una imagen en tu repositorio para usar en el modo claro.
+ light: string;
+ // Texto alternativo para hacer que la imagen sea accesible a la tecnología de asistencia
+ alt?: string;
+ }
+ | {
+ // HTML crudo para usar en el espacio de la imagen.
+ // Podría ser una etiqueta ` ` personalizada o un `` en línea.
+ html: string;
+ };
actions?: Array<{
text: string;
link: string;
diff --git a/docs/src/content/docs/es/reference/overrides.md b/docs/src/content/docs/es/reference/overrides.md
index a787b93a426..055d6f20627 100644
--- a/docs/src/content/docs/es/reference/overrides.md
+++ b/docs/src/content/docs/es/reference/overrides.md
@@ -344,6 +344,8 @@ La implementación predeterminada muestra un título grande, un lema y enlaces d
Componente renderizado alrededor del contenido principal de cada página.
La implementación predeterminada configura estilos básicos para aplicar al contenido de Markdown.
+Los estilos de contenido Markdown también están expuestos en `@astrojs/starlight/style/markdown.css` y están limitados al ámbito de la clase CSS `.sl-markdown-content`.
+
---
### Pie de página
diff --git a/docs/src/content/docs/ko/reference/overrides.md b/docs/src/content/docs/ko/reference/overrides.md
index 2e8334db69a..2aa40464f54 100644
--- a/docs/src/content/docs/ko/reference/overrides.md
+++ b/docs/src/content/docs/ko/reference/overrides.md
@@ -337,6 +337,8 @@ Starlight의 페이지 사이드바는 현재 페이지의 하위 제목을 간
각 페이지의 메인 콘텐츠 주위에 렌더링되는 컴포넌트입니다.
기본적으로 마크다운 콘텐츠에 적용할 기본 스타일을 설정합니다.
+Markdown 콘텐츠 스타일은 `@astrojs/starlight/style/markdown.css`에도 노출되며 `.sl-markdown-content` CSS 클래스로 범위가 지정됩니다.
+
---
### 바닥글
diff --git a/docs/src/content/docs/pt-br/reference/configuration.mdx b/docs/src/content/docs/pt-br/reference/configuration.mdx
index 390cbb3dfd9..df932ec3346 100644
--- a/docs/src/content/docs/pt-br/reference/configuration.mdx
+++ b/docs/src/content/docs/pt-br/reference/configuration.mdx
@@ -183,10 +183,10 @@ sidebar: [
type SidebarItem = {
label: string;
translations?: Record;
+ badge?: string | BadgeConfig;
} & (
| {
link: string;
- badge?: string | BadgeConfig;
attrs?: Record;
}
| { items: SidebarItem[]; collapsed?: boolean }
diff --git a/docs/src/content/docs/pt-br/reference/frontmatter.md b/docs/src/content/docs/pt-br/reference/frontmatter.md
index ed8d73d07e4..1e38930a6df 100644
--- a/docs/src/content/docs/pt-br/reference/frontmatter.md
+++ b/docs/src/content/docs/pt-br/reference/frontmatter.md
@@ -111,20 +111,44 @@ hero:
---
```
+Você pode exibir diferentes versões da imagem hero no modo claro e escuro.
+
+```md
+---
+hero:
+ image:
+ alt: Um logo brilhante e colorido
+ dark: ../../assets/logo-escuro.png
+ light: ../../assets/logo-claro.png
+---
+```
+
#### `HeroConfig`
```ts
interface HeroConfig {
title?: string;
tagline?: string;
- image?: {
- alt?: string;
- // Caminho relativo a uma imagem no seu repositório.
- file?: string;
- // HTML bruto para utilizar no slot de imagem.
- // Pode ser uma tag ` ` customizada ou um `` inline.
- html?: string;
- };
+ image?:
+ | {
+ // Caminho relativo de uma imagem no seu repositório.
+ file: string;
+ // Texto alternativo para tornar a imagem acessível à tecnologia assistiva
+ alt?: string;
+ }
+ | {
+ // Caminho relativo de uma imagem em seu repositório para ser usada no modo escuro.
+ dark: string;
+ // Caminho relativo de uma imagem em seu repositório para ser usada no modo claro.
+ light: string;
+ // Texto alternativo para tornar a imagem acessível à tecnologia assistiva
+ alt?: string;
+ }
+ | {
+ // HTML bruto para utilizar no slot de imagem.
+ // Pode ser uma tag ` ` personalizada ou um `` inline.
+ html: string;
+ };
actions?: Array<{
text: string;
link: string;
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/docs/vercel.json b/docs/vercel.json
new file mode 100644
index 00000000000..e5259e57302
--- /dev/null
+++ b/docs/vercel.json
@@ -0,0 +1,22 @@
+{
+ "$schema": "https://openapi.vercel.sh/vercel.json",
+
+ "routes": [
+ {
+ "src": "^/_astro/(.*)$",
+ "headers": { "cache-control": "public, max-age=31536000, immutable" },
+ "continue": true
+ },
+
+ { "src": "/(ph$|ph/)(.*)", "dest": "https://astro-houston-ph.pages.dev/ph/$2" },
+
+ { "src": "(.*)/([^./]+)$", "dest": "$1/$2/", "status": 301 },
+ { "src": "(.*)/index.html$", "dest": "$1/", "status": 301 },
+
+ { "handle": "filesystem" },
+
+ { "src": "/zh/(.*)", "dest": "/zh-cn/$1", "status": 301 },
+
+ { "src": "/(?[^/]*)/(.*)", "dest": "/$lang/404/", "status": 404 }
+ ]
+}
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..b3f792166ba
--- /dev/null
+++ b/packages/starlight/__tests__/remark-rehype/asides.test.ts
@@ -0,0 +1,144 @@
+import { createMarkdownProcessor } from '@astrojs/markdown-remark';
+import { describe, expect, test } from 'vitest';
+import { starlightAsides } from '../../integrations/asides';
+import { createTranslationSystemFromFs } from '../../utils/translations-fs';
+import { StarlightConfigSchema, type StarlightUserConfig } from '../../utils/user-config';
+
+const starlightConfig = StarlightConfigSchema.parse({
+ title: 'Asides Tests',
+ locales: { en: { label: 'English' }, fr: { label: 'French' } },
+ defaultLocale: 'en',
+} satisfies StarlightUserConfig);
+
+const useTranslations = createTranslationSystemFromFs(
+ starlightConfig,
+ // Using non-existent `_src/` to ignore custom files in this test fixture.
+ { srcDir: new URL('./_src/', import.meta.url) }
+);
+
+const processor = await createMarkdownProcessor({
+ remarkPlugins: [
+ ...starlightAsides({
+ starlightConfig,
+ astroConfig: { root: new URL(import.meta.url), srcDir: new URL('./_src/', import.meta.url) },
+ useTranslations,
+ }),
+ ],
+});
+
+test('generates ', async () => {
+ const res = await processor.render(`
+:::note
+Some text
+:::
+`);
+ expect(res.code).toMatchFileSnapshot('./snapshots/generates-aside.html');
+});
+
+describe('default labels', () => {
+ test.each([
+ ['note', 'Note'],
+ ['tip', 'Tip'],
+ ['caution', 'Caution'],
+ ['danger', 'Danger'],
+ ])('%s has label %s', async (type, label) => {
+ const res = await processor.render(`
+:::${type}
+Some text
+:::
+`);
+ expect(res.code).includes(`aria-label="${label}"`);
+ expect(res.code).includes(` ${label}
`);
+ });
+});
+
+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');
+});
+
+describe('translated labels in French', () => {
+ test.each([
+ ['note', 'Note'],
+ ['tip', 'Astuce'],
+ ['caution', 'Attention'],
+ ['danger', 'Danger'],
+ ])('%s has label %s', async (type, label) => {
+ const res = await processor.render(
+ `
+:::${type}
+Some text
+:::
+`,
+ { fileURL: new URL('./_src/content/docs/fr/index.md', import.meta.url) }
+ );
+ expect(res.code).includes(`aria-label="${label}"`);
+ expect(res.code).includes(`${label}`);
+ });
+});
+
+test('runs without locales config', async () => {
+ const processor = await createMarkdownProcessor({
+ remarkPlugins: [
+ ...starlightAsides({
+ starlightConfig: { locales: undefined },
+ astroConfig: {
+ root: new URL(import.meta.url),
+ srcDir: new URL('./_src/', import.meta.url),
+ },
+ useTranslations,
+ }),
+ ],
+ });
+ const res = await processor.render(':::note\nTest\n::');
+ expect(res.code.includes('aria-label=Note"'));
+});
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 @@
+ Note
Paragraph link .
+See more More.
\ 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/__tests__/test-utils.ts b/packages/starlight/__tests__/test-utils.ts
index b9b0e8991af..96ff4f649e9 100644
--- a/packages/starlight/__tests__/test-utils.ts
+++ b/packages/starlight/__tests__/test-utils.ts
@@ -17,6 +17,7 @@ const frontmatterSchema = docsSchema()({
z.literal('webp'),
z.literal('gif'),
z.literal('svg'),
+ z.literal('avif'),
]),
}),
});
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/index.ts b/packages/starlight/index.ts
index 53ffb2e20cc..01dc25f1e6c 100644
--- a/packages/starlight/index.ts
+++ b/packages/starlight/index.ts
@@ -49,7 +49,13 @@ export default function StarlightIntegration(opts: StarlightUserConfig): AstroIn
plugins: [vitePluginStarlightUserConfig(userConfig, config)],
},
markdown: {
- remarkPlugins: [...starlightAsides()],
+ remarkPlugins: [
+ ...starlightAsides({
+ starlightConfig: userConfig,
+ astroConfig: config,
+ useTranslations,
+ }),
+ ],
rehypePlugins: [rehypeRtlCodeSupport()],
shikiConfig:
// Configure Shiki theme if the user is using the default github-dark theme.
diff --git a/packages/starlight/integrations/asides.ts b/packages/starlight/integrations/asides.ts
index 5d2107ad79e..a97a610ae0a 100644
--- a/packages/starlight/integrations/asides.ts
+++ b/packages/starlight/integrations/asides.ts
@@ -1,10 +1,45 @@
-import type { AstroUserConfig } from 'astro';
+import type { AstroConfig, AstroUserConfig } from 'astro';
import { h as _h, s as _s, type Properties } from 'hastscript';
import type { Paragraph as P, Root } from 'mdast';
import remarkDirective from 'remark-directive';
import type { Plugin, Transformer } from 'unified';
import { remove } from 'unist-util-remove';
import { visit } from 'unist-util-visit';
+import type { StarlightConfig } from '../types';
+import type { createTranslationSystemFromFs } from '../utils/translations-fs';
+
+interface AsidesOptions {
+ starlightConfig: { locales: StarlightConfig['locales'] };
+ astroConfig: { root: AstroConfig['root']; srcDir: AstroConfig['srcDir'] };
+ useTranslations: ReturnType;
+}
+
+function pathToLocale(
+ slug: string | undefined,
+ config: AsidesOptions['starlightConfig']
+): string | undefined {
+ const locales = Object.keys(config.locales || {});
+ const baseSegment = slug?.split('/')[0];
+ if (baseSegment && locales.includes(baseSegment)) return baseSegment;
+ return undefined;
+}
+
+/** get current lang from file full path */
+function getLocaleFromPath(
+ unformattedPath: string | undefined,
+ { starlightConfig, astroConfig }: AsidesOptions
+): string | undefined {
+ const srcDir = new URL(astroConfig.srcDir, astroConfig.root);
+ const docsDir = new URL('content/docs/', srcDir);
+ const path = unformattedPath
+ // Format path to unix style path.
+ ?.replace(/\\/g, '/')
+ // Strip docs path leaving only content collection file ID.
+ // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
+ .replace(docsDir.pathname, '');
+ const locale = pathToLocale(path, starlightConfig);
+ return locale;
+}
/** Hacky function that generates an mdast HTML tree ready for conversion to HTML by rehype. */
function h(el: string, attrs: Properties = {}, children: any[] = []): P {
@@ -50,19 +85,11 @@ function s(el: string, attrs: Properties = {}, children: any[] = []): P {
*
* ```
*/
-function remarkAsides(): Plugin<[], Root> {
+function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
type Variant = 'note' | 'tip' | 'caution' | 'danger';
const variants = new Set(['note', 'tip', 'caution', 'danger']);
const isAsideVariant = (s: string): s is Variant => variants.has(s);
- // TODO: hook these up for i18n once the design for translating strings is ready
- const defaultTitles = {
- note: 'Note',
- tip: 'Tip',
- caution: 'Caution',
- danger: 'Danger',
- };
-
const iconPaths = {
// Information icon
note: [
@@ -95,7 +122,9 @@ function remarkAsides(): Plugin<[], Root> {
],
};
- const transformer: Transformer = (tree) => {
+ const transformer: Transformer = (tree, file) => {
+ const locale = getLocaleFromPath(file.history[0], options);
+ const t = options.useTranslations(locale);
visit(tree, (node, index, parent) => {
if (!parent || index === null || node.type !== 'containerDirective') {
return;
@@ -107,7 +136,7 @@ function remarkAsides(): Plugin<[], Root> {
// its children, but we want to pass it as the title prop to , so
// we iterate over the children, find a directive label, store it for the
// title prop, and remove the paragraph from children.
- let title = defaultTitles[variant];
+ let title = t(`aside.${variant}`);
remove(node, (child): boolean | void => {
if (child.data?.directiveLabel) {
if (
@@ -157,6 +186,6 @@ function remarkAsides(): Plugin<[], Root> {
type RemarkPlugins = NonNullable['remarkPlugins']>;
-export function starlightAsides(): RemarkPlugins {
- return [remarkDirective, remarkAsides()];
+export function starlightAsides(options: AsidesOptions): RemarkPlugins {
+ return [remarkDirective, remarkAsides(options)];
}
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/i18n.ts b/packages/starlight/schemas/i18n.ts
index eb26304d055..d1cd39750b8 100644
--- a/packages/starlight/schemas/i18n.ts
+++ b/packages/starlight/schemas/i18n.ts
@@ -89,6 +89,10 @@ function starlightI18nSchema() {
.describe('Label shown on the “next page” pagination arrow in the page footer.'),
'404.text': z.string().describe('Text shown on Starlight’s default 404 page'),
+ 'aside.tip': z.string().describe('Text shown on the tip aside variant'),
+ 'aside.note': z.string().describe('Text shown on the note aside variant'),
+ 'aside.caution': z.string().describe('Text shown on the warning aside variant'),
+ 'aside.danger': z.string().describe('Text shown on the danger aside variant'),
})
.partial();
}
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/translations/ar.json b/packages/starlight/translations/ar.json
index 15600f0dfdd..64b03ff7bce 100644
--- a/packages/starlight/translations/ar.json
+++ b/packages/starlight/translations/ar.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "اخر تحديث:",
"page.previousLink": "السابق",
"page.nextLink": "التالي",
- "404.text": "الصفحة غير موجودة. تأكد من الرابط أو ابحث بإستعمال شريط البحث."
+ "404.text": "الصفحة غير موجودة. تأكد من الرابط أو ابحث بإستعمال شريط البحث.",
+ "aside.note": "ملحوظة",
+ "aside.tip": "نصيحة",
+ "aside.caution": "تنبيه",
+ "aside.danger": "تحذير"
}
diff --git a/packages/starlight/translations/cs.json b/packages/starlight/translations/cs.json
index d90eeda5fc1..aaca70a7790 100644
--- a/packages/starlight/translations/cs.json
+++ b/packages/starlight/translations/cs.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Poslední aktualizace:",
"page.previousLink": "Předchozí",
"page.nextLink": "Další",
- "404.text": "Stránka nenalezena. Zkontrolujte adresu URL nebo zkuste použít vyhledávací pole."
+ "404.text": "Stránka nenalezena. Zkontrolujte adresu URL nebo zkuste použít vyhledávací pole.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/da.json b/packages/starlight/translations/da.json
index 14903f0a746..b562c0fd19d 100644
--- a/packages/starlight/translations/da.json
+++ b/packages/starlight/translations/da.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Sidst opdateret:",
"page.previousLink": "Forrige",
"page.nextLink": "Næste",
- "404.text": "Siden er ikke fundet. Tjek din URL eller prøv søgelinjen."
+ "404.text": "Siden er ikke fundet. Tjek din URL eller prøv søgelinjen.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/de.json b/packages/starlight/translations/de.json
index da82f791541..9a13711ce53 100644
--- a/packages/starlight/translations/de.json
+++ b/packages/starlight/translations/de.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Zuletzt bearbeitet:",
"page.previousLink": "Vorherige Seite",
"page.nextLink": "Nächste Seite",
- "404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste."
+ "404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste.",
+ "aside.note": "Hinweis",
+ "aside.tip": "Tipp",
+ "aside.caution": "Achtung",
+ "aside.danger": "Gefahr"
}
diff --git a/packages/starlight/translations/en.json b/packages/starlight/translations/en.json
index 5bc396b2c87..5c170f8c0bd 100644
--- a/packages/starlight/translations/en.json
+++ b/packages/starlight/translations/en.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Last updated:",
"page.previousLink": "Previous",
"page.nextLink": "Next",
- "404.text": "Page not found. Check the URL or try using the search bar."
+ "404.text": "Page not found. Check the URL or try using the search bar.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/es.json b/packages/starlight/translations/es.json
index 5cf3200abf7..fd59428b762 100644
--- a/packages/starlight/translations/es.json
+++ b/packages/starlight/translations/es.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Última actualización:",
"page.previousLink": "Página anterior",
"page.nextLink": "Siguiente página",
- "404.text": "Página no encontrada. Verifica la URL o intenta usar la barra de búsqueda."
+ "404.text": "Página no encontrada. Verifica la URL o intenta usar la barra de búsqueda.",
+ "aside.note": "Nota",
+ "aside.tip": "Consejo",
+ "aside.caution": "Precaución",
+ "aside.danger": "Peligro"
}
diff --git a/packages/starlight/translations/fa.json b/packages/starlight/translations/fa.json
index 1e83fed9833..30026dbf4df 100644
--- a/packages/starlight/translations/fa.json
+++ b/packages/starlight/translations/fa.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "آخرین به روز رسانی:",
"page.previousLink": "قبلی",
"page.nextLink": "بعدی",
- "404.text": "صفحه یافت نشد. لطفاً URL را بررسی کنید یا از جستجو استفاده نمایید."
+ "404.text": "صفحه یافت نشد. لطفاً URL را بررسی کنید یا از جستجو استفاده نمایید.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/fr.json b/packages/starlight/translations/fr.json
index bc947080e02..f7acf60c92c 100644
--- a/packages/starlight/translations/fr.json
+++ b/packages/starlight/translations/fr.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Dernière mise à jour :",
"page.previousLink": "Précédent",
"page.nextLink": "Suivant",
- "404.text": "Page non trouvée. Vérifiez l’URL ou essayez d’utiliser la barre de recherche."
+ "404.text": "Page non trouvée. Vérifiez l’URL ou essayez d’utiliser la barre de recherche.",
+ "aside.note": "Note",
+ "aside.tip": "Astuce",
+ "aside.caution": "Attention",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/gl.json b/packages/starlight/translations/gl.json
index c184338d027..808b18f28e3 100644
--- a/packages/starlight/translations/gl.json
+++ b/packages/starlight/translations/gl.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Última actualización:",
"page.previousLink": "Anterior",
"page.nextLink": "Seguinte",
- "404.text": "Paxina non atopada. Comproba a URL ou intenta usar a barra de busca."
+ "404.text": "Paxina non atopada. Comproba a URL ou intenta usar a barra de busca.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/he.json b/packages/starlight/translations/he.json
index e09ccec2ec6..e7152b262c7 100644
--- a/packages/starlight/translations/he.json
+++ b/packages/starlight/translations/he.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "עדכון אחרון:",
"page.previousLink": "הקודם",
"page.nextLink": "הבא",
- "404.text": "הדף לא נמצא. אנא בדקו את כתובת האתר או נסו להשתמש בסרגל החיפוש."
+ "404.text": "הדף לא נמצא. אנא בדקו את כתובת האתר או נסו להשתמש בסרגל החיפוש.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/id.json b/packages/starlight/translations/id.json
index ebd0cf36363..4c57efbf768 100644
--- a/packages/starlight/translations/id.json
+++ b/packages/starlight/translations/id.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Terakhir diperbaharui:",
"page.previousLink": "Sebelumnya",
"page.nextLink": "Selanjutnya",
- "404.text": "Halaman tidak ditemukan. Cek kembali kolom URL atau gunakan fitur pencarian."
+ "404.text": "Halaman tidak ditemukan. Cek kembali kolom URL atau gunakan fitur pencarian.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/it.json b/packages/starlight/translations/it.json
index f0657e89de1..4b41c78b472 100644
--- a/packages/starlight/translations/it.json
+++ b/packages/starlight/translations/it.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Ultimo aggiornamento:",
"page.previousLink": "Indietro",
"page.nextLink": "Avanti",
- "404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca."
+ "404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca.",
+ "aside.note": "Nota",
+ "aside.tip": "Consiglio",
+ "aside.caution": "Attenzione",
+ "aside.danger": "Pericolo"
}
diff --git a/packages/starlight/translations/ja.json b/packages/starlight/translations/ja.json
index 1f199b482cf..f39e219efb6 100644
--- a/packages/starlight/translations/ja.json
+++ b/packages/starlight/translations/ja.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "最終更新日:",
"page.previousLink": "前へ",
"page.nextLink": "次へ",
- "404.text": "ページが見つかりません。 URL を確認するか、検索バーを使用してみてください。"
+ "404.text": "ページが見つかりません。 URL を確認するか、検索バーを使用してみてください。",
+ "aside.note": "ノート",
+ "aside.tip": "ヒント",
+ "aside.caution": "注意",
+ "aside.danger": "危険"
}
diff --git a/packages/starlight/translations/ko.json b/packages/starlight/translations/ko.json
index 5d4c2b27712..a1baf5dfa08 100644
--- a/packages/starlight/translations/ko.json
+++ b/packages/starlight/translations/ko.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "최종 수정:",
"page.previousLink": "이전 페이지",
"page.nextLink": "다음 페이지",
- "404.text": "페이지를 찾을 수 없습니다. URL을 확인하거나 검색창을 사용해보세요."
+ "404.text": "페이지를 찾을 수 없습니다. URL을 확인하거나 검색창을 사용해보세요.",
+ "aside.note": "노트",
+ "aside.tip": "팁",
+ "aside.caution": "주의",
+ "aside.danger": "위험"
}
diff --git a/packages/starlight/translations/nb.json b/packages/starlight/translations/nb.json
index e6abae70ceb..458062f4fd8 100644
--- a/packages/starlight/translations/nb.json
+++ b/packages/starlight/translations/nb.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Sist oppdatert:",
"page.previousLink": "Forrige",
"page.nextLink": "Neste",
- "404.text": "Siden ble ikke funnet. Sjekk URL-en eller prøv å bruke søkefeltet."
+ "404.text": "Siden ble ikke funnet. Sjekk URL-en eller prøv å bruke søkefeltet.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/nl.json b/packages/starlight/translations/nl.json
index 6e485fb6e0d..d5b296aeea4 100644
--- a/packages/starlight/translations/nl.json
+++ b/packages/starlight/translations/nl.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Laatst bewerkt:",
"page.previousLink": "Vorige",
"page.nextLink": "Volgende",
- "404.text": "Pagina niet gevonden. Controleer de URL of probeer de zoekbalk."
+ "404.text": "Pagina niet gevonden. Controleer de URL of probeer de zoekbalk.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/pt.json b/packages/starlight/translations/pt.json
index 2b3790351e9..04e05af49bd 100644
--- a/packages/starlight/translations/pt.json
+++ b/packages/starlight/translations/pt.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Última atualização:",
"page.previousLink": "Anterior",
"page.nextLink": "Próximo",
- "404.text": "Página não encontrada. Verifique o URL ou tente usar a barra de pesquisa."
+ "404.text": "Página não encontrada. Verifique o URL ou tente usar a barra de pesquisa.",
+ "aside.note": "Nota",
+ "aside.tip": "Dica",
+ "aside.caution": "Cuidado",
+ "aside.danger": "Perigo"
}
diff --git a/packages/starlight/translations/ru.json b/packages/starlight/translations/ru.json
index 5d99e44e234..cd39af1fcde 100644
--- a/packages/starlight/translations/ru.json
+++ b/packages/starlight/translations/ru.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Последнее обновление:",
"page.previousLink": "Предыдущая",
"page.nextLink": "Следующая",
- "404.text": "Страница не найдена. Проверьтье URL или используйте поиск по сайту"
+ "404.text": "Страница не найдена. Проверьтье URL или используйте поиск по сайту",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/sv.json b/packages/starlight/translations/sv.json
index ef7c2d35b34..6508667464d 100644
--- a/packages/starlight/translations/sv.json
+++ b/packages/starlight/translations/sv.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Senast uppdaterad:",
"page.previousLink": "Föregående",
"page.nextLink": "Nästa",
- "404.text": "Sidan hittades inte. Kontrollera URL:n eller testa att använda sökfältet."
+ "404.text": "Sidan hittades inte. Kontrollera URL:n eller testa att använda sökfältet.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/tr.json b/packages/starlight/translations/tr.json
index d288a163a24..bd40166977c 100644
--- a/packages/starlight/translations/tr.json
+++ b/packages/starlight/translations/tr.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Son güncelleme:",
"page.previousLink": "Önceki",
"page.nextLink": "Sonraki",
- "404.text": "Sayfa bulunamadı. URL'i kontrol edin ya da arama çubuğunu kullanmayı deneyin."
+ "404.text": "Sayfa bulunamadı. URL'i kontrol edin ya da arama çubuğunu kullanmayı deneyin.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/uk.json b/packages/starlight/translations/uk.json
index 8d21a834788..7a601b81381 100644
--- a/packages/starlight/translations/uk.json
+++ b/packages/starlight/translations/uk.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Останнє оновлення:",
"page.previousLink": "Попередня",
"page.nextLink": "Наступна",
- "404.text": "Сторінку не знайдено. Перевірте URL-адресу або спробуйте скористатися рядком пошуку."
+ "404.text": "Сторінку не знайдено. Перевірте URL-адресу або спробуйте скористатися рядком пошуку.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/vi.json b/packages/starlight/translations/vi.json
index 972a660a242..c1c2ae37179 100644
--- a/packages/starlight/translations/vi.json
+++ b/packages/starlight/translations/vi.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "Cập nhật lần cuối:",
"page.previousLink": "Tiếp",
"page.nextLink": "Trước",
- "404.text": "Không tìm thấy trang. Kiểm tra URL hoặc thử sử dụng thanh tìm kiếm."
+ "404.text": "Không tìm thấy trang. Kiểm tra URL hoặc thử sử dụng thanh tìm kiếm.",
+ "aside.note": "Note",
+ "aside.tip": "Tip",
+ "aside.caution": "Caution",
+ "aside.danger": "Danger"
}
diff --git a/packages/starlight/translations/zh-CN.json b/packages/starlight/translations/zh-CN.json
index 367f63fc6b9..9776faea261 100644
--- a/packages/starlight/translations/zh-CN.json
+++ b/packages/starlight/translations/zh-CN.json
@@ -18,5 +18,9 @@
"page.lastUpdated": "最近更新:",
"page.previousLink": "上一页",
"page.nextLink": "下一页",
- "404.text": "页面未找到。检查 URL 或尝试使用搜索栏。"
+ "404.text": "页面未找到。检查 URL 或尝试使用搜索栏。",
+ "aside.note": "注意",
+ "aside.tip": "提示",
+ "aside.caution": "警告",
+ "aside.danger": "危险"
}
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