renderer.alias.img causes hydration mismatch and broken heading anchors in Nuxt Content v3
Environment
- Operating System: Linux
- Node Version: v23.7.0
- Nuxt Version: 3.17.4
- CLI Version: 3.25.1
- Nitro Version: 2.11.12
- Package Manager: [email protected]
- Builder: -
- User Config: future, experimental, devServer, compatibilityDate, telemetry, debug, devtools, modules, app, css, googleFonts, dayjs, content, vite, runtimeConfig
- Runtime Modules: @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], @nuxtjs/[email protected], @nuxt/[email protected], [email protected]
- Build Modules: -
Version
v3.5.1
Reproduction
https://github.com/gokaybiz/nuxt-content-custom-renderer-reprod
Description
When aliasing the img tag using renderer.alias in Nuxt Content v3, hydration breaks and causes heading tag anchor links to mismatch or duplicate incorrectly.
content: {
markdown: {
renderer: {
alias: {
img: 'CustomImageTag', // this breaks
a: 'CustomATag', // this does NOT cause problems
}
}
}
}
Behavior:
Server-side rendered output is fine: expected heading IDs (e.g. <h3 id="iLoveKebab">iLoveKebab</h3>)
On client-side hydration (especially on direct page load), the heading anchor text and id no longer match
For example:
<!-- SSR output -->
<h3 id="iLoveKebab"><a href="#iLoveKebab">iLoveKebab</a></h3>
<!-- After hydration -->
<h3 id="butIHateCoriander"><a href="#butIHateCoriander">iLoveKebab</a></h3> <!-- ?? -->
Repro steps:
- Enable img: 'YourCustomComponent' in renderer.alias
- Use markdown with headings and/or images near or inside headings
- Navigate directly to the page
- Observe mismatched or duplicated
<a href="#...">anchors
Expected:
- Hydration should match SSR output
- Anchor slugs and heading text should remain stable
Actual:
- Hydration mismatches break slug mapping
- Anchors jump unexpectedly or become duplicated
Additional context
No response
Logs
In the reproduction repo, you can observe as:
<h3 id="portitor-amet-vox"><a href="#portitor-amet-vox"><!--[-->Lumen<!--]--></a></h3>
<h3 id="portitor-amet-vox"><a href="#portitor-amet-vox">Portitor amet vox</a></h3>
<h3 id="idem-portitor-terra"><a href="#idem-portitor-terra"><!--[-->Diem Annus Mater Gloria Fortis Arbor<!--]--></a></h3>
@farnabaz Do you have any idea about possible causes?
It looks like this is a problem caused by nuxt/mdc. Should I open an issue there too?
Hey @gokaybiz
Sorry for the late response
I checked your repo. This is not directly related to the renderer.
In markdown, images are wrapped inside <p> paragraph. And since your custom components rendered <div>, it causes a hydration issue.
If you change <div> tag in your CustomImg component to <span> or other non-block tags it will resolve the issue.
Alternatively, you can use MDC syntax to avoid this paragraph generation
::img{alt="homo fatum lumen bellum" src="https://picsum.photos/200/300"}
::
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.
This issue was closed because it has been stalled for 30 days with no activity.