Skip to main content David Edelstein's Blog

PlantUML component

Published: 2024-04-08
dave@edelsteinautomotive.com
David Edelstein

Embed a PlantUML component in your SvelteKit blog

Here is the component:

<script>
    import { writable } from 'svelte/store'
    import { afterUpdate } from 'svelte'

    export let content;

    import encoder from "plantuml-encoder";
    const url = "http://www.plantuml.com/plantuml/svg/" + encoder.encode(content);


    let isError = writable(false);
    let imgElement;

    const handleError = e => {
        //write to the store and inform the error
        isError.set(true);
    }

    afterUpdate(()=>{
        setTimeout(()=> {
            //to support HMR, this needs to rerun so that we can check the error again.  handleError only fires once
            if(imgElement.complete && imgElement.naturalHeight !== 0)
                isError.set(false);
            else
                isError.set(true);
        }, 1000);
    });
</script>

{#if !$isError}
    <img src="{url}" alt="Plant UML" on:error={handleError} bind:this={imgElement}/>
{:else}
    <div class="error-message">Error encountered during plantuml build</div>
    <a href="{url}">View in PlantUml</a>
    <iframe src="{url}" width="100%" title="PlantUML error message"></iframe>
{/if}

<style>
    .error-message{
        color:red;
    }
</style>

The tricky part in SvelteKit though is when you embed a PlantUml component with a content param - make sure that there are no blank lines! Use a comment mark if you want to visually space things. The mdx parser gets confused here if you do not put something on very line.

<PlantUML content={`@startuml
A->B
B->C
'
C->D
@enduml`} />