diff --git a/src/shared/components/Sidebar.tsx b/src/shared/components/Sidebar.tsx
index ed2188055e..45e7af3231 100644
--- a/src/shared/components/Sidebar.tsx
+++ b/src/shared/components/Sidebar.tsx
@@ -431,6 +431,7 @@ export default function Sidebar({
diff --git a/tests/e2e/navigation.spec.ts b/tests/e2e/navigation.spec.ts
index 0f23b14bff..76db5db458 100644
--- a/tests/e2e/navigation.spec.ts
+++ b/tests/e2e/navigation.spec.ts
@@ -1,4 +1,5 @@
import { test, expect } from "@playwright/test";
+import { gotoDashboardRoute } from "./helpers/dashboardAuth";
test.describe("Dashboard Navigation", () => {
test("redirects unauthenticated user to /login", async ({ page }) => {
@@ -10,6 +11,30 @@ test.describe("Dashboard Navigation", () => {
expect(url).toMatch(/\/(login|dashboard)/);
});
+ test("does not prefetch dashboard routes and preserves client navigation", async ({ page }) => {
+ const speculativeRequests: string[] = [];
+
+ page.on("request", (request) => {
+ const headers = request.headers();
+ const isRscPrefetch =
+ headers.rsc === "1" &&
+ (headers["next-router-prefetch"] === "1" ||
+ headers.purpose?.toLowerCase().includes("prefetch") ||
+ headers["sec-purpose"]?.toLowerCase().includes("prefetch"));
+
+ if (isRscPrefetch) speculativeRequests.push(request.url());
+ });
+
+ await gotoDashboardRoute(page, "/home");
+ await expect(page.getByRole("link", { name: /providers/i }).first()).toBeVisible();
+ await page.waitForTimeout(500);
+
+ expect(speculativeRequests).toEqual([]);
+
+ await page.getByRole("link", { name: /providers/i }).first().click();
+ await expect(page).toHaveURL(/\/dashboard\/providers/);
+ });
+
test("login page renders with form elements", async ({ page }) => {
await page.goto("/login");
// Should show some form of authentication UI
diff --git a/tests/unit/sidebar-prefetch-policy-8281.test.ts b/tests/unit/sidebar-prefetch-policy-8281.test.ts
new file mode 100644
index 0000000000..02c170cc71
--- /dev/null
+++ b/tests/unit/sidebar-prefetch-policy-8281.test.ts
@@ -0,0 +1,17 @@
+import assert from "node:assert/strict";
+import { readFile } from "node:fs/promises";
+import test from "node:test";
+
+const SIDEBAR = "src/shared/components/Sidebar.tsx";
+
+test("#8281: dashboard navigation opts out of automatic route prefetch", async () => {
+ const source = await readFile(SIDEBAR, "utf8");
+
+ const internalLink = source.match(//);
+ assert.ok(internalLink, "expected the sidebar's internal navigation Link");
+ assert.match(internalLink[0], /prefetch=\{false\}/);
+
+ const logoLink = source.match(//);
+ assert.ok(logoLink, "expected the sidebar logo home Link");
+ assert.match(logoLink[0], /prefetch=\{false\}/);
+});