Custom Components
Custom Node Rendering
vue
<script setup>
import { h } from 'vue'
import { IncremarkContent } from '@incremark/vue'
const CustomHeading = {
props: ['node'],
setup(props) {
const level = props.node.depth
return () => h(`h${level}`, { class: 'my-heading' }, props.node.children)
}
}
const components = {
heading: CustomHeading
}
</script>
<template>
<IncremarkContent :content="content" :components="components" />
</template>tsx
import { IncremarkContent } from '@incremark/react'
function CustomHeading({ node, children }) {
const Tag = `h${node.depth}` as keyof JSX.IntrinsicElements
return <Tag className="my-heading">{children}</Tag>
}
const components = {
heading: CustomHeading
}
<IncremarkContent content={content} components={components} />svelte
<script lang="ts">
import { IncremarkContent } from '@incremark/svelte'
import CustomHeading from './CustomHeading.svelte'
const components = {
heading: CustomHeading
}
</script>
<IncremarkContent {content} {components} />tsx
import { IncremarkContent } from '@incremark/solid'
import CustomHeading from './CustomHeading'
const components = {
heading: CustomHeading
}
<IncremarkContent content={content()} components={components} />Component Types
| Type | Node |
|---|---|
heading | Headings h1-h6 |
paragraph | Paragraph |
code | Code block (default rendering only) |
list | List |
listItem | List item |
table | Table |
blockquote | Blockquote |
thematicBreak | Divider |
image | Image |
link | Link |
inlineCode | Inline code |
Code Component Behavior
Important
When customizing the code component, it only replaces the default code block rendering. The built-in Mermaid support and customCodeBlocks logic are preserved.
The code block rendering follows this priority:
- customCodeBlocks: Language-specific custom components (e.g.,
echarts,mermaid) - Built-in Mermaid: Automatic Mermaid diagram rendering
- components['code']: Custom default code block (if provided)
- Default: Built-in syntax highlighting with Shiki
This means:
- If you set
components: { code: MyCodeBlock }, it only affects regular code blocks - Mermaid diagrams will still use the built-in Mermaid renderer
customCodeBlocksconfigurations take precedence
vue
<script setup>
import { IncremarkContent } from '@incremark/vue'
import MyCodeBlock from './MyCodeBlock.vue'
// This only replaces default code rendering
// Mermaid and customCodeBlocks are not affected
const components = {
code: MyCodeBlock
}
</script>
<template>
<IncremarkContent :content="content" :components="components" />
</template>tsx
import { IncremarkContent } from '@incremark/react'
function MyCodeBlock({ node }) {
return (
<pre className="my-code">
<code>{node.value}</code>
</pre>
)
}
const components = {
code: MyCodeBlock
}
<IncremarkContent content={content} components={components} />svelte
<script lang="ts">
import { IncremarkContent } from '@incremark/svelte'
import MyCodeBlock from './MyCodeBlock.svelte'
const components = {
code: MyCodeBlock
}
</script>
<IncremarkContent {content} {components} />tsx
import { IncremarkContent } from '@incremark/solid'
function MyCodeBlock(props: { node: any }) {
return (
<pre class="my-code">
<code>{props.node.value}</code>
</pre>
)
}
const components = {
code: MyCodeBlock
}
<IncremarkContent content={content()} components={components} />Custom Code Component Props
When creating a custom code component, your component will receive these props:
| Prop | Type | Description |
|---|---|---|
node | Code | The code node from mdast |
theme | string | Shiki theme name |
fallbackTheme | string | Fallback theme when loading fails |
disableHighlight | boolean | Whether to disable syntax highlighting |
The node object contains:
node.value: The code content as a stringnode.lang: The language identifier (e.g.,'typescript','python')node.meta: Optional metadata after the language identifier