# @humanspeak/svelte-markdown — full reference > Concatenated dump of every doc page under https://markdown.svelte.page/docs. > Each section is bounded by an HTML comment with the source URL, > so agents can extract individual pages or cite a specific section. --- # Rendering AI Agent Output > Render streaming HTML and markdown from AI coding agents with @humanspeak/svelte-markdown, including XSS-safe defaults and custom HTML tag routing. **Source:** [https://markdown.svelte.page/docs/advanced/agent-output](https://markdown.svelte.page/docs/advanced/agent-output) --- Modern AI coding agents — Claude Code, Codex, ChatGPT, and agentic workflows — increasingly emit HTML alongside markdown to produce richer output: design mockups, dashboards, code review explainers, interactive artifacts, throwaway editors, status reports. `@humanspeak/svelte-markdown` is built to render this kind of mixed output safely and incrementally. For background on why HTML has become a common agent output format, see [Thariq's post on the unreasonable effectiveness of HTML](https://x.com/trq212/status/2052809885763747935). ## Why This Package Four properties make rendering agent output particularly demanding, and the defaults here handle each one: 1. **Agents stream their output.** You need to render a partial response as chunks arrive, not after the whole message is done. 2. **Agents mix markdown and HTML freely.** A single response can include headings, fenced code, tables, SVG, custom elements, and inline `` tags side by side. 3. **Agents can produce dangerous markup.** A prompt-injected response might contain `javascript:` URLs, inline event handlers, or `' // Block all attributes on iframes, use defaults for everything else function customSanitizeAttributes(attributes, context, sanitizeUrl) { if (context.tag === 'iframe') return {} return defaultSanitizeAttributes(attributes, context, sanitizeUrl) } ``` ### Disabling Sanitization If you fully trust your markdown source and need to allow all URLs and attributes, use the passthrough functions: ```svelte ``` > **Warning:** Only disable sanitization for content you fully control. Never use passthrough functions with user-generated input. ### Sanitization API Reference | Export | Type | Description | |--------|------|-------------| | `defaultSanitizeUrl` | `SanitizeUrlFn` | Protocol allowlist (http, https, mailto, tel, relative) | | `defaultSanitizeAttributes` | `SanitizeAttributesFn` | Strips `on*` handlers, validates URL attributes | | `unsanitizedUrl` | `SanitizeUrlFn` | Passthrough -- allows all URLs | | `unsanitizedAttributes` | `SanitizeAttributesFn` | Passthrough -- allows all attributes | | `SanitizeUrlFn` | Type | `(url: string, context: SanitizeContext) => string` | | `SanitizeAttributesFn` | Type | `(attributes: Record, context: SanitizeContext, sanitizeUrl: SanitizeUrlFn) => Record` | | `SanitizeContext` | Type | `{ type: string, tag: string }` | ## Known Gaps (Not Handled by Defaults) The built-in sanitizer covers URL protocols and event handlers, but some classes of risk pass through and need either custom sanitizers or HTML tag filtering: - **Inline `style="..."` attributes are not sanitized.** They pass through unchanged (only `on*` and `srcdoc` are stripped). Modern browsers do not execute JavaScript via CSS, but visual hijacking (`display: none`) and exfiltration via background-image URLs are possible. - **`') const safeHtml = allowHtmlOnly([ 'strong', 'em', 'a', 'code', 'pre', 'ul', 'ol', 'li', 'p', 'br', 'hr', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'table', 'thead', 'tbody', 'tr', 'th', 'td' ]) ``` ### Block Specific Dangerous Tags ```svelte ``` ## Restricting Markdown Elements You can also restrict which markdown elements are rendered: ```svelte ``` ## External Sanitization For applications that require additional protection, you can sanitize the markdown source before passing it to `SvelteMarkdown`. Note that input-level sanitizers like DOMPurify operate on HTML, not Markdown syntax -- they will not catch Markdown-native injection vectors like `[Click](javascript:alert('XSS'))`. The built-in URL sanitization handles this automatically. ### Using DOMPurify (Combined with Built-in Sanitization) ```svelte ``` ### Using the `parsed` Callback You can inspect and filter tokens after parsing: ```svelte ``` ## Security Recommendations ### For user-generated content: 1. **Use the built-in sanitization** (enabled by default). This blocks dangerous URL protocols and event handler attributes. 2. **Block all HTML** using `buildUnsupportedHTML()` for the strictest protection. 3. If you need some HTML, use `allowHtmlOnly()` with a strict allowlist of safe tags. 4. Consider combining with DOMPurify for defense-in-depth. ### For trusted content (CMS, documentation, etc.): 1. The default sanitization is generally sufficient for trusted sources. 2. Use `excludeHtmlOnly()` to block specific tags you do not want (e.g., `iframe`, `form`). ### General best practices: 1. **Validate input on the server.** Client-side filtering adds defense-in-depth but should not be your only protection. 2. **Use Content Security Policy (CSP) headers.** Restrict inline scripts and other dangerous behaviors at the browser level. 3. **Keep dependencies updated.** Regularly update `@humanspeak/svelte-markdown`, Marked, and HTMLParser2 to get security fixes. 4. **Audit your custom renderers.** If you create custom renderers, make sure they do not use `{@html}` with untrusted content. ## What About ``) rather than executing or applying them. HTMLParser2 processes HTML structurally and does not execute scripts on its own. This means dangerous content is visible but inert. For untrusted input you should still block or sanitize HTML — escaped script text in a document is rarely the user experience you want. ## Related - [Allow/Deny Filtering](/docs/advanced/allow-deny) -- detailed filtering function documentation - [HTML Renderers](/docs/renderers/html-renderers) -- all HTML tag renderers - [HTML Filtering Examples](/docs/examples/html-filtering) -- practical filtering examples # Token Caching > Use built-in LRU token caching in @humanspeak/svelte-markdown to speed repeat renders, tune TTL and cache size, and inspect parse performance. **Source:** [https://markdown.svelte.page/docs/advanced/token-caching](https://markdown.svelte.page/docs/advanced/token-caching) --- `@humanspeak/svelte-markdown` includes a built-in LRU (Least Recently Used) token cache that dramatically improves performance for repeated renders of the same markdown content. When you pass a string to the `source` prop, the parsed tokens are automatically cached and reused on subsequent renders. Under the hood, the caching layer is powered by [`@humanspeak/memory-cache`](https://www.npmjs.com/package/@humanspeak/memory-cache) -- a generic in-memory cache with TTL expiration and LRU eviction. `TokenCache` extends the `MemoryCache` class from that package, adding markdown-specific convenience methods on top. You get all the battle-tested caching primitives (size limits, TTL, LRU eviction) for free. ## Performance Characteristics | Operation | Time | |-----------|------| | Cache hit (cached content) | < 1ms | | Cache miss (fresh parse) | 50-200ms (depends on document size) | | Hash computation (10KB doc) | ~0.05ms | | Hash computation (100KB doc) | ~0.5ms | | Memory usage (50 cached docs) | ~5MB | This means cached re-renders are **50-200x faster** than fresh parsing. ## How It Works 1. When `SvelteMarkdown` receives a string `source`, it generates a cache key from the source content and parser options using a fast FNV-1a hash. 2. It checks the global `tokenCache` singleton for a cached entry. 3. On a cache hit, the cached tokens are returned immediately without parsing. 4. On a cache miss, the markdown is parsed via Marked's lexer, and the resulting tokens are stored in the cache. 5. When the cache reaches its `maxSize`, the least recently used entry is evicted. 6. Entries automatically expire after the configured TTL (time-to-live). Pre-parsed token arrays passed to `source` bypass the cache entirely. ## Default Configuration The global `tokenCache` singleton is created with these defaults: | Setting | Default | Description | |---------|---------|-------------| | `maxSize` | `50` | Maximum number of cached documents | | `ttl` | `300000` (5 minutes) | Time-to-live in milliseconds | ## Using the Global Cache The global singleton is shared across all `SvelteMarkdown` instances in your application: ```typescript import { tokenCache } from '@humanspeak/svelte-markdown' // Check how many documents are cached console.log(tokenCache.size) // Clear all cached tokens tokenCache.clearAllTokens() // Check if specific content is cached const isCached = tokenCache.hasTokens(markdownString, { gfm: true }) // Manually retrieve cached tokens const tokens = tokenCache.getTokens(markdownString, { gfm: true }) // Manually cache tokens tokenCache.setTokens(markdownString, { gfm: true }, parsedTokens) // Remove a specific cached entry tokenCache.deleteTokens(markdownString, { gfm: true }) ``` ## Creating a Custom TokenCache If you need different cache settings (e.g., for a high-traffic application or memory-constrained environment), you can create your own `TokenCache` instance: ```typescript import { TokenCache } from '@humanspeak/svelte-markdown' const customCache = new TokenCache({ maxSize: 200, // Cache more documents ttl: 15 * 60 * 1000 // 15-minute TTL }) ``` ## TokenCache API `TokenCache` extends `MemoryCache` and adds markdown-specific convenience methods. ### Constructor ```typescript new TokenCache(options?: { maxSize?: number; ttl?: number }) ``` | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `maxSize` | `number` | `50` | Maximum number of cached documents | | `ttl` | `number` | `300000` | Time-to-live in milliseconds | ### Methods #### `getTokens(source, options)` Retrieve cached tokens for the given source and options. Returns `undefined` if not cached or expired. ```typescript const tokens = cache.getTokens(markdown, options) ``` #### `setTokens(source, options, tokens)` Store parsed tokens in the cache. If the cache is full, the least recently used entry is evicted. ```typescript cache.setTokens(markdown, options, tokens) ``` #### `hasTokens(source, options)` Check whether tokens are cached without retrieving them. ```typescript if (cache.hasTokens(markdown, options)) { console.log('Cache hit') } ``` #### `deleteTokens(source, options)` Remove a specific cached entry. Returns `true` if the entry was removed, `false` if not found. ```typescript cache.deleteTokens(markdown, options) ``` #### `clearAllTokens()` Remove all entries from the cache. ```typescript cache.clearAllTokens() ``` ### Inherited from MemoryCache `TokenCache` inherits all methods from [`MemoryCache`](https://www.npmjs.com/package/@humanspeak/memory-cache) (`@humanspeak/memory-cache`), including: - `get(key)` -- retrieve by raw key - `set(key, value)` -- store by raw key - `has(key)` -- check existence by raw key - `delete(key)` -- remove by raw key - `clear()` -- remove all entries - `size` -- number of cached entries ## Cache Key Generation Cache keys are generated by hashing both the source content and the parser options: ``` key = hash(source) + ":" + hash(JSON.stringify(options)) ``` This ensures that the same markdown parsed with different options (e.g., `gfm: true` vs `gfm: false`) produces separate cache entries. The hash function uses FNV-1a, a fast non-cryptographic hash algorithm optimized for speed and good distribution. It operates in a single pass through the string. ## When Caching Is Bypassed Caching is automatically bypassed in these cases: - **Pre-parsed tokens**: When `source` is an array of `Token[]`, no parsing or caching occurs. - **Empty string**: When `source` is `''`, an empty array is returned directly. ## Best Practices 1. **Let the default cache work for you.** In most applications, the global singleton with its default settings is sufficient. 2. **Increase `maxSize` for content-heavy apps.** If your application renders many unique markdown documents, increase the cache size to reduce re-parsing. 3. **Reduce TTL for dynamic content.** If your markdown content changes frequently, use a shorter TTL to avoid serving stale cached tokens. 4. **Use `clearAllTokens()` when content updates.** If you know the source content has changed (e.g., after a CMS update), clear the cache to force re-parsing. 5. **Pre-parse tokens for static content.** For content that never changes, parse it once and pass the tokens directly to avoid cache overhead entirely. ## Related - [SvelteMarkdown Component](/docs/api/svelte-markdown) -- main component documentation - [Types & Exports](/docs/api/types) -- `TokenCache`, `MemoryCache`, `tokenCache` exports # Tree Shaking > Keep @humanspeak/svelte-markdown bundles lean with subpath imports, optional peer dependencies, and bundler practices for KaTeX and Mermaid. **Source:** [https://markdown.svelte.page/docs/advanced/tree-shaking](https://markdown.svelte.page/docs/advanced/tree-shaking) --- `@humanspeak/svelte-markdown` is designed so the core markdown component does not force optional extension payloads into your app. The easiest way to keep that true in your own bundle is to import the narrowest entrypoint that matches what you actually render. ## Recommended Imports For plain markdown, import only the component: ```svelte ``` Use the root package when you need helpers, types, sanitizer utilities, or renderer maps from the public API: ```svelte ``` For extensions, prefer the extension family subpath: ```svelte ``` The compatibility barrel still works: ```ts import { markedKatex, KatexRenderer } from '@humanspeak/svelte-markdown/extensions' ``` Use it when convenience matters more than a visibly narrow import. For bundle-sensitive code, the family subpaths make your intent clearer to both people and bundlers. ## Optional Peer Payloads The extension tokenizers are small parser helpers. The renderer components are where heavy optional peers enter. | Import | Pulls heavy peer into initial bundle? | Notes | |--------|---------------------------------------|-------| | `@humanspeak/svelte-markdown/SvelteMarkdown` | No | Core component only. | | `markedKatex` from `/extensions/katex` | No | Tokenizes math; does not import `katex`. | | `KatexRenderer` from `/extensions/katex` | Yes, `katex` | Uses `katex.renderToString()` synchronously. | | `markedMermaid` from `/extensions/mermaid` | No | Tokenizes Mermaid fences; does not import `mermaid`. | | `MermaidRenderer` from `/extensions/mermaid` | No initial `mermaid` chunk | Dynamically imports Mermaid in the browser. | This means you can parse math or diagrams without paying for the renderer until you actually import the renderer path. If you provide your own renderer or snippet, your imports decide what ships. ## Environment Best Practices ### SvelteKit and Vite Use ESM imports and leave dependency pre-bundling to Vite. Avoid importing every extension from the compatibility barrel in shared modules if a route only needs one family. ```svelte ``` If only one route needs KaTeX or Mermaid, import those renderers in that route or route-level component instead of a shared app shell. ### SSR `KatexRenderer` is synchronous and works during SSR. `MermaidRenderer` is browser-only internally: it waits for mount, then dynamically imports Mermaid and renders the diagram. That keeps Mermaid out of the server render path and out of the initial client graph. For server-rendered pages that must avoid any client-side Mermaid work, use `markedMermaid()` with a custom placeholder renderer or snippet and hydrate a diagram component only where needed. ### Custom Renderers and Snippets Tree shaking follows your imports. If a snippet imports `katex`, the page that owns the snippet pays for KaTeX: ```svelte {#snippet inlineKatex(props)} {@html katex.renderToString(props.text, { throwOnError: false })} {/snippet} ``` That is fine when the route needs math. Keep that import out of routes that do not. ### Lazy Route Loading For apps with a documentation or content area, put markdown features behind route-level imports. A marketing page that renders plain markdown does not need to share the same module that imports math, diagrams, footnotes, and alerts. ```ts // Good: math route owns its math renderer import. import { markedKatex, KatexRenderer } from '@humanspeak/svelte-markdown/extensions/katex' // Avoid in app-wide modules unless every page needs every extension. import { AlertRenderer, FootnoteRef, FootnoteSection, KatexRenderer, MermaidRenderer } from '@humanspeak/svelte-markdown/extensions' ``` ## Checking Your Bundle For Vite apps, inspect the production bundle after a build: ```bash npm run build ``` For the most reliable report, add a Rollup visualizer plugin to your app build and confirm: - Plain markdown routes do not include KaTeX or Mermaid. - KaTeX appears only where `KatexRenderer`, `katex`, or a math snippet imports it. - Mermaid appears behind a dynamic chunk when using `MermaidRenderer`. As a quick heuristic, you can also search generated client assets for distinctive library strings. These text checks may need adjustment for your minifier or build output: ```bash grep -R "KaTeX" .svelte-kit/output/client/_app grep -R "mermaid" .svelte-kit/output/client/_app ``` The package also has an internal verification script: ```bash pnpm test:tree-shaking ``` That script builds small consumer entries and checks that the published subpaths behave as expected. ## Related Pages - [Marked Extensions](/docs/advanced/marked-extensions) -- KaTeX, Mermaid, alerts, footnotes, and custom extension setup - [Token Caching](/docs/advanced/token-caching) -- parser cache behavior and extension identity - [SvelteMarkdown API](/docs/api/svelte-markdown) -- component props and public imports # SvelteMarkdown Component > Use the SvelteMarkdown component API: props, renderers, snippets, extensions, parsed callbacks, inline mode, token input, and TypeScript types. **Source:** [https://markdown.svelte.page/docs/api/svelte-markdown](https://markdown.svelte.page/docs/api/svelte-markdown) --- The `SvelteMarkdown` component is the main entry point for rendering markdown content. It accepts a markdown string (or pre-parsed tokens), parses it, and renders the result through a composable system of Svelte renderer components. ```svelte ``` ## Props ### `source` - **Type:** `string | Token[]` - **Default:** `[]` The markdown content to render. Can be either a raw markdown string or an array of pre-parsed [Marked tokens](https://marked.js.org/using_pro#lexer). When a string is provided, it is parsed using Marked's lexer (with built-in token caching for performance). When pre-parsed tokens are provided, parsing is skipped entirely. When using the imperative streaming API (`bind:this` + `writeChunk()`), `source` must be a string. Token-array sources remain read-only. ```svelte ``` ### `renderers` - **Type:** `Partial` - **Default:** `{}` An object mapping renderer keys to custom Svelte components. Any keys you provide will override the corresponding default renderer. Keys you omit will use the built-in defaults. The `renderers` object supports two categories of keys: 1. **Markdown renderer keys** (e.g., `heading`, `paragraph`, `link`, `code`) -- see [Markdown Renderers](/docs/renderers/markdown-renderers) 2. **`html`** -- an object mapping HTML tag names to components -- see [HTML Renderers](/docs/renderers/html-renderers) ```svelte ``` To override HTML tag renderers within markdown, use the nested `html` key: ```svelte ``` When you provide a partial `html` object, it is merged with the defaults -- your overrides replace only the tags you specify, and all other HTML tags continue using their built-in renderers. ### `options` - **Type:** `Partial` - **Default:** `{}` Configuration options for the markdown parser. These are merged with the default options. ```svelte ``` #### Available Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `headerIds` | `boolean` | `true` | Generate `id` attributes on heading elements using [github-slugger](https://github.com/Flet/github-slugger) | | `headerPrefix` | `string` | `''` | String to prepend to generated heading IDs | | `gfm` | `boolean` | `true` | Enable [GitHub Flavored Markdown](https://github.github.com/gfm/) (tables, strikethrough, task lists, etc.) | | `breaks` | `boolean` | `false` | Convert single newlines in paragraphs to `
` elements | The options object also passes through Marked's own configuration properties such as `async`, `pedantic`, `silent`, `tokenizer`, and `walkTokens`. ### `isInline` - **Type:** `boolean` - **Default:** `false` When set to `true`, the markdown is parsed as inline content. This means block-level elements like headings, paragraphs, lists, and blockquotes are not produced. Only inline elements such as bold, italic, links, code spans, and images are rendered. This is useful when you want to embed markdown within a `` or other inline HTML context. ```svelte

Status:

``` ### `streaming` - **Type:** `boolean` - **Default:** `false` Enables optimized rendering for LLM streaming scenarios. When `true`, the component diffs parsed tokens against the previous result and only updates changed DOM nodes, keeping render cost proportional to the change rather than the full document size. ```svelte ``` `streaming` also enables the component instance methods described below. **Note:** `streaming` is automatically disabled when async extensions are used. A console warning is logged in this case. See [LLM Streaming](/docs/advanced/llm-streaming) for usage patterns and performance data. ## Instance Methods When you bind the component instance, `SvelteMarkdown` exposes imperative helpers for streaming writers: ### `writeChunk(chunk)` - **Type:** `(chunk: StreamingChunk) => void` Accepts either a string append chunk or an offset patch object: ```svelte ``` Rules: - String chunks append to the internal buffer. - Object chunks use `{ value, offset }` overwrite semantics, not insert semantics. - Offset writes preserve trailing content after the overwritten span. - If `offset` skips ahead, the gap is padded with spaces. - Offset mode does not support delete or truncate semantics. - The first successful write locks the stream into append mode or offset mode until reset. - Offset chunks require a non-negative safe integer `offset`. - Calls are ignored with a warning when `streaming={false}`, async extensions are active, or `source` is a token array. ### `resetStream(nextSource?)` - **Type:** `(nextSource?: string) => void` Clears the internal streaming buffer and resets mode locking. Pass a string to seed the next stream: ```typescript markdown?.resetStream() markdown?.resetStream('# Seed') ``` Changing the `source` prop also resets the imperative buffer and becomes the new baseline. ### `parsed` - **Type:** `(tokens: Token[] | TokensList) => void` - **Default:** `() => {}` A callback function that is invoked with the parsed token array whenever the source is parsed. This is useful for inspecting the token tree, building a table of contents, or performing other analysis on the parsed output. ```svelte
``` The callback fires reactively via a Svelte `$effect` -- it will be called again whenever the tokens change (e.g., when `source` changes). ## Default Options The full set of default options applied when no `options` prop is provided: ```typescript const defaultOptions: SvelteMarkdownOptions = { async: false, breaks: false, gfm: true, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null, headerIds: true, headerPrefix: '' } ``` ## Token Caching When you pass a string to `source`, the component automatically caches parsed tokens using an internal LRU cache. On subsequent renders with the same source and options, the cached tokens are returned in under 1ms instead of re-parsing (which can take 50-200ms for large documents). The cache is a global singleton (`tokenCache`) shared across all `SvelteMarkdown` instances. It defaults to 50 entries with a 5-minute TTL. See [Token Caching](/docs/advanced/token-caching) for advanced configuration. When you pass pre-parsed tokens to `source`, caching is bypassed entirely. ## Renderer Merging The component merges your custom renderers with the defaults: ```typescript // Internal behavior const combinedRenderers = { ...defaultRenderers, ...renderers, html: renderers.html ? { ...defaultRenderers.html, ...renderers.html } : defaultRenderers.html } ``` This means: - Top-level renderer keys you provide replace the defaults - Top-level renderer keys you omit use the built-in components - For `html`, your overrides are merged with the default HTML renderer map ## Complete Example ```svelte tokens = t} />

Parsed {tokens.length} tokens

``` ## Related - [Types & Exports](/docs/api/types) -- all exported types, functions, and constants - [Markdown Renderers](/docs/renderers/markdown-renderers) -- list of all 24 renderer keys - [Custom Renderers](/docs/renderers/custom-renderers) -- guide to building custom components - [Token Caching](/docs/advanced/token-caching) -- cache configuration and performance # Types & Exports > Explore exported types, functions, constants, cache classes, renderer keys, and utility helpers from @humanspeak/svelte-markdown for Svelte 5. **Source:** [https://markdown.svelte.page/docs/api/types](https://markdown.svelte.page/docs/api/types) --- This page documents every named export from `@humanspeak/svelte-markdown`. The package provides a default export (the component) plus types, utility functions, constants, and cache classes. ## Default Export ### `SvelteMarkdown` The main component. See [SvelteMarkdown Component](/docs/api/svelte-markdown) for full documentation. ```typescript import SvelteMarkdown from '@humanspeak/svelte-markdown' ``` ## Types ### `SvelteMarkdownProps` The props interface for the `SvelteMarkdown` component. ```typescript type SvelteMarkdownProps = { source: Token[] | string renderers?: Partial options?: Partial extensions?: MarkedExtension[] isInline?: boolean streaming?: boolean parsed?: (tokens: Token[] | TokensList) => void } ``` ### `StreamingOffsetChunk` Offset patch payload for imperative streaming writes. ```typescript interface StreamingOffsetChunk { value: string offset: number } ``` ### `StreamingChunk` Union accepted by `writeChunk()`. ```typescript type StreamingChunk = string | StreamingOffsetChunk ``` ### `SvelteMarkdownOptions` Configuration options for the markdown parser. Extends Marked's `MarkedOptions` with additional properties. ```typescript interface SvelteMarkdownOptions extends MarkedOptions { headerIds?: boolean headerPrefix?: string } ``` | Property | Type | Default | Description | |----------|------|---------|-------------| | `headerIds` | `boolean` | `true` | Generate `id` attributes on heading elements | | `headerPrefix` | `string` | `''` | Prefix prepended to generated heading IDs | | `gfm` | `boolean` | `true` | Enable GitHub Flavored Markdown | | `breaks` | `boolean` | `false` | Convert newlines to `
` | Plus all properties from Marked's `MarkedOptions` (e.g., `async`, `pedantic`, `silent`, `tokenizer`, `walkTokens`). ### `Renderers` A type mapping every markdown renderer key to a `RendererComponent`. Includes the special `html` key that maps to `HtmlRenderers`. ```typescript type Renderers = { html: HtmlRenderers // Raw text rawtext: RendererComponent escape: RendererComponent // Block elements heading: RendererComponent paragraph: RendererComponent blockquote: RendererComponent code: RendererComponent list: RendererComponent listitem: RendererComponent hr: RendererComponent // Table elements table: RendererComponent tablehead: RendererComponent tablebody: RendererComponent tablerow: RendererComponent tablecell: RendererComponent // Inline elements text: RendererComponent link: RendererComponent image: RendererComponent em: RendererComponent strong: RendererComponent codespan: RendererComponent br: RendererComponent del: RendererComponent // List variations orderedlistitem: RendererComponent unorderedlistitem: RendererComponent } ``` ### `HtmlRenderers` A string-keyed record mapping HTML tag names to Svelte components (or `null`). ```typescript interface HtmlRenderers { [key: string]: Component | null } ``` ### `RendererComponent` The type for any individual renderer -- a Svelte component, `undefined`, or `null`. ```typescript type RendererComponent = Component | undefined | null ``` ### `Token` Re-exported from [Marked](https://marked.js.org/). Represents a single parsed markdown token. ```typescript import type { Token } from '@humanspeak/svelte-markdown' ``` ### `TokensList` Re-exported from Marked. An array of tokens with additional metadata (e.g., `links`). ```typescript import type { TokensList } from '@humanspeak/svelte-markdown' ``` ## Constants ### `defaultRenderers` The default renderer map used by `SvelteMarkdown` when no `renderers` prop is provided. This is the complete `Renderers` object with all 24 markdown renderers and the `html` map. ```typescript import { defaultRenderers } from '@humanspeak/svelte-markdown' // Inspect the default heading renderer console.log(defaultRenderers.heading) // Use as a base for partial overrides const myRenderers = { ...defaultRenderers, heading: MyCustomHeading } ``` ### `rendererKeys` An array of all valid markdown renderer key names (excluding `html`). Useful for iteration or validation. ```typescript import { rendererKeys } from '@humanspeak/svelte-markdown' console.log(rendererKeys) // ['heading', 'paragraph', 'text', 'image', 'link', 'em', 'escape', // 'strong', 'codespan', 'del', 'table', 'tablehead', 'tablebody', // 'tablerow', 'tablecell', 'list', 'orderedlistitem', // 'unorderedlistitem', 'listitem', 'hr', 'blockquote', 'code', // 'br', 'rawtext'] ``` ### `htmlRendererKeys` An array of all valid HTML renderer tag names. ```typescript import { htmlRendererKeys } from '@humanspeak/svelte-markdown' console.log(htmlRendererKeys) // ['a', 'abbr', 'address', 'article', 'aside', 'audio', 'b', ...] ``` ## Components ### `Html` The default HTML renderer map object. Maps HTML tag names to their corresponding Svelte components. ```typescript import { Html } from '@humanspeak/svelte-markdown' // Access the default
renderer const DivRenderer = Html.div ``` ### `UnsupportedHTML` A component that renders nothing. Used as a placeholder when an HTML tag is blocked via allow/deny filtering. ```typescript import { UnsupportedHTML } from '@humanspeak/svelte-markdown' ``` ### `Unsupported` A component that renders nothing. Used as a placeholder when a markdown renderer is blocked via allow/deny filtering. ```typescript import { Unsupported } from '@humanspeak/svelte-markdown' ``` ## HTML Filtering Functions These functions produce `HtmlRenderers` objects for controlling which HTML tags are rendered. See [Allow/Deny](/docs/advanced/allow-deny) for detailed usage. ### `allowHtmlOnly(allowed)` Returns an `HtmlRenderers` map where only the specified tags use their default (or custom) components. All other tags are set to `UnsupportedHTML`. ```typescript import { allowHtmlOnly } from '@humanspeak/svelte-markdown' // Only allow , , and const html = allowHtmlOnly(['strong', 'em', 'a']) // Allow
with a custom component const html = allowHtmlOnly([['div', MyDiv], 'a']) ``` **Signature:** ```typescript function allowHtmlOnly( allowed: Array ): HtmlRenderers ``` ### `excludeHtmlOnly(excluded, overrides?)` Returns an `HtmlRenderers` map where the specified tags are set to `UnsupportedHTML`. All other tags use their defaults (or optional custom overrides). ```typescript import { excludeHtmlOnly } from '@humanspeak/svelte-markdown' // Block ` const renderers = { html: allowHtmlOnly(['strong', 'em', 'a', 'code', 'br']) } ``` ## Block Specific Tags Block only the tags you consider dangerous, allowing everything else: ```svelte ``` ## Allow Tags with Custom Components Use the tuple syntax to allow specific tags and render them with custom Svelte components: ```svelte {@render children?.()} ``` ```svelte ``` ## Combine HTML and Markdown Filtering Restrict both HTML tags and markdown renderers for maximum control: ```svelte ``` ## Exclude with Overrides Block specific tags while providing custom components for others: ```svelte ``` ## Related - [Allow/Deny](/docs/advanced/allow-deny) -- API reference for all filtering functions - [Security](/docs/advanced/security) -- security best practices - [HTML Renderers](/docs/renderers/html-renderers) -- all 69+ HTML tag renderers # Inline Rendering > Render inline markdown with @humanspeak/svelte-markdown using the isInline prop for span-friendly text, links, emphasis, and compact UI contexts. **Source:** [https://markdown.svelte.page/docs/examples/inline-rendering](https://markdown.svelte.page/docs/examples/inline-rendering) --- The `isInline` prop tells `SvelteMarkdown` to parse the source as inline markdown rather than block-level markdown. This is useful when you want to render markdown within a ``, `

`, or other inline HTML context without producing block-level elements like `

`, `

`, or `