Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ef17520
[docs-infra] Test HTML validation in broken links checker
Janpot Mar 24, 2026
f4e3866
update
Janpot Mar 25, 2026
d242c98
update
Janpot Mar 25, 2026
15f1342
Update @mui/internal-code-infra to latest preview
Janpot Mar 25, 2026
2a98e46
Update htmlValidate config to extend mui:recommended and disable no-r…
Janpot Mar 30, 2026
fa7f70a
Update @mui/internal-code-infra to latest preview
Janpot Mar 30, 2026
16b4757
[docs] Add missing title attribute to embedded iframes
Janpot Apr 15, 2026
cf90002
[docs] Add aria-label to color picker radios in ColorTool
Janpot Apr 15, 2026
9b617b4
[docs-infra] Configure HTML validation rules and fix minor issues
Janpot Apr 16, 2026
93f8d2c
[docs-infra] Run link checker as separate CI step instead of during b…
Janpot Apr 16, 2026
b63e0eb
[docs] Fix invalid label/for reference in GroupedSelect demo
Janpot Apr 21, 2026
0c70547
[docs] Regenerate RtlOptOut JS and preview
Janpot Apr 21, 2026
145e36a
Merge remote-tracking branch 'upstream/master' into test-html-validate
Janpot Apr 21, 2026
1ce330c
Update pnpm-lock.yaml
Janpot Apr 22, 2026
929b08a
Merge remote-tracking branch 'upstream/master' into test-html-validate
Janpot Apr 29, 2026
29ef84d
Merge remote-tracking branch 'upstream/master' into test-html-validate
Janpot Apr 29, 2026
96861b1
Update pnpm-lock.yaml
Janpot Apr 29, 2026
74de731
fixes
Janpot Apr 29, 2026
a5bd441
Fix some duplicate ids
Janpot Apr 29, 2026
12c770f
Update reportBrokenLinks.mts
Janpot Apr 29, 2026
be70850
Only on ubuntu
Janpot Apr 30, 2026
0cf1cce
Update @mui/internal-code-infra and only fail on html-validate errors
Janpot May 4, 2026
8e0a0bd
Merge remote-tracking branch 'upstream/master' into test-html-validate
Janpot May 4, 2026
eee64f0
fixes
Janpot May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ jobs:
# - run: pnpm release:changelog
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check docs links
if: ${{ matrix.os == 'ubuntu-latest' }}
run: pnpm docs:link-check
- name: Debug export-detail.json on when pnpm docs:build fails with EMFILE error
if: failure()
run: cat ./docs/.next/export-detail.json || true
Expand Down
4 changes: 1 addition & 3 deletions docs/data/material/components/selects/GroupedSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ export default function GroupedSelect() {
</Select>
</FormControl>
<FormControl sx={{ m: 1, minWidth: 120 }}>
<InputLabel id={`${id}-label`} htmlFor={`${id}-select`}>
Grouping
</InputLabel>
<InputLabel id={`${id}-label`}>Grouping</InputLabel>
<Select
defaultValue=""
id={`${id}-select`}
Expand Down
4 changes: 1 addition & 3 deletions docs/data/material/components/selects/GroupedSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ export default function GroupedSelect() {
</Select>
</FormControl>
<FormControl sx={{ m: 1, minWidth: 120 }}>
<InputLabel id={`${id}-label`} htmlFor={`${id}-select`}>
Grouping
</InputLabel>
<InputLabel id={`${id}-label`}>Grouping</InputLabel>
<Select
defaultValue=""
id={`${id}-select`}
Expand Down
1 change: 1 addition & 0 deletions docs/data/material/customization/color/ColorTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ function ColorTool() {
onChange={handleChangeHue(intent)}
value={hue}
name={intent}
aria-label={hue}
icon={
<Box
sx={{ width: 48, height: 48 }}
Expand Down
2 changes: 1 addition & 1 deletion docs/data/material/customization/color/color.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The Material Design team has also built an awesome palette configuration tool: [
This can help you create a color palette for your UI, as well as measure the accessibility level of any color combination.

<a href="https://m2.material.io/inline-tools/color/" target="_blank" rel="noopener nofollow" class="remove-link-arrow">
<img src="/static/images/color/colorTool.png" alt="Official color tool" style="width: 574px" width=1148" height="610" />
<img src="/static/images/color/colorTool.png" alt="Official color tool" style="width: 574px" width="1148" height="610" />
</a>
<br />
<br />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function RtlOptOut() {
label="Toggle RTL"
/>
<CacheProvider value={rtl ? rtlCache : ltrCache}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : ''}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : undefined}>
<Normal>RTL normal behavior</Normal>
<Noflip>RTL noflip</Noflip>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function RtlOptOut() {
label="Toggle RTL"
/>
<CacheProvider value={rtl ? rtlCache : ltrCache}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : ''}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : undefined}>
<Normal>RTL normal behavior</Normal>
<Noflip>RTL noflip</Noflip>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
label="Toggle RTL"
/>
<CacheProvider value={rtl ? rtlCache : ltrCache}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : ''}>
<Box sx={{ flexGrow: 1, mx: 2 }} dir={rtl ? 'rtl' : undefined}>
<Normal>RTL normal behavior</Normal>
<Noflip>RTL noflip</Noflip>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ You can use the [Similayer](https://www.figma.com/community/plugin/7357332678833

The video below shows how to add new columns by detaching cells from their row components, allowing you to freely move content around.

<iframe src="https://www.loom.com/embed/6dd71cc374bc4d84af35ebb75d107d38?sid=1d3a4790-4c28-433e-94ce-97dd969601dd" webkitallowfullscreen mozallowfullscreen allowfullscreen style="width: 100%; height: 500px; border: 0"></iframe>
<iframe src="https://www.loom.com/embed/6dd71cc374bc4d84af35ebb75d107d38?sid=1d3a4790-4c28-433e-94ce-97dd969601dd" title="Adding new columns by detaching cells from row components" webkitallowfullscreen mozallowfullscreen allowfullscreen style="width: 100%; height: 500px; border: 0"></iframe>

#### Adding new columns in the main component

Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/discover-more/backers/backers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Sponsorship increases the rate of bug fixes, documentation improvements, and fea
## Diamond sponsors

<p style="display: flex; justify-content: start; align-items: center; flex-wrap: wrap; margin-top: 8px;">
<a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="doit.com" href="https://www.doit.com/flexsave/?utm_source=mui.com&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/doit-square.svg" alt="doit" title="Management platform for Google Cloud and AWS" loading="lazy" /></a>
<a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="formengine.io" href="https://formengine.io/lightweight-react-json-schema-form-builder-library-for-mui?utm_source=mui&utm_medium=sponsor&utm_campaign=mui&utm_content=stop-manually&utm_term=smartway" rel="noopener sponsored" target="_blank" class="remove-link-arrow" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/formengine-square.svg" alt="formengine" title="Build forms with MUI the smart way!" loading="lazy" /></a>
<a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="doit.com" href="https://www.doit.com/flexsave/?utm_source=mui.com&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/doit-square.svg" alt="doit" title="Management platform for Google Cloud and AWS" loading="lazy" /></a>
<a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="formengine.io" href="https://formengine.io/lightweight-react-json-schema-form-builder-library-for-mui?utm_source=mui&utm_medium=sponsor&utm_campaign=mui&utm_content=stop-manually&utm_term=smartway" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/formengine-square.svg" alt="formengine" title="Build forms with MUI the smart way!" loading="lazy" /></a>
</p>

_1/3 slots available_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ There are examples for the following styling solutions:

Nothing fancy, just plain CSS.

{{"demo": "StyledComponents.js", "hideToolbar": true}}
{{"demo": "StyledComponents.js", "hideToolbar": true, "anchorId": null}}

[![Edit Button](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/plain-css-fdue7)

Expand Down Expand Up @@ -95,7 +95,7 @@ In Material UI, all child elements have an increased specificity of 2: `.parent

The following examples override the slider's `thumb` style in addition to the custom styles on the slider itself.

{{"demo": "StyledComponentsDeep.js", "hideToolbar": true}}
{{"demo": "StyledComponentsDeep.js", "hideToolbar": true, "anchorId": null}}

```css title="PlainCssSliderDeep1.css"
.slider {
Expand Down Expand Up @@ -236,7 +236,7 @@ In Material UI, all child elements have an increased specificity of 2: `.parent

The following example overrides the slider's `thumb` style in addition to the custom styles on the slider itself.

{{"demo": "StyledComponentsDeep.js", "hideToolbar": true}}
{{"demo": "StyledComponentsDeep.js", "hideToolbar": true, "anchorId": null}}

```css title="GlobalCssSliderDeep.css"
.MuiSlider-root {
Expand Down Expand Up @@ -401,7 +401,7 @@ const StyledTooltip = styled(({ className, ...props }) => (

It's hard to know the market share of [this styling solution](https://github.com/css-modules/css-modules) as it's dependent on the bundling solution people are using.

{{"demo": "StyledComponents.js", "hideToolbar": true}}
{{"demo": "StyledComponents.js", "hideToolbar": true, "anchorId": null}}

[![Edit Button](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/css-modules-nuyg8)

Expand Down Expand Up @@ -760,7 +760,7 @@ If styles aren't applying correctly:

Now it's all set up and you can start using Tailwind CSS on the Material UI components!

{{"demo": "StyledComponents.js", "hideToolbar": true}}
{{"demo": "StyledComponents.js", "hideToolbar": true, "anchorId": null}}

[![Edit on StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/edit/github-ndkshy?file=pages%2Findex.tsx)

Expand All @@ -784,7 +784,7 @@ If you attempt to style the Slider, for example, you'll likely want to customize

This example showcases how to override the Slider's `thumb` style.

{{"demo": "StyledComponentsDeep.js", "hideToolbar": true}}
{{"demo": "StyledComponentsDeep.js", "hideToolbar": true, "anchorId": null}}

```jsx title="SliderThumbOverrides.tsx"
import * as React from 'react';
Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": true,
"license": "MIT",
"scripts": {
"build": "rimraf ./export && cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=8192 next build && pnpm build-sw && pnpm link-check",
"build": "rimraf ./export && cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=8192 next build && pnpm build-sw",
"build:clean": "rimraf .next && pnpm build",
"build-sw": "node ./scripts/buildServiceWorker.js",
"dev": "next dev",
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/blog/2019-developer-survey-results.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ It's sorted descending, with the most important concerns first:
</figure>
<br />
<figure style="margin-inline-start: 0;">
<img style="display: block; margin: 0 auto;" src="/static/blog/2019-developer-survey-results/5b.png" style="display: block; margin: 0 auto;" alt="Pie chart: 70.6% promoters, 24.8% neutrals, 4.6% detractors" />
<img style="display: block; margin: 0 auto;" src="/static/blog/2019-developer-survey-results/5b.png" alt="Pie chart: 70.6% promoters, 24.8% neutrals, 4.6% detractors" />
<figcaption style="font-style: italic; text-align: center;">Result.</figcaption>
</figure>

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/blog/2020-introducing-sketch.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ The UI kit was created specifically for Material UI, a popular React UI library

The following video demonstrates how the symbols can be used to design an invoice page.

<iframe height="364" style="aspect-ratio: 16 / 9; width: 100% !important; max-width: 648px; border: 0" src="https://www.youtube.com/embed/DTU6r_VE2C4" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<iframe height="364" style="aspect-ratio: 16 / 9; width: 100% !important; max-width: 648px; border: 0" src="https://www.youtube.com/embed/DTU6r_VE2C4" title="Designing an invoice page with the Material UI Sketch symbols" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Sketch Cloud preview: https://mui.com/store/previews/sketch-react/.

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/blog/material-ui-v1-is-out.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ We are so excited about this release, as it's setting a new course for the proje

✨✨✨ See the **[1.0.0 Release Note](https://github.com/mui/material-ui/releases/tag/v1.0.0)** on GitHub. ✨✨✨

<iframe src="https://codesandbox.io/embed/4j7m47vlm4" style="width: 100%; height: 300px; border: 0"></iframe>
<iframe src="https://codesandbox.io/embed/4j7m47vlm4" title="Material UI v1 button demo on CodeSandbox" style="width: 100%; height: 300px; border: 0"></iframe>

<p class="blog-description">One button</p>

Expand Down
6 changes: 3 additions & 3 deletions docs/pages/blog/toolpad-use-cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Other KPI pages also use this health badge and pre-built Chart components to com

The video below demonstrates the usage of this app in dev mode:

<video controls width="100%" height="auto" alt="zendesk first reply in devmode">
<video controls style="width: 100%; height: auto" alt="zendesk first reply in devmode">
<source src="/static/blog/toolpad-use-cases/zendesk-first-reply-dev.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Expand All @@ -74,7 +74,7 @@ In the Toolpad app, the operations team can view a table of all customers who ne
They select one, email them from Zendesk, and update the status to `CONTACTED`, which is then written back to the database.
This is a private app for internal use that can't be shared, but the following video gives a quick demo:

<video controls width="100%" height="auto" alt="overdue invoice page">
<video controls style="width: 100%; height: auto" alt="overdue invoice page">
<source src="/static/blog/toolpad-use-cases/overdue-invoice.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Expand All @@ -89,7 +89,7 @@ Our operations team is responsible for paying contributors, but the script prove
We solved this problem by importing the script into Toolpad and creating a UI for it.
The video below shows how a user can select the dates, run the script, and receive text that's properly formatted to copy and paste directly into Slack communications:

<video controls width="100%" height="auto" alt="contributor payout page">
<video controls style="width: 100%; height: auto" alt="contributor payout page">
<source src="/static/blog/toolpad-use-cases/contributor-payout.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/v6-beta-pickers.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Please, try it out for yourself in the live demo below.

<iframe
src="https://codesandbox.io/embed/date-field-demo-pb87v0?fontsize=12&hidenavigation=1&module=%2F"
title="Date Field demo on CodeSandbox"
style="width:100%; height:200px; border:0; border-radius: 4px; overflow:hidden;"
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
Expand Down
99 changes: 97 additions & 2 deletions docs/scripts/reportBrokenLinks.mts
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,114 @@ async function main() {
'[id^="demo-"] a[href^="#outlined-buttons"]',
'[id^="demo-"] a[href^="#foo"]',
],
htmlValidate: [
// Default — applies to every page.
{
config: {
rules: {
// Prism.js outputs raw ">" in syntax-highlighted code blocks.
// https://github.com/PrismJS/prism/issues/2516
// https://gitlab.com/html-validate/html-validate/-/work_items/348
'no-raw-characters': 'off',
// TODO: re-enable and fix violations (mostly <style>/<div> inside <span>/<div>).
'element-permitted-content': 'off',
// html-validate incorrectly requires `imagesizes` on `<link rel="preload"
// as="image" imagesrcset="... 2x, ... 3x">`. Per the HTML spec, `imagesizes`
// is only required when `imagesrcset` uses *width* descriptors; with density
// descriptors (2x, 3x) it must be omitted.
// Reported: https://gitlab.com/html-validate/html-validate/-/work_items/352
'element-required-attributes': 'off',
// TODO: re-enable after an a11y pass on demos. Many Slider/Radio/Switch
// demos on styling-focused pages render a native <input> without a label.
'input-missing-label': 'off',
// TODO: remaining violations are infra-level (same demo rendered
// multiple times gets duplicate anchor IDs, and the blog template
// has desktop + mobile search with the same id="search").
'no-dup-id': 'off',
},
},
},
// Demos use Typography variant="h6" for visual styling (renders <h6>),
// some pages lack an <h1>, and typography demos intentionally show all
// heading variants. Blog/marketing templates also start at <h2>.
{
path: [
/^\/blog(\/|$|\?)/,
'/core',
'/material-ui',
'/careers',
'/about',
'/pricing',
'/material-ui/customization/typography',
'/material-ui/customization/css-theme-variables/native-color',
'/material-ui/react-typography',
'/material-ui/react-popper',
'/material-ui/getting-started/templates/checkout',
'/material-ui/getting-started/templates/marketing-page',
'/material-ui/getting-started/templates/blog',
],
config: { rules: { 'heading-level': 'warn' } },
},
// MUI's Collapse and TreeView wrap <li> children in <div> elements,
// breaking the required <ul>/<ol> parentage.
{
path: [
'/system/getting-started/the-sx-prop',
'/material-ui/transitions',
'/material-ui/getting-started/templates/dashboard',
],
config: { rules: { 'element-permitted-parent': 'warn' } },
},
// Some demos use aria-label/aria-labelledby on elements without an
// appropriate role (Avatar <div>, FormGroup <div>, Grid templates).
{
path: [
'/material-ui/react-app-bar',
'/material-ui/react-grid',
'/system/react-grid',
'/material-ui/react-checkbox',
'/material-ui/react-select',
'/material-ui/react-switch',
'/material-ui/react-divider',
'/material-ui/react-list',
'/material-ui/react-card',
'/material-ui/integrations/routing',
'/material-ui/getting-started/templates/marketing-page',
'/material-ui/getting-started/templates/blog',
],
config: { rules: { 'aria-label-misuse': 'warn' } },
},
// Portaled elements (Menu, Select, Autocomplete listbox) and Base UI
// components render aria-controls/aria-labelledby targets only after
// client hydration, so they're missing from the static HTML.
{
path: [
'/material-ui/react-app-bar',
'/material-ui/react-number-field',
'/material-ui/customization/overriding-component-structure',
'/material-ui/react-dialog',
'/material-ui/react-menu',
'/material-ui/getting-started/templates/dashboard',
],
config: { rules: { 'no-missing-references': 'warn' } },
},
],
ignores: [
{
// The links checker uses standard github slugger to check if the anchor exists. But the MUI docs use
// a custom slugger that sometimes generates different slugs.
// Ideally we makeit use the github slugegr so links are consistent whether in the html version or
// Ideally we make it use the github slugger so links are consistent whether in the html version or
// a standard markdown renderer.
path: '/material-ui/react-table.md',
href: '#sorting-selecting',
},
],
});

process.exit(issues.length);
const errorCount = issues.filter(
(issue) => issue.type !== 'html-validate' || issue.severity >= 2,
).length;
process.exit(errorCount);
}

main();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"@eslint/compat": "2.0.5",
"@mui/internal-babel-plugin-minify-errors": "2.0.8-canary.27",
"@mui/internal-bundle-size-checker": "1.0.9-canary.77",
"@mui/internal-code-infra": "0.0.4-canary.35",
"@mui/internal-code-infra": "https://pkg.pr.new/mui/mui-public/@mui/internal-code-infra@655e0675",
"@mui/internal-docs-utils": "workspace:^",
"@mui/internal-netlify-cache": "0.0.3-canary.5",
"@mui/internal-scripts": "workspace:^",
Expand Down
Loading
Loading