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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingwontfixThis will not be worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions