From 01a1467b9fd7e2ffd5e503fb520461574dab3348 Mon Sep 17 00:00:00 2001 From: "Charles Graham, SWT" Date: Mon, 11 May 2026 12:40:41 -0700 Subject: [PATCH 1/2] Fix duplicated docs hash links --- src/App.jsx | 5 ++--- src/app-url.js | 29 +++++++++++++++++++++++++++++ src/app-url.test.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/app-url.js create mode 100644 src/app-url.test.js diff --git a/src/App.jsx b/src/App.jsx index a0a408c..12cc7a4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -3,6 +3,7 @@ import { getNavHelper } from "internal-nav-helper"; import { useConnect } from "redux-bundler-hook"; import links from "./nav-links"; import { FaGithub } from "react-icons/fa"; +import { normalizeUrlForHash } from "./app-url"; const version = import.meta.env.PKG_VERSION; const BASE_URL = import.meta.env.BASE_URL; @@ -38,9 +39,7 @@ function App() { return (
{ - // Remove BASE_URL# before it is added again by the navhelper so it can be included in the hrefs for copy url purposes - if (url.includes(`${BASE_URL}#`)) url = url.replace(`${BASE_URL}#`, ""); - doUpdateHash(url); + doUpdateHash(normalizeUrlForHash(url, BASE_URL)); })} > = 0) { + // Internal hash links are already pointing at the target route, so keep + // only the path after "#". + return url.slice(hashIndex + 1) || "/"; + } + + let basePath = "/"; + try { + basePath = new URL(baseUrl, "http://localhost").pathname; + } catch { + basePath = "/"; + } + + const normalizedBasePath = `/${basePath.replace(/^\/+|\/+$/g, "")}/`; + if (normalizedBasePath !== "//" && url.startsWith(normalizedBasePath)) { + // Same-origin links without a hash still need the deploy subpath removed + // before they are handed to doUpdateHash. + return url.slice(normalizedBasePath.length - 1) || "/"; + } + + return url; +} diff --git a/src/app-url.test.js b/src/app-url.test.js new file mode 100644 index 0000000..61ef49a --- /dev/null +++ b/src/app-url.test.js @@ -0,0 +1,31 @@ +import { describe, expect, it } from "vitest"; +import { normalizeUrlForHash } from "./app-url"; + +describe("normalizeUrlForHash", () => { + it("extracts the route from a same-origin hash URL under a base path", () => { + expect( + normalizeUrlForHash( + "/groundwork/#/docs/navigation/sidebar", + "https://usace.github.io/groundwork/", + ), + ).toBe("/docs/navigation/sidebar"); + }); + + it("extracts the route from a root hash URL", () => { + expect( + normalizeUrlForHash( + "/#/docs/navigation/sidebar", + "http://localhost:5173/", + ), + ).toBe("/docs/navigation/sidebar"); + }); + + it("strips the base path from non-hash same-origin URLs", () => { + expect( + normalizeUrlForHash( + "/groundwork/docs", + "https://usace.github.io/groundwork/", + ), + ).toBe("/docs"); + }); +}); From 9eb5b974e84760e28de62bddf4737650d50e91b6 Mon Sep 17 00:00:00 2001 From: "Charles Graham, SWT" Date: Mon, 11 May 2026 14:07:02 -0700 Subject: [PATCH 2/2] Fix docs preview base and home logo link --- lib/composite/header/index.jsx | 5 ++--- vite.config.js | 5 +---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/composite/header/index.jsx b/lib/composite/header/index.jsx index b3917e5..534642d 100644 --- a/lib/composite/header/index.jsx +++ b/lib/composite/header/index.jsx @@ -5,7 +5,6 @@ import { Button } from "../../components/button"; import { GiHamburgerMenu } from "react-icons/gi"; import { useState } from "react"; import gwMerge from "../../gw-merge"; -import Link from "../../components/navigation/link"; const BASE_URL = import.meta.env.BASE_URL; @@ -28,14 +27,14 @@ function Title({ title = "", subtitle = "" }) { function Logo() { return (
- + U.S. Army Corps of Engineers - +
®
diff --git a/vite.config.js b/vite.config.js index a16cba7..58433a4 100644 --- a/vite.config.js +++ b/vite.config.js @@ -40,10 +40,7 @@ export default defineConfig(({ mode }) => { }; } else { console.log("Building preview app", mode); - const base = - mode === "production" - ? "https://usace.github.io/groundwork/" - : "http://localhost:5173/"; + const base = mode === "production" ? "/groundwork/" : "/"; return { plugins: [react()], base: base,