N
Nuxt4w ago
Mason

Issue with @nuxt/content markdown processing involving mixed HTML and plaintext

Hey! I am making a blog using @nuxt/content. One problem I've run into is that when I mix HTML and plain text in my markdown files, the HTML "eats" the plaintext below it. I could simply avoid HTML, but the reason I'm bringing up this issue is because it's ALSO happening when I use Vue components within my markdown. I have created a Vue component which is pretty much essential for how I plan to set up my blog, so I would definitely like to get this sorted. I have tried searching, but I'm not totally sure what keywords to even use. I've also tried asking AI, and it wasn't helpful either, though it did seem to think it was not @nuxt/content specific? I would love it if somebody could at least give me a lead to follow to find the source of this problem. I will post a version with my custom Vue components, as well as custom beforeParse plugin, if necessary. But that might take a bit of time and effort to get a reproducible example on codesandbox, so I'm hoping the following example is enough: https://codesandbox.io/p/devbox/currying-violet-dzy4n3?workspaceId=ws_Phyvisc1F78GerdH9AzfWs On this link, you can see content/test.md is my markdown. If you navigate to /test on the web preview, you'll see that it only shows the text "test1" and "test3", and test2 and test4 are nowhere to be seen. One thing to note: since I am using a 'content:file:beforeParse' script, if you have a solution that relies on me manually editing my markdown before it gets parsed, that would be an acceptable solution for me. Such as if a certain bit of text/markdown/html needs to be appended before/after every HTML element in order to stop it from eating the plaintext below it, for example.
5 Replies
kapa.ai
kapa.ai4w ago
Hi @Mason. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- This issue—where HTML or custom Vue components in your Markdown "eat" the plaintext that follows—is a known challenge when mixing raw HTML, custom components, and Markdown in Nuxt Content. The root cause is often how the Markdown parser (MDC) interprets block-level HTML or custom components: when a block-level HTML tag or component is not properly separated from surrounding Markdown, the parser may treat everything until the next block as part of that HTML/component, causing subsequent plaintext to be ignored or not rendered as expected. Why does this happen? - Markdown Parsing Rules: In Markdown, when you insert raw HTML or a custom component (using MDC syntax), the parser may treat everything until the next blank line as part of that block. This is especially true for block-level elements and custom components. - Vue Components in Markdown: When using Vue components in Markdown via MDC syntax (e.g., ::my-component ... ::), the content inside is slotted into the component, and if not properly separated, following Markdown may be "swallowed" by the component or HTML block. - Raw HTML: Similar issues occur with raw HTML, as Markdown parsers often switch to HTML mode until a blank line is encountered. How to Fix or Work Around 1. Add Blank Lines Between Blocks The most reliable workaround is to ensure there is a blank line (an empty line) before and after any HTML or custom component block in your Markdown. This signals to the parser to treat the blocks separately. Example:
test1

<div>test2</div>

test3

::my-component
test4
::

test5
test1

<div>test2</div>

test3

::my-component
test4
::

test5
2. Use MDC Syntax for Vue Components When using Vue components, always use the MDC block syntax and ensure blank lines before and after:
::my-component
Some content
::

Some text after the component.
::my-component
Some content
::

Some text after the component.
3. If Using a content:file:beforeParse Hook If you want to automate this, you can use the content:file:beforeParse hook in your nuxt.config.ts to programmatically insert blank lines before and after HTML/component blocks. This can help standardize your Markdown files and prevent the issue:
export default defineNuxtConfig({
hooks: {
'content:file:beforeParse'(file) {
// Example: Add blank lines before/after <div> or ::component blocks
file.content = file.content.replace(/(<div[\s\S]*?>[\s\S]*?<\/div>)/g, '\n$1\n');
file.content = file.content.replace(/(::[a-zA-Z0-9-]+[\s\S]*?::)/g, '\n$1\n');
}
}
})
export default defineNuxtConfig({
hooks: {
'content:file:beforeParse'(file) {
// Example: Add blank lines before/after <div> or ::component blocks
file.content = file.content.replace(/(<div[\s\S]*?>[\s\S]*?<\/div>)/g, '\n$1\n');
file.content = file.content.replace(/(::[a-zA-Z0-9-]+[\s\S]*?::)/g, '\n$1\n');
}
}
})
Note: This is a basic example; you may need to adjust the regex for your specific use case. References - The MDC syntax and how to use Vue components in Markdown: Docs: Native parameters & Vue Components - Explanation of the content:file:beforeParse hook: Docs: Advanced Hooks - Best practices for minimizing formatting issues: Blog: Best practices to minimize unintended changes Summary - Always separate HTML and custom component blocks from plaintext with blank lines in your Markdown. - Use the MDC syntax for Vue components and ensure proper spacing. - If needed, automate formatting with the content:file:beforeParse hook. If you continue to experience issues, consider sharing a minimal reproducible example with the Nuxt Content team, as edge cases with Markdown parsing can sometimes require deeper investigation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@264590999479648268> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mason
MasonOP4w ago
@kapa.ai The problem with adding newlines is that I want my Vue component to be inline with the plaintext surrounding it. Adding newlines between the plaintext and the Vue component would put them on separate lines, which is not desirable.
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct—adding blank lines will force the component or HTML block onto its own line, which is not suitable for inline usage. According to the Nuxt Content documentation, the MDC syntax is designed to allow Vue components to be used in Markdown, but the examples and documentation focus on block-level usage (using ::component-name ... ::), and there is no official support or example for using custom Vue components inline with text in Markdown files. The same limitation applies to raw HTML: Markdown parsers generally treat HTML tags as block-level unless they're simple inline tags like <span> or <a>. The knowledge sources do not provide a built-in or documented way to use custom Vue components inline with plaintext in Nuxt Content Markdown. All official examples and documentation show block-level usage only, and there is no mention of a workaround for inline custom components or a way to change the parsing behavior to support this use case Docs: Native parameters & Vue Components. If you need inline dynamic content, you may be limited to using standard Markdown features or inline HTML (with simple tags), but not custom Vue components. If this is essential for your project, you might need to consider a custom Markdown-it plugin or a more advanced parsing strategy, but this is not covered in the official documentation. Summary:
There is no officially documented way to use custom Vue components inline with plaintext in Nuxt Content Markdown. Only block-level usage is supported according to the current knowledge sources. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@264590999479648268> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?