From c2051456affd2662c4cd3d68d94b96079ed51063 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 2 Jun 2026 06:34:32 +0000
Subject: [PATCH 1/4] Initial plan
From 35f362d63281fb978261d3204707ffa1f3020f8f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 2 Jun 2026 06:52:12 +0000
Subject: [PATCH 2/4] Fix broken Edit page link URL normalization
Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com>
---
.../src/components/starlight/EditLink.astro | 33 ++++++++++--
.../tests/unit/edit-link.vitest.test.ts | 53 +++++++++++++++++++
2 files changed, 81 insertions(+), 5 deletions(-)
create mode 100644 src/frontend/tests/unit/edit-link.vitest.test.ts
diff --git a/src/frontend/src/components/starlight/EditLink.astro b/src/frontend/src/components/starlight/EditLink.astro
index 53ef07036..691d5c5df 100644
--- a/src/frontend/src/components/starlight/EditLink.astro
+++ b/src/frontend/src/components/starlight/EditLink.astro
@@ -1,18 +1,41 @@
---
-import DefaultEditLink from '@astrojs/starlight/components/EditLink.astro';
-
import { Icon } from '@astrojs/starlight/components';
const { editUrl } = Astro.locals.starlightRoute;
+const normalizedEditUrl = normalizeGitHubEditUrl(editUrl);
+
+function normalizeGitHubEditUrl(url: URL | string | undefined): string | undefined {
+ if (!url) return undefined;
+
+ const value = url.toString();
+
+ try {
+ const parsed = new URL(value);
+
+ if (parsed.hostname !== 'github.com') return value;
+
+ const segments = parsed.pathname.split('/').filter(Boolean);
+ if (segments.length < 4) return value;
+
+ const [owner, repo, action, ...rest] = segments;
+ if (action === 'edit' || action === 'blob') return value;
+
+ parsed.pathname = `/${owner}/${repo}/blob/${[action, ...rest].join('/')}`;
+ return parsed.toString();
+ } catch {
+ return value;
+ }
+}
---
{
- editUrl && (
+ normalizedEditUrl && (
{Astro.locals.t('footer.translatePage' as any)}
diff --git a/src/frontend/tests/unit/edit-link.vitest.test.ts b/src/frontend/tests/unit/edit-link.vitest.test.ts
new file mode 100644
index 000000000..17d31f991
--- /dev/null
+++ b/src/frontend/tests/unit/edit-link.vitest.test.ts
@@ -0,0 +1,53 @@
+import { describe, expect, it } from 'vitest';
+import EditLink from '../../src/components/starlight/EditLink.astro';
+import { normalizeHtml, renderComponent, type StarlightRoute } from './astro-test-utils';
+
+describe('starlight EditLink', () => {
+ it('normalizes malformed GitHub edit links missing /edit or /blob', async () => {
+ const starlightRoute: StarlightRoute = {
+ editUrl:
+ 'https://github.com/microsoft/aspire.dev/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx',
+ entry: {
+ id: 'whats-new/aspire-13-4',
+ slug: 'whats-new/aspire-13-4',
+ filePath: 'src/content/docs/whats-new/aspire-13-4.mdx',
+ data: {},
+ },
+ };
+
+ const html = normalizeHtml(
+ await renderComponent(EditLink, {
+ locals: { starlightRoute },
+ slots: { default: 'Edit page' },
+ })
+ );
+
+ expect(html).toContain(
+ 'href="https://github.com/microsoft/aspire.dev/blob/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx"'
+ );
+ });
+
+ it('preserves valid GitHub edit links', async () => {
+ const starlightRoute: StarlightRoute = {
+ editUrl:
+ 'https://github.com/microsoft/aspire.dev/edit/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx',
+ entry: {
+ id: 'whats-new/aspire-13-4',
+ slug: 'whats-new/aspire-13-4',
+ filePath: 'src/content/docs/whats-new/aspire-13-4.mdx',
+ data: {},
+ },
+ };
+
+ const html = normalizeHtml(
+ await renderComponent(EditLink, {
+ locals: { starlightRoute },
+ slots: { default: 'Edit page' },
+ })
+ );
+
+ expect(html).toContain(
+ 'href="https://github.com/microsoft/aspire.dev/edit/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx"'
+ );
+ });
+});
From b43b8148829ad44f55ae61feefe56c55ea3d7328 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 2 Jun 2026 06:54:22 +0000
Subject: [PATCH 3/4] Add regression coverage for Edit page URL normalization
Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com>
---
src/frontend/src/components/starlight/EditLink.astro | 2 +-
src/frontend/tests/unit/edit-link.vitest.test.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/frontend/src/components/starlight/EditLink.astro b/src/frontend/src/components/starlight/EditLink.astro
index 691d5c5df..b26d8c5d3 100644
--- a/src/frontend/src/components/starlight/EditLink.astro
+++ b/src/frontend/src/components/starlight/EditLink.astro
@@ -7,7 +7,7 @@ const normalizedEditUrl = normalizeGitHubEditUrl(editUrl);
function normalizeGitHubEditUrl(url: URL | string | undefined): string | undefined {
if (!url) return undefined;
- const value = url.toString();
+ const value = url instanceof URL ? url.toString() : url;
try {
const parsed = new URL(value);
diff --git a/src/frontend/tests/unit/edit-link.vitest.test.ts b/src/frontend/tests/unit/edit-link.vitest.test.ts
index 17d31f991..6b2e301ba 100644
--- a/src/frontend/tests/unit/edit-link.vitest.test.ts
+++ b/src/frontend/tests/unit/edit-link.vitest.test.ts
@@ -3,7 +3,7 @@ import EditLink from '../../src/components/starlight/EditLink.astro';
import { normalizeHtml, renderComponent, type StarlightRoute } from './astro-test-utils';
describe('starlight EditLink', () => {
- it('normalizes malformed GitHub edit links missing /edit or /blob', async () => {
+ it('normalizes malformed GitHub links by inserting /blob/', async () => {
const starlightRoute: StarlightRoute = {
editUrl:
'https://github.com/microsoft/aspire.dev/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx',
From 9da64b47a753a0564493d396049f0158b4c387fd Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 2 Jun 2026 18:14:03 +0000
Subject: [PATCH 4/4] Simplify: revert EditLink normalization, rely on correct
astro config editLink.baseUrl
Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com>
---
.../src/components/starlight/EditLink.astro | 33 ++----------
.../tests/unit/edit-link.vitest.test.ts | 53 -------------------
2 files changed, 5 insertions(+), 81 deletions(-)
delete mode 100644 src/frontend/tests/unit/edit-link.vitest.test.ts
diff --git a/src/frontend/src/components/starlight/EditLink.astro b/src/frontend/src/components/starlight/EditLink.astro
index b26d8c5d3..53ef07036 100644
--- a/src/frontend/src/components/starlight/EditLink.astro
+++ b/src/frontend/src/components/starlight/EditLink.astro
@@ -1,41 +1,18 @@
---
+import DefaultEditLink from '@astrojs/starlight/components/EditLink.astro';
+
import { Icon } from '@astrojs/starlight/components';
const { editUrl } = Astro.locals.starlightRoute;
-const normalizedEditUrl = normalizeGitHubEditUrl(editUrl);
-
-function normalizeGitHubEditUrl(url: URL | string | undefined): string | undefined {
- if (!url) return undefined;
-
- const value = url instanceof URL ? url.toString() : url;
-
- try {
- const parsed = new URL(value);
-
- if (parsed.hostname !== 'github.com') return value;
-
- const segments = parsed.pathname.split('/').filter(Boolean);
- if (segments.length < 4) return value;
-
- const [owner, repo, action, ...rest] = segments;
- if (action === 'edit' || action === 'blob') return value;
-
- parsed.pathname = `/${owner}/${repo}/blob/${[action, ...rest].join('/')}`;
- return parsed.toString();
- } catch {
- return value;
- }
-}
---
{
- normalizedEditUrl && (
+ editUrl && (
{Astro.locals.t('footer.translatePage' as any)}
diff --git a/src/frontend/tests/unit/edit-link.vitest.test.ts b/src/frontend/tests/unit/edit-link.vitest.test.ts
deleted file mode 100644
index 6b2e301ba..000000000
--- a/src/frontend/tests/unit/edit-link.vitest.test.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { describe, expect, it } from 'vitest';
-import EditLink from '../../src/components/starlight/EditLink.astro';
-import { normalizeHtml, renderComponent, type StarlightRoute } from './astro-test-utils';
-
-describe('starlight EditLink', () => {
- it('normalizes malformed GitHub links by inserting /blob/', async () => {
- const starlightRoute: StarlightRoute = {
- editUrl:
- 'https://github.com/microsoft/aspire.dev/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx',
- entry: {
- id: 'whats-new/aspire-13-4',
- slug: 'whats-new/aspire-13-4',
- filePath: 'src/content/docs/whats-new/aspire-13-4.mdx',
- data: {},
- },
- };
-
- const html = normalizeHtml(
- await renderComponent(EditLink, {
- locals: { starlightRoute },
- slots: { default: 'Edit page' },
- })
- );
-
- expect(html).toContain(
- 'href="https://github.com/microsoft/aspire.dev/blob/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx"'
- );
- });
-
- it('preserves valid GitHub edit links', async () => {
- const starlightRoute: StarlightRoute = {
- editUrl:
- 'https://github.com/microsoft/aspire.dev/edit/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx',
- entry: {
- id: 'whats-new/aspire-13-4',
- slug: 'whats-new/aspire-13-4',
- filePath: 'src/content/docs/whats-new/aspire-13-4.mdx',
- data: {},
- },
- };
-
- const html = normalizeHtml(
- await renderComponent(EditLink, {
- locals: { starlightRoute },
- slots: { default: 'Edit page' },
- })
- );
-
- expect(html).toContain(
- 'href="https://github.com/microsoft/aspire.dev/edit/main/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx"'
- );
- });
-});