marmelab/react-admin · info
No element with id "main-content" was found. Ensure the elem
Error message
No element with id "main-content" was found. Ensure the element that contains your main content has an id of "main-content".
What it means
SkipNavigationButton's skipToContent handler looks up the element with id "main-content" to move focus past the navigation. In non-production builds, if no such element exists it warns that the app layout is missing the required anchor, and the skip action does nothing.
Source
Thrown at packages/ra-ui-materialui/src/button/SkipNavigationButton.tsx:67
opacity: 0.8,
backgroundColor: (theme.vars || theme).palette.background.default,
},
'&:focus': {
top: theme.spacing(2),
transition: theme.transitions.create(['top', 'opacity'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
}));
const skipToContent = () => {
if (typeof document === 'undefined') return;
const element = document.getElementById('main-content');
if (!element) {
if (process.env.NODE_ENV !== 'production') {
console.warn(
'No element with id "main-content" was found. Ensure the element that contains your main content has an id of "main-content".'
);
}
return;
}
element.setAttribute('tabIndex', '-1');
element.focus();
element.blur();
element.removeAttribute('tabIndex');
};
declare module '@mui/material/styles' {
interface ComponentNameToClassKey {
RaSkipNavigationButton: 'root';
}
View on GitHub (pinned to 051f511bb0)
Solutions
- Give the element wrapping the layout children id="main-content" in your custom Layout.
- Use react-admin's default Layout, which already includes the main-content wrapper.
- In tests, mock skipToContent or render a stub element with id="main-content".
Example fix
// before (custom Layout)
<div className={classes.root}>
<Menu />
{children}
</div>
// after
<div className={classes.root}>
<Menu />
<div id="main-content">{children}</div>
</div> Defensive patterns
Strategy: validation
Validate before calling
if (typeof document !== 'undefined' && !document.getElementById('main-content')) {
console.warn('Custom Layout is missing <div id="main-content">');
} Type guard
const hasMainContent = () => typeof document !== 'undefined' && document.getElementById('main-content') !== null; Prevention
- Always include id="main-content" on the children wrapper in custom Layouts.
- Start custom layouts from react-admin's default Layout source.
- Add an accessibility smoke test asserting the anchor exists.
When it happens
Trigger: Clicking/activating the SkipNavigationButton (or calling skipToContent) in a custom Layout that lacks <div id="main-content"> around the children, or in tests rendering Layout fragments without the id.
Common situations: Building a custom Layout component without copying the main-content wrapper; upgrading Layout code and dropping the id; unit tests that render the button in isolation.
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/ba4216bb86cf15a9.
Report an issue: GitHub.