content icon indicating copy to clipboard operation
content copied to clipboard

renderer.alias.img causes hydration mismatch and broken heading anchors in Nuxt Content v3

Open gokaybiz opened this issue 7 months ago • 3 comments

Environment

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:

  1. Enable img: 'YourCustomComponent' in renderer.alias
  2. Use markdown with headings and/or images near or inside headings
  3. Navigate directly to the page
  4. 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


gokaybiz avatar May 30 '25 07:05 gokaybiz

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>

gokaybiz avatar May 30 '25 08:05 gokaybiz

@farnabaz Do you have any idea about possible causes?

gokaybiz avatar May 30 '25 10:05 gokaybiz

It looks like this is a problem caused by nuxt/mdc. Should I open an issue there too?

gokaybiz avatar Jun 06 '25 15:06 gokaybiz

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"}
::

farnabaz avatar Jul 03 '25 09:07 farnabaz

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.

github-actions[bot] avatar Sep 01 '25 10:09 github-actions[bot]

This issue was closed because it has been stalled for 30 days with no activity.

github-actions[bot] avatar Oct 01 '25 11:10 github-actions[bot]