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
childrenSnippetRendered child content

Default output: <p>

blockquote

Renders blockquote elements.

Props:

PropTypeDescription
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

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)
childrenSnippetRendered child content (list items)

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

listitem

Renders individual list items.

Props:

PropTypeDescription
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
childrenSnippetRendered child content

Default output: (no wrapper — renders children directly)

link

Renders anchor links.

Props:

PropTypeDescription
hrefstringLink URL
titlestring \| undefinedLink title attribute
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
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
childrenSnippetRendered child content

Default output: <em>

strong

Renders strong (bold) text.

Props:

PropTypeDescription
childrenSnippetRendered child content

Default output: <strong>

codespan

Renders inline code spans.

Props:

PropTypeDescription
rawstringRaw code text (backticks are stripped)

Default output: <code>

del

Renders strikethrough text (requires GFM to be enabled).

Props:

PropTypeDescription
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

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