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
- π‘οΈ XSS protection and sanitization
- π¨ Custom Marked extensions support (e.g., GitHub-style alerts)
- π Improved attribute handling and component isolation
- π¦ Enhanced token cleanup and nested content support
- Improved HTML attribute isolation for nested components
- Enhanced token cleanup for better nested content handling
- Added proper attribute inheritance control
- Implemented strict debugging checks in CI/CD pipeline
- Enhanced Playwright E2E test coverage
- Added comprehensive tests for custom extensions
- Improved test reliability with proper component mounting checks
- Added specific test cases for nested component scenarios
- Note: Performance tests use a higher threshold for Firefox due to slower execution in CI environments. See
tests/performance.test.ts
for details.
- Added automated debugging statement detection
- Improved release workflow with GPG signing
- Enhanced PR validation and automated version bumping
- Added manual workflow triggers for better release control
- Implemented monthly cache cleanup
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
}
const { href = '', title = '', children }: Props = $props()
</script>
<a {href} {title} class="custom-link">
{@render children?.()}
</a>
If you would like to extend other renderers please take a look inside the renderers folder for the default implentation of them. If you would like feature additions please feel free to open an issue!
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 noderawtext
- All other text that is going to be included in an object above
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 |
The package includes several security features:
- XSS protection through HTML sanitization
- Secure HTML parsing with HTMLParser2
- Safe handling of HTML entities
- Protection against malicious markdown injection
MIT Β© Humanspeak, Inc.
Made with β₯ by Humanspeak