Fixes RouterProvider on Link

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2026-01-07 17:48:40 +00:00
parent 564f26e508
commit b3253b69aa
2 changed files with 19 additions and 8 deletions
+5
View File
@@ -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.
+14 -8
View File
@@ -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<HTMLAnchorElement, LinkProps>((props, ref) => {
const navigate = useNavigate();
const LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
const { classNames, dataAttributes, cleanedProps } = useStyles(
LinkDefinition,
{
@@ -52,11 +50,11 @@ export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
...restProps
} = cleanedProps;
const isExternal = isExternalLink(href);
const internalRef = useRef<HTMLAnchorElement>(null);
const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;
// 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<HTMLAnchorElement, LinkProps>((props, ref) => {
linkRef,
);
const anchorElement = (
return (
<a
{...linkProps}
{...dataAttributes}
@@ -79,16 +77,24 @@ export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
{children}
</a>
);
});
LinkInternal.displayName = 'LinkInternal';
/** @public */
export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
const navigate = useNavigate();
const isExternal = isExternalLink(props.href);
// If it's an external link, render without RouterProvider
if (isExternal) {
return anchorElement;
return <LinkInternal {...props} ref={ref} />;
}
// For internal links, use RouterProvider
// For internal links, wrap in RouterProvider so useLink can access the router
return (
<RouterProvider navigate={navigate} useHref={useHref}>
{anchorElement}
<LinkInternal {...props} ref={ref} />
</RouterProvider>
);
});