From 78cf7a1725682a5fba9a46b755e7823b6e811606 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 16:33:20 +0000 Subject: [PATCH 01/18] scalar fixes --- unified-doc/docusaurus.config.ts | 2 ++ unified-doc/src/theme/Layout/index.tsx | 16 ++++++++- .../src/theme/ScalarDocusaurus/index.tsx | 35 +++++++++++++++++++ unified-doc/src/theme/SearchBar/index.tsx | 10 +++++- 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 unified-doc/src/theme/ScalarDocusaurus/index.tsx diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 592c17cc..31c9ee9e 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -337,6 +337,8 @@ const config: Config = { return { resolve: { alias: { + [path.join(path.dirname(require.resolve('@scalar/docusaurus/dist/index.js')), 'ScalarDocusaurus')]: + path.resolve(__dirname, 'src/theme/ScalarDocusaurus/index.tsx'), '@openziti': path.resolve(__dirname, `${openziti}/docusaurus`), '@openziti_remotes': path.resolve(__dirname, `${openziti}/docusaurus/docs/_remotes`), '@frontdoor': path.resolve(__dirname, `${frontdoor}/docusaurus`), diff --git a/unified-doc/src/theme/Layout/index.tsx b/unified-doc/src/theme/Layout/index.tsx index d9161843..5f1188f8 100644 --- a/unified-doc/src/theme/Layout/index.tsx +++ b/unified-doc/src/theme/Layout/index.tsx @@ -1,6 +1,7 @@ import React, {type ReactNode} from 'react'; import {NetFoundryLayout, NetFoundryLayoutProps, StarUsProps} from '@netfoundry/docusaurus-theme/ui'; import {useLocation} from "@docusaurus/router"; +import Link from '@docusaurus/Link'; import {unifiedFooter} from "@site/src/components/footer"; import {frontdoorFooter} from "@frontdoor/src/components/footer"; import {onpremFooter} from "@selfhosted/src/components/footer"; @@ -24,6 +25,8 @@ const mapFooter = (p: string) => { export default function LayoutWrapper(props: NetFoundryLayoutProps): ReactNode { const {pathname} = useLocation(); + const isApiPage = /\/(api-reference|openapi-reference)$/.test(pathname); + const backUrl = isApiPage ? pathname.split('/').slice(0, -1).join('/') || '/' : '/'; let starProps: StarUsProps | undefined; if (matchPath(pathname, 'openziti')) { starProps = { @@ -39,8 +42,19 @@ export default function LayoutWrapper(props: NetFoundryLayoutProps): ReactNode { const footerToShow = mapFooter(pathname); return ( + {isApiPage && ( +
+ ← Back to docs +
+ )} {props.children}
); } - diff --git a/unified-doc/src/theme/ScalarDocusaurus/index.tsx b/unified-doc/src/theme/ScalarDocusaurus/index.tsx new file mode 100644 index 00000000..dea0e590 --- /dev/null +++ b/unified-doc/src/theme/ScalarDocusaurus/index.tsx @@ -0,0 +1,35 @@ +import Layout from '@theme/Layout'; +import React, { useEffect, useRef } from 'react'; + +declare global { + interface Window { + Scalar?: { + createApiReference(el: Element, config: object): { destroy(): void }; + }; + } +} + +type Props = { + route: { configuration: Record; id: string }; +}; + +export const ScalarDocusaurus = ({ route }: Props) => { + const ref = useRef(null); + + useEffect(() => { + if (!window.Scalar || !ref.current) return; + const instance = window.Scalar.createApiReference(ref.current, { + ...route.configuration, + hideDarkModeToggle: true, + }); + return () => instance?.destroy(); + }, []); + + return ( + +
+ + ); +}; + +export default ScalarDocusaurus; diff --git a/unified-doc/src/theme/SearchBar/index.tsx b/unified-doc/src/theme/SearchBar/index.tsx index 0d5c7a40..732660c6 100644 --- a/unified-doc/src/theme/SearchBar/index.tsx +++ b/unified-doc/src/theme/SearchBar/index.tsx @@ -2,19 +2,27 @@ import React, {useEffect, useState} from "react"; import ReactDOM from "react-dom"; import {DocSearchButton} from "@docsearch/react"; +import {useLocation} from '@docusaurus/router'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import { ProductSearch } from '@netfoundry/docusaurus-theme/ui'; import styles from "./SearchBar.module.css"; import clsx from "clsx"; +// Scalar API reference routes — Ctrl+K belongs to Scalar on these pages. +const isScalarPage = (pathname: string) => + /\/(api-reference|openapi-reference)$/.test(pathname); + export default function SearchBar() { const [open, setOpen] = useState(false); const [mounted, setMounted] = useState(false); const [mouseDownTarget, setMouseDownTarget] = useState(null); + const { pathname } = useLocation(); + const onApiPage = isScalarPage(pathname); useEffect(() => setMounted(true), []); useEffect(() => { + if (onApiPage) return; const onKey = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") { e.preventDefault(); @@ -24,7 +32,7 @@ export default function SearchBar() { }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); - }, []); + }, [onApiPage]); useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]); const { customFields } = useDocusaurusContext().siteConfig; From 0e2da4dd1fd466dbea2092cb530caa829250bac2 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 18:43:50 +0000 Subject: [PATCH 02/18] root fix --- packages/docusaurus-theme/theme/SearchBar/index.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/docusaurus-theme/theme/SearchBar/index.tsx b/packages/docusaurus-theme/theme/SearchBar/index.tsx index a56cabac..833ea051 100644 --- a/packages/docusaurus-theme/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme/theme/SearchBar/index.tsx @@ -4,18 +4,25 @@ import ReactDOM from "react-dom"; import {DocSearchButton as DocSearchButtonOrig} from "@docsearch/react"; const DocSearchButton = DocSearchButtonOrig as React.ComponentType<{onClick: () => void}>; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import {useLocation} from '@docusaurus/router'; import {ProductSearch} from "../../src/components/ProductSearch"; import styles from "./SearchBar.module.css"; import clsx from "clsx"; +const isScalarPage = (pathname: string) => + /\/(api-reference|openapi-reference)$/.test(pathname); + export default function SearchBar() { const [open, setOpen] = useState(false); const [mounted, setMounted] = useState(false); const [mouseDownTarget, setMouseDownTarget] = useState(null); + const { pathname } = useLocation(); + const onApiPage = isScalarPage(pathname); useEffect(() => setMounted(true), []); useEffect(() => { + if (onApiPage) return; const onKey = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") { e.preventDefault(); @@ -25,7 +32,7 @@ export default function SearchBar() { }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); - }, []); + }, [onApiPage]); useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]); const { siteConfig } = useDocusaurusContext(); From 9b1c2e8e86dacb3a2f2930c3a23a3db59e4b10de Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 18:59:22 +0000 Subject: [PATCH 03/18] fix back to docs link --- packages/docusaurus-theme/theme/SearchBar/index.tsx | 2 +- unified-doc/src/theme/Layout/index.tsx | 2 +- unified-doc/src/theme/SearchBar/index.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-theme/theme/SearchBar/index.tsx b/packages/docusaurus-theme/theme/SearchBar/index.tsx index 833ea051..86e1e4c3 100644 --- a/packages/docusaurus-theme/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme/theme/SearchBar/index.tsx @@ -11,7 +11,7 @@ import styles from "./SearchBar.module.css"; import clsx from "clsx"; const isScalarPage = (pathname: string) => - /\/(api-reference|openapi-reference)$/.test(pathname); + /(api-reference|openapi-reference)$/.test(pathname); export default function SearchBar() { const [open, setOpen] = useState(false); diff --git a/unified-doc/src/theme/Layout/index.tsx b/unified-doc/src/theme/Layout/index.tsx index 5f1188f8..3e7c2c67 100644 --- a/unified-doc/src/theme/Layout/index.tsx +++ b/unified-doc/src/theme/Layout/index.tsx @@ -25,7 +25,7 @@ const mapFooter = (p: string) => { export default function LayoutWrapper(props: NetFoundryLayoutProps): ReactNode { const {pathname} = useLocation(); - const isApiPage = /\/(api-reference|openapi-reference)$/.test(pathname); + const isApiPage = /(api-reference|openapi-reference)$/.test(pathname); const backUrl = isApiPage ? pathname.split('/').slice(0, -1).join('/') || '/' : '/'; let starProps: StarUsProps | undefined; if (matchPath(pathname, 'openziti')) { diff --git a/unified-doc/src/theme/SearchBar/index.tsx b/unified-doc/src/theme/SearchBar/index.tsx index 732660c6..20b033d8 100644 --- a/unified-doc/src/theme/SearchBar/index.tsx +++ b/unified-doc/src/theme/SearchBar/index.tsx @@ -11,7 +11,7 @@ import clsx from "clsx"; // Scalar API reference routes — Ctrl+K belongs to Scalar on these pages. const isScalarPage = (pathname: string) => - /\/(api-reference|openapi-reference)$/.test(pathname); + /(api-reference|openapi-reference)$/.test(pathname); export default function SearchBar() { const [open, setOpen] = useState(false); From 81450904d89a7c153aab89ab4be4b1b110d1c67c Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 19:47:54 +0000 Subject: [PATCH 04/18] fixes vercel --- packages/docusaurus-theme/package.json | 2 ++ unified-doc/src/theme/Layout/index.tsx | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-theme/package.json b/packages/docusaurus-theme/package.json index 567a840b..8886542f 100644 --- a/packages/docusaurus-theme/package.json +++ b/packages/docusaurus-theme/package.json @@ -46,6 +46,7 @@ }, "peerDependencies": { "@docusaurus/core": "^3", + "@docusaurus/router": "^3", "@docusaurus/theme-classic": "^3", "@docusaurus/theme-common": "^3", "react": "^18 || ^19", @@ -62,6 +63,7 @@ }, "devDependencies": { "@docusaurus/core": "^3", + "@docusaurus/router": "^3", "@docusaurus/theme-classic": "^3", "@docusaurus/theme-common": "^3", "@docusaurus/types": "^3", diff --git a/unified-doc/src/theme/Layout/index.tsx b/unified-doc/src/theme/Layout/index.tsx index 3e7c2c67..2d61ba17 100644 --- a/unified-doc/src/theme/Layout/index.tsx +++ b/unified-doc/src/theme/Layout/index.tsx @@ -1,7 +1,6 @@ import React, {type ReactNode} from 'react'; import {NetFoundryLayout, NetFoundryLayoutProps, StarUsProps} from '@netfoundry/docusaurus-theme/ui'; import {useLocation} from "@docusaurus/router"; -import Link from '@docusaurus/Link'; import {unifiedFooter} from "@site/src/components/footer"; import {frontdoorFooter} from "@frontdoor/src/components/footer"; import {onpremFooter} from "@selfhosted/src/components/footer"; @@ -26,7 +25,6 @@ const mapFooter = (p: string) => { export default function LayoutWrapper(props: NetFoundryLayoutProps): ReactNode { const {pathname} = useLocation(); const isApiPage = /(api-reference|openapi-reference)$/.test(pathname); - const backUrl = isApiPage ? pathname.split('/').slice(0, -1).join('/') || '/' : '/'; let starProps: StarUsProps | undefined; if (matchPath(pathname, 'openziti')) { starProps = { @@ -51,7 +49,7 @@ export default function LayoutWrapper(props: NetFoundryLayoutProps): ReactNode { borderBottom: '1px solid var(--ifm-hr-border-color)', background: 'var(--ifm-navbar-background-color)', }}> - ← Back to docs +
)} {props.children} From ee2d4192727db583045c3bdf777278f4b0cc390d Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 20:00:45 +0000 Subject: [PATCH 05/18] fix version error --- packages/docusaurus-theme/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/docusaurus-theme/package.json b/packages/docusaurus-theme/package.json index 8886542f..567a840b 100644 --- a/packages/docusaurus-theme/package.json +++ b/packages/docusaurus-theme/package.json @@ -46,7 +46,6 @@ }, "peerDependencies": { "@docusaurus/core": "^3", - "@docusaurus/router": "^3", "@docusaurus/theme-classic": "^3", "@docusaurus/theme-common": "^3", "react": "^18 || ^19", @@ -63,7 +62,6 @@ }, "devDependencies": { "@docusaurus/core": "^3", - "@docusaurus/router": "^3", "@docusaurus/theme-classic": "^3", "@docusaurus/theme-common": "^3", "@docusaurus/types": "^3", From 522cb81d9e90900e50bc2670db1ad11a22c4eba8 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 20:11:35 +0000 Subject: [PATCH 06/18] fix(theme): exclude theme/ from tsc compilation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit theme/ files use @docusaurus/router, a Docusaurus virtual module that only resolves in webpack context — not during standalone tsc. Co-Authored-By: Claude Sonnet 4.6 --- packages/docusaurus-theme/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-theme/tsconfig.json b/packages/docusaurus-theme/tsconfig.json index 56ae35ac..ce688519 100644 --- a/packages/docusaurus-theme/tsconfig.json +++ b/packages/docusaurus-theme/tsconfig.json @@ -16,7 +16,7 @@ "paths": { } }, - "include": ["src/**/*", "theme/**/*"], + "include": ["src/**/*"], "exclude": ["node_modules", "dist"], "watchOptions": { "watchFile": "dynamicPriorityPolling", From 59f3229eec3e5cbfcdeaf74adbeded21cecdf236 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 20:33:42 +0000 Subject: [PATCH 07/18] chore: trigger rebuild From a81ec763f79ab02f42676c9d085ef4bc7edfbc0b Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 20:37:31 +0000 Subject: [PATCH 08/18] chore: trigger rebuild From 30f9da79e71b6b60375b0a48ffd60ba9d0769c6a Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 19 May 2026 16:47:19 -0400 Subject: [PATCH 09/18] add vercel-ignore to scripts folder --- scripts/vercel-ignore.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 scripts/vercel-ignore.sh diff --git a/scripts/vercel-ignore.sh b/scripts/vercel-ignore.sh new file mode 100755 index 00000000..d03dc4c2 --- /dev/null +++ b/scripts/vercel-ignore.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Vercel "Ignored Build Step" helper. +# Exit 0 = skip build, Exit 1 = build. +# Usage: scripts/vercel-ignore.sh e.g. scripts/vercel-ignore.sh packages/ + +set -e + +WATCH_PATH="$1" + +if [ -z "$WATCH_PATH" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# Vercel clones shallow with no 'origin' remote configured. Wire one up. +if ! git remote get-url origin >/dev/null 2>&1; then + git remote add origin "https://github.com/netfoundry/docusaurus-shared" +fi + +git fetch origin main --depth=100 + +if git diff --quiet origin/main...HEAD -- "$WATCH_PATH"; then + echo "No changes under $WATCH_PATH vs origin/main -- skipping build." + exit 0 +else + echo "Changes detected under $WATCH_PATH vs origin/main -- building." + exit 1 +fi From 3bd54561ba3efe195ba303b23dc7b61fc8e75703 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 19 May 2026 16:49:31 -0400 Subject: [PATCH 10/18] trigger build --- scripts/vercel-ignore.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/vercel-ignore.sh b/scripts/vercel-ignore.sh index d03dc4c2..7331b5ae 100755 --- a/scripts/vercel-ignore.sh +++ b/scripts/vercel-ignore.sh @@ -26,3 +26,4 @@ else echo "Changes detected under $WATCH_PATH vs origin/main -- building." exit 1 fi + From 0b30aaa94dde331e026012154368c68dc4c22c65 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 19 May 2026 16:52:44 -0400 Subject: [PATCH 11/18] trigger build --- scripts/vercel-ignore.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/vercel-ignore.sh b/scripts/vercel-ignore.sh index 7331b5ae..81cd16d4 100755 --- a/scripts/vercel-ignore.sh +++ b/scripts/vercel-ignore.sh @@ -27,3 +27,4 @@ else exit 1 fi + From 330df90f3aa4ab36bf1fc54cdb12d7ea79a56e4d Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 21:25:03 +0000 Subject: [PATCH 12/18] fix(theme): declare @docusaurus/router so theme/ compiles to dist/ @docusaurus/router is a webpack virtual module that tsc can't resolve. Adding a module declaration lets tsc compile theme/**/* (which produces dist/theme/ for getThemePath()) without errors. Co-Authored-By: Claude Sonnet 4.6 --- .../docusaurus-theme/src/docusaurus-virtual-modules.d.ts | 6 ++++++ packages/docusaurus-theme/tsconfig.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts diff --git a/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts b/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts new file mode 100644 index 00000000..224ddfa2 --- /dev/null +++ b/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts @@ -0,0 +1,6 @@ +// @docusaurus/router is a Docusaurus virtual module resolved by webpack at +// runtime. This declaration lets tsc compile theme/ files that import from it. +declare module '@docusaurus/router' { + export function useLocation(): { pathname: string; search: string; hash: string; state: unknown }; + export function useHistory(): { push(path: string): void; replace(path: string): void; goBack(): void }; +} diff --git a/packages/docusaurus-theme/tsconfig.json b/packages/docusaurus-theme/tsconfig.json index ce688519..56ae35ac 100644 --- a/packages/docusaurus-theme/tsconfig.json +++ b/packages/docusaurus-theme/tsconfig.json @@ -16,7 +16,7 @@ "paths": { } }, - "include": ["src/**/*"], + "include": ["src/**/*", "theme/**/*"], "exclude": ["node_modules", "dist"], "watchOptions": { "watchFile": "dynamicPriorityPolling", From e9ff70a6d3ca9c0e71c8dc80965e73c391fc8027 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Tue, 19 May 2026 21:37:55 +0000 Subject: [PATCH 13/18] feat(theme): move ScalarDocusaurus to theme, auto-inject webpack alias The ScalarDocusaurus override (which calls instance.destroy() on unmount to prevent Ctrl+K listener leaks) now lives in the theme package and is applied automatically to any site that has @scalar/docusaurus installed, via a configureWebpack hook. Sites no longer need their own copy of the component or a manual webpack alias. Also declare @docusaurus/router and @theme/Layout as virtual modules so tsc can compile theme/ files without errors. Bumps to 0.12.3. Co-Authored-By: Claude Sonnet 4.6 --- packages/docusaurus-theme/package.json | 2 +- .../src/docusaurus-virtual-modules.d.ts | 11 +++++++++-- packages/docusaurus-theme/src/index.ts | 19 +++++++++++++++++++ .../theme/ScalarDocusaurus/index.tsx | 0 unified-doc/docusaurus.config.ts | 2 -- 5 files changed, 29 insertions(+), 5 deletions(-) rename {unified-doc/src => packages/docusaurus-theme}/theme/ScalarDocusaurus/index.tsx (100%) diff --git a/packages/docusaurus-theme/package.json b/packages/docusaurus-theme/package.json index 567a840b..495f951d 100644 --- a/packages/docusaurus-theme/package.json +++ b/packages/docusaurus-theme/package.json @@ -1,6 +1,6 @@ { "name": "@netfoundry/docusaurus-theme", - "version": "0.12.2", + "version": "0.12.3", "description": "NetFoundry Docusaurus theme with shared layout, footer, and styling", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts b/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts index 224ddfa2..8b958937 100644 --- a/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts +++ b/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts @@ -1,6 +1,13 @@ -// @docusaurus/router is a Docusaurus virtual module resolved by webpack at -// runtime. This declaration lets tsc compile theme/ files that import from it. +// These are Docusaurus virtual modules resolved by webpack at runtime. +// Declarations here let tsc compile theme/ files that import from them. + declare module '@docusaurus/router' { export function useLocation(): { pathname: string; search: string; hash: string; state: unknown }; export function useHistory(): { push(path: string): void; replace(path: string): void; goBack(): void }; } + +declare module '@theme/Layout' { + import type { ReactNode } from 'react'; + export interface Props { children?: ReactNode } + export default function Layout(props: Props): ReactNode; +} diff --git a/packages/docusaurus-theme/src/index.ts b/packages/docusaurus-theme/src/index.ts index 5b99f3dc..f9b4ad21 100644 --- a/packages/docusaurus-theme/src/index.ts +++ b/packages/docusaurus-theme/src/index.ts @@ -19,6 +19,25 @@ export default function themeNetFoundry( return path.resolve(__dirname, '../theme'); }, + // If @scalar/docusaurus is installed, redirect its built-in ScalarDocusaurus + // component to our version which calls instance.destroy() on unmount, + // preventing its global Ctrl+K listener from leaking to non-API pages. + configureWebpack() { + try { + const scalarDist = path.dirname(require.resolve('@scalar/docusaurus/dist/index.js')); + return { + resolve: { + alias: { + [path.join(scalarDist, 'ScalarDocusaurus')]: + path.resolve(__dirname, '../theme/ScalarDocusaurus/index.js'), + }, + }, + }; + } catch { + return {}; + } + }, + // Automatically inject CSS getClientModules() { const modules: string[] = [ diff --git a/unified-doc/src/theme/ScalarDocusaurus/index.tsx b/packages/docusaurus-theme/theme/ScalarDocusaurus/index.tsx similarity index 100% rename from unified-doc/src/theme/ScalarDocusaurus/index.tsx rename to packages/docusaurus-theme/theme/ScalarDocusaurus/index.tsx diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 31c9ee9e..592c17cc 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -337,8 +337,6 @@ const config: Config = { return { resolve: { alias: { - [path.join(path.dirname(require.resolve('@scalar/docusaurus/dist/index.js')), 'ScalarDocusaurus')]: - path.resolve(__dirname, 'src/theme/ScalarDocusaurus/index.tsx'), '@openziti': path.resolve(__dirname, `${openziti}/docusaurus`), '@openziti_remotes': path.resolve(__dirname, `${openziti}/docusaurus/docs/_remotes`), '@frontdoor': path.resolve(__dirname, `${frontdoor}/docusaurus`), From 8507b8ef170e87a718b13a17ce7ad95b5902adae Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 20 May 2026 16:57:24 +0000 Subject: [PATCH 14/18] fix: set Scalar searchHotKey to 'i' to avoid Ctrl+K conflict Co-Authored-By: Claude Sonnet 4.6 --- unified-doc/docusaurus.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 592c17cc..66bbfc51 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -446,28 +446,28 @@ const config: Config = { label: 'Edge Client API reference', route: `/${routeBase('openziti')}/reference/developer/api/edge-client-api-reference`, showNavLink: false, - configuration: {url: 'https://get.openziti.io/spec/client.yml', hideClientButton: true, hideTestRequestButton: true}, + configuration: {url: 'https://get.openziti.io/spec/client.yml', hideClientButton: true, hideTestRequestButton: true, searchHotKey: 'i'}, } as ScalarOptions], build(BUILD_FLAGS.OPENZITI) && ['@scalar/docusaurus', { id: 'edge-management', label: 'Edge Management API reference', route: `/${routeBase('openziti')}/reference/developer/api/edge-management-api-reference`, showNavLink: false, - configuration: {url: 'https://get.openziti.io/spec/management.yml', hideClientButton: true, hideTestRequestButton: true}, + configuration: {url: 'https://get.openziti.io/spec/management.yml', hideClientButton: true, hideTestRequestButton: true, searchHotKey: 'i'}, } as ScalarOptions], build(BUILD_FLAGS.PLATFORM) && ['@scalar/docusaurus', { id: 'platform-api', label: 'API reference', route: `/${routeBase('platform')}/api-guides/openapi-reference`, showNavLink: false, - configuration: {url: `${docsBase}console-api-spec.yaml`, hideClientButton: true, hideTestRequestButton: true}, + configuration: {url: `${docsBase}console-api-spec.yaml`, hideClientButton: true, hideTestRequestButton: true, searchHotKey: 'i'}, } as ScalarOptions], build(BUILD_FLAGS.FRONTDOOR) && ['@scalar/docusaurus', { id: 'frontdoor-api', label: 'API reference', route: `/${routeBase('frontdoor')}/reference/api-reference`, showNavLink: false, - configuration: {url: `${docsBase}frontdoor-api-spec.yaml`, hideClientButton: true, hideTestRequestButton: true}, + configuration: {url: `${docsBase}frontdoor-api-spec.yaml`, hideClientButton: true, hideTestRequestButton: true, searchHotKey: 'i'}, } as ScalarOptions], ].filter(Boolean), themeConfig: { From ee4b7206e0463c8d9e36e66f2ea772599adca605 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 20 May 2026 19:36:48 +0000 Subject: [PATCH 15/18] revert: remove theme SearchBar guard and ScalarDocusaurus override searchHotKey: 'i' in each site's Scalar config resolves the Ctrl+K conflict at the source. The SearchBar onApiPage guard and ScalarDocusaurus destroy() override are no longer needed. Co-Authored-By: Claude Sonnet 4.6 --- packages/docusaurus-theme/package.json | 2 +- .../src/docusaurus-virtual-modules.d.ts | 13 ------- packages/docusaurus-theme/src/index.ts | 19 ---------- .../theme/ScalarDocusaurus/index.tsx | 35 ------------------- .../theme/SearchBar/index.tsx | 9 +---- unified-doc/src/theme/SearchBar/index.tsx | 10 +----- 6 files changed, 3 insertions(+), 85 deletions(-) delete mode 100644 packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts delete mode 100644 packages/docusaurus-theme/theme/ScalarDocusaurus/index.tsx diff --git a/packages/docusaurus-theme/package.json b/packages/docusaurus-theme/package.json index 495f951d..567a840b 100644 --- a/packages/docusaurus-theme/package.json +++ b/packages/docusaurus-theme/package.json @@ -1,6 +1,6 @@ { "name": "@netfoundry/docusaurus-theme", - "version": "0.12.3", + "version": "0.12.2", "description": "NetFoundry Docusaurus theme with shared layout, footer, and styling", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts b/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts deleted file mode 100644 index 8b958937..00000000 --- a/packages/docusaurus-theme/src/docusaurus-virtual-modules.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -// These are Docusaurus virtual modules resolved by webpack at runtime. -// Declarations here let tsc compile theme/ files that import from them. - -declare module '@docusaurus/router' { - export function useLocation(): { pathname: string; search: string; hash: string; state: unknown }; - export function useHistory(): { push(path: string): void; replace(path: string): void; goBack(): void }; -} - -declare module '@theme/Layout' { - import type { ReactNode } from 'react'; - export interface Props { children?: ReactNode } - export default function Layout(props: Props): ReactNode; -} diff --git a/packages/docusaurus-theme/src/index.ts b/packages/docusaurus-theme/src/index.ts index f9b4ad21..5b99f3dc 100644 --- a/packages/docusaurus-theme/src/index.ts +++ b/packages/docusaurus-theme/src/index.ts @@ -19,25 +19,6 @@ export default function themeNetFoundry( return path.resolve(__dirname, '../theme'); }, - // If @scalar/docusaurus is installed, redirect its built-in ScalarDocusaurus - // component to our version which calls instance.destroy() on unmount, - // preventing its global Ctrl+K listener from leaking to non-API pages. - configureWebpack() { - try { - const scalarDist = path.dirname(require.resolve('@scalar/docusaurus/dist/index.js')); - return { - resolve: { - alias: { - [path.join(scalarDist, 'ScalarDocusaurus')]: - path.resolve(__dirname, '../theme/ScalarDocusaurus/index.js'), - }, - }, - }; - } catch { - return {}; - } - }, - // Automatically inject CSS getClientModules() { const modules: string[] = [ diff --git a/packages/docusaurus-theme/theme/ScalarDocusaurus/index.tsx b/packages/docusaurus-theme/theme/ScalarDocusaurus/index.tsx deleted file mode 100644 index dea0e590..00000000 --- a/packages/docusaurus-theme/theme/ScalarDocusaurus/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import Layout from '@theme/Layout'; -import React, { useEffect, useRef } from 'react'; - -declare global { - interface Window { - Scalar?: { - createApiReference(el: Element, config: object): { destroy(): void }; - }; - } -} - -type Props = { - route: { configuration: Record; id: string }; -}; - -export const ScalarDocusaurus = ({ route }: Props) => { - const ref = useRef(null); - - useEffect(() => { - if (!window.Scalar || !ref.current) return; - const instance = window.Scalar.createApiReference(ref.current, { - ...route.configuration, - hideDarkModeToggle: true, - }); - return () => instance?.destroy(); - }, []); - - return ( - -
- - ); -}; - -export default ScalarDocusaurus; diff --git a/packages/docusaurus-theme/theme/SearchBar/index.tsx b/packages/docusaurus-theme/theme/SearchBar/index.tsx index 86e1e4c3..a56cabac 100644 --- a/packages/docusaurus-theme/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme/theme/SearchBar/index.tsx @@ -4,25 +4,18 @@ import ReactDOM from "react-dom"; import {DocSearchButton as DocSearchButtonOrig} from "@docsearch/react"; const DocSearchButton = DocSearchButtonOrig as React.ComponentType<{onClick: () => void}>; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import {useLocation} from '@docusaurus/router'; import {ProductSearch} from "../../src/components/ProductSearch"; import styles from "./SearchBar.module.css"; import clsx from "clsx"; -const isScalarPage = (pathname: string) => - /(api-reference|openapi-reference)$/.test(pathname); - export default function SearchBar() { const [open, setOpen] = useState(false); const [mounted, setMounted] = useState(false); const [mouseDownTarget, setMouseDownTarget] = useState(null); - const { pathname } = useLocation(); - const onApiPage = isScalarPage(pathname); useEffect(() => setMounted(true), []); useEffect(() => { - if (onApiPage) return; const onKey = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") { e.preventDefault(); @@ -32,7 +25,7 @@ export default function SearchBar() { }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); - }, [onApiPage]); + }, []); useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]); const { siteConfig } = useDocusaurusContext(); diff --git a/unified-doc/src/theme/SearchBar/index.tsx b/unified-doc/src/theme/SearchBar/index.tsx index 20b033d8..0d5c7a40 100644 --- a/unified-doc/src/theme/SearchBar/index.tsx +++ b/unified-doc/src/theme/SearchBar/index.tsx @@ -2,27 +2,19 @@ import React, {useEffect, useState} from "react"; import ReactDOM from "react-dom"; import {DocSearchButton} from "@docsearch/react"; -import {useLocation} from '@docusaurus/router'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import { ProductSearch } from '@netfoundry/docusaurus-theme/ui'; import styles from "./SearchBar.module.css"; import clsx from "clsx"; -// Scalar API reference routes — Ctrl+K belongs to Scalar on these pages. -const isScalarPage = (pathname: string) => - /(api-reference|openapi-reference)$/.test(pathname); - export default function SearchBar() { const [open, setOpen] = useState(false); const [mounted, setMounted] = useState(false); const [mouseDownTarget, setMouseDownTarget] = useState(null); - const { pathname } = useLocation(); - const onApiPage = isScalarPage(pathname); useEffect(() => setMounted(true), []); useEffect(() => { - if (onApiPage) return; const onKey = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") { e.preventDefault(); @@ -32,7 +24,7 @@ export default function SearchBar() { }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); - }, [onApiPage]); + }, []); useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]); const { customFields } = useDocusaurusContext().siteConfig; From 05d765406ace03ee0c470a3f82a7c3e5c5febd91 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 20 May 2026 19:58:50 +0000 Subject: [PATCH 16/18] fix: update broken openziti intro links learn/introduction was removed in the Diataxis restructure; update links in unified-doc home and docs index pages to point to /intro. Co-Authored-By: Claude Sonnet 4.6 --- unified-doc/src/pages/docs/index.tsx | 4 ++-- unified-doc/src/pages/index.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unified-doc/src/pages/docs/index.tsx b/unified-doc/src/pages/docs/index.tsx index c9349e7c..866630c0 100644 --- a/unified-doc/src/pages/docs/index.tsx +++ b/unified-doc/src/pages/docs/index.tsx @@ -35,7 +35,7 @@ export default function Home(): ReactNode { Frontdoor Docs - OpenZiti Docs + OpenZiti Docs zLAN Docs
@@ -85,7 +85,7 @@ export default function Home(): ReactNode { Open-source zero-trust networking project and SDKs.
- Go to OpenZiti + Go to OpenZiti
diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 375548ae..4b082280 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -57,7 +57,7 @@ const products = [ logo: `${IMG}/openziti-sm-logo.svg`, tag: 'Open Source', accent: GREEN, - link: `${DOCS_BASE}openziti/learn/introduction`, + link: `${DOCS_BASE}openziti/intro`, features: ['Community support', 'Full overlay mesh: controller, routers, and SDKs', 'Embed zero-trust in any application'], description: 'The open-source zero-trust networking framework behind NetFoundry. Add zero trust to existing apps with tunnelers, or embed it directly with the SDK for the strongest posture.' }, From bdbc10ca46f8f724fc5f198a8e441c727645ce08 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 20 May 2026 20:01:25 +0000 Subject: [PATCH 17/18] Revert "fix: update broken openziti intro links" This reverts commit 05d765406ace03ee0c470a3f82a7c3e5c5febd91. --- unified-doc/src/pages/docs/index.tsx | 4 ++-- unified-doc/src/pages/index.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unified-doc/src/pages/docs/index.tsx b/unified-doc/src/pages/docs/index.tsx index 866630c0..c9349e7c 100644 --- a/unified-doc/src/pages/docs/index.tsx +++ b/unified-doc/src/pages/docs/index.tsx @@ -35,7 +35,7 @@ export default function Home(): ReactNode { Frontdoor Docs - OpenZiti Docs + OpenZiti Docs zLAN Docs @@ -85,7 +85,7 @@ export default function Home(): ReactNode { Open-source zero-trust networking project and SDKs.
- Go to OpenZiti + Go to OpenZiti
diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 4b082280..375548ae 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -57,7 +57,7 @@ const products = [ logo: `${IMG}/openziti-sm-logo.svg`, tag: 'Open Source', accent: GREEN, - link: `${DOCS_BASE}openziti/intro`, + link: `${DOCS_BASE}openziti/learn/introduction`, features: ['Community support', 'Full overlay mesh: controller, routers, and SDKs', 'Embed zero-trust in any application'], description: 'The open-source zero-trust networking framework behind NetFoundry. Add zero trust to existing apps with tunnelers, or embed it directly with the SDK for the strongest posture.' }, From 2b2900905903c3566423cdd6f17df220091c9cf0 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 20 May 2026 20:11:24 +0000 Subject: [PATCH 18/18] fix: update openziti links to 2.x paths after version promotion PR #1288 promoted 2.x to the default version; learn/introduction no longer exists in the 2.x default path. Update unified-doc page links to /intro. Co-Authored-By: Claude Sonnet 4.6 --- unified-doc/src/pages/docs/index.tsx | 4 ++-- unified-doc/src/pages/index.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unified-doc/src/pages/docs/index.tsx b/unified-doc/src/pages/docs/index.tsx index c9349e7c..866630c0 100644 --- a/unified-doc/src/pages/docs/index.tsx +++ b/unified-doc/src/pages/docs/index.tsx @@ -35,7 +35,7 @@ export default function Home(): ReactNode { Frontdoor Docs - OpenZiti Docs + OpenZiti Docs zLAN Docs @@ -85,7 +85,7 @@ export default function Home(): ReactNode { Open-source zero-trust networking project and SDKs.
- Go to OpenZiti + Go to OpenZiti
diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 375548ae..4b082280 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -57,7 +57,7 @@ const products = [ logo: `${IMG}/openziti-sm-logo.svg`, tag: 'Open Source', accent: GREEN, - link: `${DOCS_BASE}openziti/learn/introduction`, + link: `${DOCS_BASE}openziti/intro`, features: ['Community support', 'Full overlay mesh: controller, routers, and SDKs', 'Embed zero-trust in any application'], description: 'The open-source zero-trust networking framework behind NetFoundry. Add zero trust to existing apps with tunnelers, or embed it directly with the SDK for the strongest posture.' },