Skip to content

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 ​

TypeNode
headingHeadings h1-h6
paragraphParagraph
codeCode block (default rendering only)
listList
listItemList item
tableTable
blockquoteBlockquote
thematicBreakDivider
imageImage
linkLink
inlineCodeInline 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:

  1. customCodeBlocks: Language-specific custom components (e.g., echarts, mermaid)
  2. Built-in Mermaid: Automatic Mermaid diagram rendering
  3. components['code']: Custom default code block (if provided)
  4. 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
  • customCodeBlocks configurations 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:

PropTypeDescription
nodeCodeThe code node from mdast
themestringShiki theme name
fallbackThemestringFallback theme when loading fails
disableHighlightbooleanWhether to disable syntax highlighting

The node object contains:

  • node.value: The code content as a string
  • node.lang: The language identifier (e.g., 'typescript', 'python')
  • node.meta: Optional metadata after the language identifier