Skip to content

[BUG] MUI Breadcrumb links lose all styling — sx/underline/color/variant spread onto a plain <span> #7462

Description

@Purav-Kanda

Describe the bug

In @refinedev/mui's Breadcrumb component, the internal LinkRouter helper is typed to accept MUI LinkProps (sx, underline, color, variant) but renders them onto a bare native instead of an actual MUI component:

// packages/mui/src/components/breadcrumb/index.tsx

const LinkRouter = (props: LinkProps & { to?: string }) => {
  const { to, children, ...restProps } = props;
  return (
    <Link to={to || ""}>
      <span {...restProps}>{children}</span>
    </Link>
  );
};

Because is a plain DOM element, none of the MUI styling props do anything. They just get dumped onto the DOM node as literal, invalid HTML attributes.

I confirmed this with a minimal repro (real React server render) using the exact call-site props this component passes:

<LinkRouter underline="hover" sx={{ display: "flex", alignItems: "center", fontSize: "14px", marginLeft: 0.5 }} color="inherit" to="/posts" variant="subtitle1">
  Posts
</LinkRouter>

Current (buggy) output:

html<span underline="hover" sx="[object Object]" color="inherit" variant="subtitle1">Posts</span>
Visible impact: breadcrumb links aren't flex-aligned with their icons, get no hover underline, don't inherit color, and don't get the intended typography size.

Root cause: this is a regression from the v5 migration (#6945), specifically commit 5d63ada ("fix(mui): remove deprecated api"). Before that commit, LinkRouter correctly rendered MUI's actual Link:

const LinkRouter = (props: LinkProps & { to?: string }) => (
  <Link {...props} component={ActiveLink} />
);

When the legacy-router plumbing (useRouterContext, useRouterType, ActiveLink) was removed in favor of the single useLink() API, the component was rewritten to wrap a — but the props meant for MUI's Link were never re-wired to an actual MUI component. The file still has an unused import { Link as MuiLink } from "@mui/material" (dead since that commit) — a leftover from an incomplete fix.

The shared breadcrumbTests suite (packages/ui-tests/src/tests/breadcrumb.tsx) only checks structure (text, href, icon presence), never styling, so this slipped through untested.

Steps To Reproduce

  1. Use @refinedev/mui's in any resource list/show/edit page with at least 2 breadcrumb levels (default minItems).
  2. Open browser devtools and inspect a breadcrumb link element.
  3. Observe the rendered carries non-functional attributes (sx, underline, color, variant) instead of MUI-generated
    classes/CSS, and has no flex alignment, hover underline, or inherited color.

(Minimal standalone repro, outside a full app, using the exact LinkRouter source and MUI's real Link component:)

const React = require('react');
const { renderToStaticMarkup } = require('react-dom/server');
const MuiLink = require('@mui/material/Link').default;

const Link = ({ to, children }) => React.createElement('a', { href: to }, children);

// current (buggy) implementation
const LinkRouterBuggy = (props) => {
  const { to, children, ...restProps } = props;
  return React.createElement(Link, { to: to || '' },
    React.createElement('span', restProps, children));
};
console.log(renderToStaticMarkup(
  React.createElement(LinkRouterBuggy, {
    underline: 'hover',
    sx: { display: 'flex', alignItems: 'center', fontSize: '14px', marginLeft: 0.5 },
    color: 'inherit', to: '/posts', variant: 'subtitle1',
  }, 'Posts')
));
// -> <a href="/posts"><span underline="hover" sx="[ob

Expected behavior

The sx, underline, color, and variant props passed to LinkRouter should actually style the rendered link — flex-aligned with its icon, underlined on hover, inheriting color, and sized per the typography variant — instead of being dumped as inert HTML attributes on a plain .

Suggested fix — render the inner element as MUI's Link (kept as component="span" to avoid nesting two tags, consistent with the precaution taken in #7428 for the ThemedTitle hydration bug):

const LinkRouter = (props: LinkProps & { to?: string }) => {
  const { to, children, ...restProps } = props;
  return (
    <Link to={to || ""}>
      <MuiLink component="span" {...restProps}>
        {children}
      </MuiLink>
    </Link>
  );
};

Verified locally — fixed output:

html<span class="MuiTypography-root MuiTypography-subtitle1 MuiLink-root MuiLink-underlineHover css-...">Posts</span>
with generated CSS correctly showing display:flex; align-items:center; font-size:14px; margin-left:4px; and :hover { text-decoration: underline; } — matching the intended props.

Packages

N/A — found via direct review of the @refinedev/mui source on main (not from a running app's npm run refine whoami output). Affects @refinedev/mui, current main branch, regression present since commit 5d63ada (part of #6945, the v5 migration). Verified against the latest commit on packages/mui/src/components/breadcrumb/index.tsx as of this report.

Additional Context

I have a working fix patched and verified locally (before/after server-render output shown above) and am happy to open a PR for it once this issue is confirmed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions