Skip to content

πŸ“ Fast, lightweight Markdown renderer component for Svelte applications with full CommonMark support

License

Notifications You must be signed in to change notification settings

humanspeak/svelte-markdown

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@humanspeak/svelte-markdown

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.

NPM version Build Status Coverage Status License Downloads CodeQL Code Style: Trunk TypeScript Types Maintenance

Features

  • πŸš€ 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

Installation

npm i -S @humanspeak/svelte-markdown

Or with your preferred package manager:

pnpm add @humanspeak/svelte-markdown
yarn add @humanspeak/svelte-markdown

External Dependencies

This package carefully selects its dependencies to provide a robust and maintainable solution:

Core Dependencies

  • 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

Basic Usage

<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} />

TypeScript Support

The package is written in TypeScript and includes full type definitions:

import type {
    Renderers,
    Token,
    TokensList,
    SvelteMarkdownOptions
} from '@humanspeak/svelte-markdown'

Custom Renderer Example

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>

Advanced Features

Table Support with Mixed Content

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>              |

HTML in Markdown

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>

Available Renderers

  • text - Text within other elements
  • paragraph - 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

Optional List Renderers

For fine-grained styling:

  • orderedlistitem - Items in ordered lists
  • unorderedlistitem - Items in unordered lists

HTML Renderers

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
}

Events

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} />

Props

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

License

MIT Β© Humanspeak, Inc.

Credits

Made with β™₯ by Humanspeak