From 2da0b663bcfb15f44790be11422f3c8754591352 Mon Sep 17 00:00:00 2001 From: Johan Persson Date: Thu, 23 Apr 2026 15:28:13 +0200 Subject: [PATCH] Replace useHref with useResolvedPath in useDefinition useResolvedPath returns the resolved path without the router basename, eliminating the need for manual basename detection and stripping. Signed-off-by: Johan Persson --- .../src/hooks/useDefinition/useDefinition.tsx | 29 +++++-------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/packages/ui/src/hooks/useDefinition/useDefinition.tsx b/packages/ui/src/hooks/useDefinition/useDefinition.tsx index a0e3c53164..1382b352f7 100644 --- a/packages/ui/src/hooks/useDefinition/useDefinition.tsx +++ b/packages/ui/src/hooks/useDefinition/useDefinition.tsx @@ -21,7 +21,11 @@ import { useBgProvider, useBgConsumer, BgProvider } from '../useBg'; import { resolveDefinitionProps, processUtilityProps } from './helpers'; import { useAnalytics } from '../../analytics/useAnalytics'; import { noopTracker } from '../../analytics/useAnalytics'; -import { useHref, useInRouterContext } from 'react-router-dom'; +import { + useResolvedPath, + useInRouterContext, + createPath, +} from 'react-router-dom'; import { isExternalLink } from '../../utils/linkUtils'; import type { ComponentConfig, @@ -40,32 +44,13 @@ export function useDefinition< ): UseDefinitionResult { const { breakpoint } = useBreakpoint(); - // Pre-resolve href at component render time (where route context is - // correct), so that click-navigation has a correct absolute path - // regardless of where useNavigate is called. `useHref` returns the - // path with basename prepended; strip it so the output is the - // canonical pre-basename form that react-router's downstream useHref - // and navigate both expect as input (avoids double-prefixing). - // External URLs bypass resolution. let hrefResolvedProps = props; const hasRouter = useInRouterContext(); if (hasRouter) { const rawHref = (props as any).href; - // useHref('/') returns the router's basename. Strip trailing slashes - // so the prefix check works regardless of how the consumer configured - // their . - const basename = useHref('/').replace(/\/+$/, '') || '/'; - const absoluteHref = useHref(rawHref ?? ''); + const resolved = useResolvedPath(rawHref ?? ''); if (rawHref !== undefined && !isExternalLink(rawHref)) { - let stripped = absoluteHref; - if ( - basename !== '/' && - (absoluteHref === basename || absoluteHref.startsWith(`${basename}/`)) - ) { - stripped = - absoluteHref === basename ? '/' : absoluteHref.slice(basename.length); - } - hrefResolvedProps = { ...props, href: stripped } as P; + hrefResolvedProps = { ...props, href: createPath(resolved) } as P; } }