logo

Markdown Renderers

@humanspeak/svelte-markdown includes 24 built-in renderer components that handle the various token types produced by the Marked parser. Each renderer is a Svelte 5 component that accepts specific props based on the token type it handles.

You can override any renderer by passing a custom component via the renderers prop on SvelteMarkdown.

Renderer Keys

The complete list of renderer keys is available at runtime via the rendererKeys export:

import { rendererKeys } from '@humanspeak/svelte-markdown'
import { rendererKeys } from '@humanspeak/svelte-markdown'

Block-Level Renderers

heading

Renders heading elements (<h1> through <h6>). When headerIds is enabled in options, each heading receives an id attribute generated by github-slugger.

Props:

PropTypeDescription
depthnumberHeading level (1-6)
rawstringRaw heading text
textstringPlain text content (used for ID generation)
optionsSvelteMarkdownOptionsParser options (for headerIds and headerPrefix)
slug(val: string) => stringSlugification function
childrenSnippetRendered child content

Default output: <h1 id="...">, <h2 id="...">, etc.

paragraph

Renders paragraph elements.

Props:

PropTypeDescription
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content
childrenSnippetRendered child content

Default output: <p>

blockquote

Renders blockquote elements.

Props:

PropTypeDescription
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content
childrenSnippetRendered child content

Default output: <blockquote>

code

Renders fenced code blocks with a language class for syntax highlighting.

Props:

PropTypeDescription
langstringLanguage identifier (e.g., "javascript", "python")
textstringCode content
codeBlockStyle'indented' \| undefinedStyle of code block (indented vs fenced)

Default output: <pre class="{lang}"><code>{text}</code></pre>

hr

Renders horizontal rules. This renderer accepts no props.

Default output: <hr />

List Renderers

list

Renders ordered and unordered lists.

Props:

PropTypeDescription
orderedbooleantrue for ordered lists, false for unordered
startnumberStarting number for ordered lists (default: 1)
looseboolean \| undefinedWhether the list has loose spacing
childrenSnippetRendered child content (list items)

Default output: <ol start="..."> or <ul>

listitem

Renders individual list items.

Props:

PropTypeDescription
textstring \| undefinedRaw text content of the list item
taskboolean \| undefinedWhether this is a task/checkbox list item
checkedboolean \| undefinedCheckbox state (only meaningful when task is true)
looseboolean \| undefinedWhether the item has loose spacing
childrenSnippetRendered child content
listItemIndexnumber \| undefinedIndex of this item within the list

Default output: <li>

orderedlistitem

A specialized renderer for ordered list items. Set to null by default, which means the regular listitem renderer is used. Override this to render ordered list items differently from unordered ones.

Default value: null (falls back to listitem)

unorderedlistitem

A specialized renderer for unordered list items. Set to null by default, which means the regular listitem renderer is used. Override this to render unordered list items differently from ordered ones.

Default value: null (falls back to listitem)

Table Renderers

table

Renders the outer table wrapper element.

Props:

PropTypeDescription
childrenSnippetRendered child content (thead and tbody)

Default output: <table>

tablehead

Renders the table head section.

Props:

PropTypeDescription
childrenSnippetRendered child content (header row)

Default output: <thead>

tablebody

Renders the table body section.

Props:

PropTypeDescription
childrenSnippetRendered child content (body rows)

Default output: <tbody>

tablerow

Renders individual table rows.

Props:

PropTypeDescription
childrenSnippetRendered child content (cells)

Default output: <tr>

tablecell

Renders individual table cells. Outputs either <th> or <td> based on the header prop, with optional text alignment.

Props:

PropTypeDescription
headerbooleantrue for header cells, false for data cells
align'left' \| 'center' \| 'right' \| 'justify' \| 'char' \| null \| undefinedText alignment
childrenSnippetRendered child content

Default output: <th style="text-align: ..."> or <td style="text-align: ...">

Inline Renderers

text

Renders inline text content. This is a passthrough renderer that renders its children directly without any wrapping element.

Props:

PropTypeDescription
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content
childrenSnippetRendered child content

Default output: (no wrapper — renders children directly)

link

Renders anchor links.

Props:

PropTypeDescription
hrefstringLink URL
titlestring \| undefinedLink title attribute
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content of the link
childrenSnippetRendered child content (link text)

Default output: <a href="..." title="...">

image

Renders images with built-in lazy loading and fade-in support via IntersectionObserver.

Props:

PropTypeDescription
hrefstringImage source URL
titlestring \| undefinedImage title attribute
textstringAlt text for the image
rawstring \| undefinedRaw markdown source
lazybooleanEnable lazy loading (default: true)
fadeInbooleanEnable fade-in animation on load (default: true)

Default output: <img src="..." alt="..." title="..." loading="lazy">

The default Image renderer uses IntersectionObserver to defer loading images until they are near the viewport (with a 50px root margin). Images start with opacity: 0 and transition to full opacity when loaded.

em

Renders emphasized (italic) text.

Props:

PropTypeDescription
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content
childrenSnippetRendered child content

Default output: <em>

strong

Renders strong (bold) text.

Props:

PropTypeDescription
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content
childrenSnippetRendered child content

Default output: <strong>

codespan

Renders inline code spans.

Props:

PropTypeDescription
rawstringRaw code text including backticks
textstring \| undefinedDecoded text content (backticks stripped)

Default output: <code>

del

Renders strikethrough text (requires GFM to be enabled).

Props:

PropTypeDescription
rawstring \| undefinedRaw markdown source
textstring \| undefinedPlain text content
childrenSnippetRendered child content

Default output: <del>

br

Renders line breaks.

Props:

PropTypeDescription
childrenSnippetAny trailing content

Default output: <br />

Special Renderers

escape

Renders escaped characters (e.g., \* renders as *).

Props:

PropTypeDescription
textstringThe escaped character
rawstring \| undefinedRaw markdown source (e.g., \*)

Default output: plain text (no wrapper)

rawtext

Renders raw text content that is not part of any other token.

Props:

PropTypeDescription
textstringRaw text content

Default output: plain text (no wrapper)

Overriding a Renderer

To override any renderer, create a Svelte component that accepts the same props and pass it via the renderers prop:

<!-- CustomHeading.svelte -->
<script lang="ts">
    import type { Snippet } from 'svelte'

    interface Props {
        depth: number
        raw: string
        text: string
        children?: Snippet
    }

    const { depth, text, children }: Props = $props()
</script>

<div class="heading heading-{depth}" data-text={text}>
    {@render children?.()}
</div>
<!-- CustomHeading.svelte -->
<script lang="ts">
    import type { Snippet } from 'svelte'

    interface Props {
        depth: number
        raw: string
        text: string
        children?: Snippet
    }

    const { depth, text, children }: Props = $props()
</script>

<div class="heading heading-{depth}" data-text={text}>
    {@render children?.()}
</div>
<!-- App.svelte -->
<script>
    import SvelteMarkdown from '@humanspeak/svelte-markdown'
    import CustomHeading from './CustomHeading.svelte'
</script>

<SvelteMarkdown
    source="# My Heading"
    renderers={{ heading: CustomHeading }}
/>
<!-- App.svelte -->
<script>
    import SvelteMarkdown from '@humanspeak/svelte-markdown'
    import CustomHeading from './CustomHeading.svelte'
</script>

<SvelteMarkdown
    source="# My Heading"
    renderers={{ heading: CustomHeading }}
/>

Related