A powerful, customizable markdown renderer for Svelte with TypeScript support. Built as a successor to the original svelte-markdown package by Pablo Berganza, now maintained and enhanced by Humanspeak, Inc.
- π Full markdown syntax support through Marked
- πͺ Complete TypeScript support with strict typing
- π¨ Customizable component rendering system
- π Secure HTML parsing via HTMLParser2
- π― GitHub-style slug generation for headers
- βΏ WCAG 2.1 accessibility compliance
- π§ͺ Comprehensive test coverage (vitest and playwright)
- π Svelte 5 runes compatibility
npm i -S @humanspeak/svelte-markdown
Or with your preferred package manager:
pnpm add @humanspeak/svelte-markdown
yarn add @humanspeak/svelte-markdown
This package carefully selects its dependencies to provide a robust and maintainable solution:
-
marked
- Industry-standard markdown parser
- Battle-tested in production
- Extensive security features
-
github-slugger
- GitHub-style heading ID generation
- Unicode support
- Collision handling
-
htmlparser2
- High-performance HTML parsing
- Streaming capabilities
- Security-focused design
<script lang="ts">
import SvelteMarkdown from '@humanspeak/svelte-markdown'
const source = `
# This is a header
This is a paragraph with **bold** and <em>mixed HTML</em>.
* List item with \`inline code\`
* And a [link](https://svelte.dev)
* With nested items
* Supporting full markdown
`
</script>
<SvelteMarkdown {source} />
The package is written in TypeScript and includes full type definitions:
import type {
Renderers,
Token,
TokensList,
SvelteMarkdownOptions
} from '@humanspeak/svelte-markdown'
Here's a complete example of a custom renderer with TypeScript support:
<script lang="ts">
import type { Snippet } from 'svelte'
interface Props {
children?: Snippet
href?: string
title?: string
text?: string
}
const { href = '', title = '', text = '', children }: Props = $props()
</script>
<a {href} {title} class="custom-link">
{@render children?.() ?? text}
</a>
The package excels at handling complex nested structures and mixed content:
| Type | Content |
| ---------- | --------------------------------------- |
| Nested | <div>**bold** and _italic_</div> |
| Mixed List | <ul><li>Item 1</li><li>Item 2</li></ul> |
| Code | <code>`inline code`</code> |
Seamlessly mix HTML and Markdown:
<div style="color: blue">
### This is a Markdown heading inside HTML
And here's some **bold** text too!
</div>
<details>
<summary>Click to expand</summary>
- This is a markdown list
- Inside an HTML details element
- Supporting **bold** and _italic_ text
</details>
text
- Text within other elementsparagraph
- Paragraph (<p>
)em
- Emphasis (<em>
)strong
- Strong/bold (<strong>
)hr
- Horizontal rule (<hr>
)blockquote
- Block quote (<blockquote>
)del
- Deleted/strike-through (<del>
)link
- Link (<a>
)image
- Image (<img>
)table
- Table (<table>
)tablehead
- Table head (<thead>
)tablebody
- Table body (<tbody>
)tablerow
- Table row (<tr>
)tablecell
- Table cell (<td>
/<th>
)list
- List (<ul>
/<ol>
)listitem
- List item (<li>
)heading
- Heading (<h1>
-<h6>
)codespan
- Inline code (<code>
)code
- Block of code (<pre><code>
)html
- HTML node
For fine-grained styling:
orderedlistitem
- Items in ordered listsunorderedlistitem
- Items in unordered lists
The html
renderer is special and can be configured separately to handle HTML elements:
Element | Description |
---|---|
div |
Division element |
span |
Inline container |
table |
HTML table structure |
thead |
Table header group |
tbody |
Table body group |
tr |
Table row |
td |
Table data cell |
th |
Table header cell |
ul |
Unordered list |
ol |
Ordered list |
li |
List item |
code |
Code block |
em |
Emphasized text |
strong |
Strong text |
a |
Anchor/link |
img |
Image |
You can customize HTML rendering by providing your own components:
import type { HtmlRenderers } from '@humanspeak/svelte-markdown'
const customHtmlRenderers: Partial<HtmlRenderers> = {
div: YourCustomDivComponent,
span: YourCustomSpanComponent
}
The component emits a parsed
event when tokens are calculated:
<script lang="ts">
import SvelteMarkdown from '@humanspeak/svelte-markdown'
const handleParsed = (tokens: Token[] | TokensList) => {
console.log('Parsed tokens:', tokens)
}
</script>
<SvelteMarkdown {source} parsed={handleParsed} />
Prop | Type | Description |
---|---|---|
source | string | Token[] |
Markdown content or pre-parsed tokens |
renderers | Partial<Renderers> |
Custom component overrides |
options | SvelteMarkdownOptions |
Marked parser configuration |
isInline | boolean |
Toggle inline parsing mode |
MIT Β© Humanspeak, Inc.
Made with β₯ by Humanspeak