Skip to content

Use with your framework

generateSvg() returns an SVG string and the core has no DOM dependency, so any framework can render a diagram by injecting that string. There is nothing React-specific in the core — sfn-diagram-react exists for convenience, not necessity.

Each snippet below is the whole integration. See API reference for the full option set (theme, layout, showIcons, …) and generateMermaid if you would rather emit Mermaid than SVG.

Every snippet renders a static diagram. Want pan/zoom, search, and a click-a-state detail panel too, without wiring it up yourself? <sfn-diagram> is a custom element built on the exact same generateSvg() output — it works in every framework below, including the ones with a static snippet here.

Svelte 5

<script lang="ts">
import { generateSvg } from 'sfn-diagram';
let { definition } = $props();
const svg = $derived(generateSvg({ aslDefinition: definition }).svg);
</script>
{@html svg}

Vue 3

<script setup lang="ts">
import { computed } from 'vue';
import { generateSvg } from 'sfn-diagram';
import type { AslDefinition } from 'sfn-diagram';
const props = defineProps<{ definition: AslDefinition | string }>();
const svg = computed(() => generateSvg({ aslDefinition: props.definition }).svg);
</script>
<template>
<div v-html="svg" />
</template>

Solid

import { createMemo } from 'solid-js';
import { generateSvg } from 'sfn-diagram';
import type { AslDefinition } from 'sfn-diagram';
export function SfnDiagram(props: { definition: AslDefinition | string }) {
const svg = createMemo(() => generateSvg({ aslDefinition: props.definition }).svg);
return <div innerHTML={svg()} />;
}

Preact

import { generateSvg } from 'sfn-diagram';
import type { AslDefinition } from 'sfn-diagram';
export function SfnDiagram({ definition }: { definition: AslDefinition | string }) {
const { svg } = generateSvg({ aslDefinition: definition });
return <div dangerouslySetInnerHTML={{ __html: svg }} />;
}

Angular

[innerHTML] strips SVG unless the value is marked trusted, so the sanitizer bypass is required.

import { Component, computed, inject, input } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { generateSvg } from 'sfn-diagram';
import type { AslDefinition } from 'sfn-diagram';
@Component({
selector: 'sfn-diagram',
template: `<div [innerHTML]="svg()"></div>`,
})
export class SfnDiagramComponent {
readonly definition = input.required<AslDefinition | string>();
private readonly sanitizer = inject(DomSanitizer);
readonly svg = computed(() =>
this.sanitizer.bypassSecurityTrustHtml(
generateSvg({ aslDefinition: this.definition() }).svg
)
);
}

Astro

Astro runs the frontmatter at build time, so the diagram ships as static markup with zero client-side JavaScript — the DOM-free core at its best. (Astro also hosts React islands, so sfn-diagram-react works there too if you need interactivity.)

---
import { generateSvg } from 'sfn-diagram';
// `?raw` gives the file as a string, which `aslDefinition` accepts directly
import definition from '../workflows/order-processing.asl.json?raw';
const { svg } = generateSvg({ aslDefinition: definition, theme: 'light' });
---
<Fragment set:html={svg} />

Hono

import { Hono } from 'hono';
import { html, raw } from 'hono/html';
import { generateSvg } from 'sfn-diagram';
// `?raw` gives the file as a string, which `aslDefinition` accepts directly
import definition from '../workflows/order-processing.asl.json?raw';
const app = new Hono();
app.get('/diagram', (c) => {
const { svg } = generateSvg({ aslDefinition: definition });
return c.html(html`<div>${raw(svg)}</div>`);
});

raw() is Hono’s equivalent of the other frameworks’ “unsafe HTML” escape hatches — html template literals HTML-escape interpolated values by default, so an unescaped SVG string needs it explicitly marked safe.

Vanilla JS / htmx / anything else

import { generateSvg } from 'sfn-diagram';
const response = await fetch('/workflows/order-processing.asl.json');
const { svg } = generateSvg({ aslDefinition: await response.text() });
document.querySelector('#diagram').innerHTML = svg;

On the “unsafe HTML” APIs. Every snippet above uses its framework’s raw-HTML escape hatch ({@html}, v-html, innerHTML, dangerouslySetInnerHTML, raw()). The SVG builder HTML-escapes every attribute and text value it emits, following the HTML serialization algorithm, so state names, comments, and choice conditions taken from your ASL are escaped before they reach the string.