-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Description
Reproduction
- Go to https://stackblitz.com/edit/github-8mzcjeeh?file=app%2Froutes%2Fblog%2Fpost.mdx
- Run the project
- Update the
blog/post.mdx
file - See that HMR doesn't work because of the consistent-components-exports
System Info
System:
OS: Windows 11 10.0.26100
CPU: (16) x64 AMD Ryzen 7 5800X 8-Core Processor
Memory: 46.29 GB / 63.93 GB
Binaries:
Node: 22.14.0 - C:\nvm4w\nodejs\node.EXE
Yarn: 1.22.22 - C:\nvm4w\nodejs\yarn.CMD
npm: 10.9.2 - C:\nvm4w\nodejs\npm.CMD
pnpm: 10.12.1 - C:\nvm4w\nodejs\pnpm.CMD
Browsers:
Edge: Chromium (133.0.3065.59)
Internet Explorer: 11.0.26100.1882
npmPackages:
@react-router/dev: ^7.7.0 => 7.7.0
@react-router/node: ^7.7.0 => 7.7.0
@react-router/serve: ^7.7.0 => 7.7.0
react-router: ^7.7.0 => 7.7.0
vite: ^6.3.3 => 6.3.5
Used Package Manager
npm
Expected Behavior
HMR doesn't break when saving a .mdx
file with frontmatter
.
Actual Behavior
HMR breaks when editing mdx
files with frontmatter
.
I understand why this is happening — the error message from React Refresh makes it clear. When using remark-frontmatter
with @mdx-js/rollup
, it adds a frontmatter
export. Since this isn't included in the CLIENT_NON_COMPONENT_EXPORTS
array inside the @react-router/dev/vite
Vite plugin, HMR is disabled because React Refresh treats it as a second component export.
I saw that you’ve already worked around this issue for all the other exports like meta
, handle
, links
, etc., via this array:
const CLIENT_NON_COMPONENT_EXPORTS = [
"clientAction",
"clientLoader",
"unstable_clientMiddleware",
"handle",
"meta",
"links",
"shouldRevalidate",
];
Now, I could patch the plugin locally and add "frontmatter"
to this list — and it would work — but I’d expect support for frontmatter to be handled by the framework itself, especially given how common it is in MDX workflows.
I also considered setting the name
option in remark-mdx-frontmatter
to "handle"
, which technically works — but then I can't export an actual handle
anymore without causing a duplicate export error.
// vite.config.ts
mdx({
remarkPlugins: [
remarkFrontmatter,
[remarkMdxFrontmatter, { name: "handle" }],
],
}),
Also, @brookslybrand — not sure how HMR with frontmatter worked for you in this video, but with the same setup in RR7 it doesn’t seem to work out of the box when frontmatter is involved.
Suggestion
Would it make sense to either:
- Add
"frontmatter"
to the defaultCLIENT_NON_COMPONENT_EXPORTS
, or - Expose a plugin option to extend the whitelist from the user side? (Which would be my preferred solution, because I ran into the same issue trying to export
tableOfContents
via https://github.com/stefanprobst/rehype-extract-toc#how-to-use-with-mdx)