diff --git a/.changeset/healthy-rabbits-grab.md b/.changeset/healthy-rabbits-grab.md new file mode 100644 index 00000000000..1bde31b8081 --- /dev/null +++ b/.changeset/healthy-rabbits-grab.md @@ -0,0 +1,5 @@ +--- +'@astrojs/starlight': patch +--- + +Fix sidebar highlighting and navigation buttons for pages with path containing non-ASCII characters 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/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 ?? {} }; }