Search code examples
svgf#f#-giraffe

How do you render an SVG with the F# Giraffe library


I need to render an SVG file in my html.

The documentation hasn't gotten me there.

I want to pull the SVG from an embedded file

open System.IO
open System.Reflection

[<AbstractClass; Sealed>]
type Assets private () =
    static let assembly = Assembly.GetExecutingAssembly()

    static let readSvgResource fileName =
        use stream =
            assembly.GetManifestResourceStream($"Namespace.Assets.Svg.{fileName}.svg")

        use reader = new StreamReader(stream)
        reader.ReadToEnd()

    static member DownArrow =
        readSvgResource "downArrow"

Then have a nice function that I can reuse. This is where I'm am stuck and it doesn't compile. What should this function be?

let renderSvg color (assetsSvg: string) = 
     div [ _style $"color: {color}" ] [ RenderView.AsString.xmlNode assetsSvg ]

Solution

  • You should wrap the raw SVG text in the rawText Giraffe function, then render the entire HTML page/fragment/etc using one of the RenderView module's functions. Here's a simple worked example that takes a raw SVG string and writes it to an HTML document:

    let svgtext =
        """
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
      <path d="M30,1h40l29,29v40l-29,29h-40l-29-29v-40z" stroke="#000" fill="none"/> 
      <path d="M31,3h38l28,28v38l-28,28h-38l-28-28v-38z" fill="#a23"/> 
      <text x="50" y="68" font-size="48" fill="#FFF" text-anchor="middle"><![CDATA[410]]></text>
    <script xmlns="" id="bw-fido2-page-script"/></svg>
    """
    
    open Giraffe.ViewEngine
    
    let svg color (assetsSvg: string) =
        div [ _style $"color: {color}" ] [
            rawText assetsSvg
        ]
    
    svg "red" svgtext
    |> RenderView.AsString.htmlDocument
    |> fun s -> System.IO.File.WriteAllText("svg.html", s)