diff --git a/.changeset/new-windows-reply.md b/.changeset/new-windows-reply.md new file mode 100644 index 0000000000..e15ea2f1de --- /dev/null +++ b/.changeset/new-windows-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed `Link` component causing hard page refreshes for internal routes. The component now properly uses React Router's navigation instead of full page reloads. diff --git a/packages/ui/src/components/Link/Link.tsx b/packages/ui/src/components/Link/Link.tsx index 351fc15279..9dd9926f97 100644 --- a/packages/ui/src/components/Link/Link.tsx +++ b/packages/ui/src/components/Link/Link.tsx @@ -25,9 +25,7 @@ import { useNavigate, useHref } from 'react-router-dom'; import { isExternalLink } from '../../utils/isExternalLink'; import styles from './Link.module.css'; -/** @public */ -export const Link = forwardRef((props, ref) => { - const navigate = useNavigate(); +const LinkInternal = forwardRef((props, ref) => { const { classNames, dataAttributes, cleanedProps } = useStyles( LinkDefinition, { @@ -52,11 +50,11 @@ export const Link = forwardRef((props, ref) => { ...restProps } = cleanedProps; - const isExternal = isExternalLink(href); const internalRef = useRef(null); const linkRef = (ref || internalRef) as React.RefObject; // Use useLink hook to get link props + // For internal links, this will use the RouterProvider's navigate function const { linkProps } = useLink( { href, @@ -66,7 +64,7 @@ export const Link = forwardRef((props, ref) => { linkRef, ); - const anchorElement = ( + return ( ((props, ref) => { {children} ); +}); + +LinkInternal.displayName = 'LinkInternal'; + +/** @public */ +export const Link = forwardRef((props, ref) => { + const navigate = useNavigate(); + const isExternal = isExternalLink(props.href); // If it's an external link, render without RouterProvider if (isExternal) { - return anchorElement; + return ; } - // For internal links, use RouterProvider + // For internal links, wrap in RouterProvider so useLink can access the router return ( - {anchorElement} + ); });