Inlining svg into style tag

hi im trying to inline a svg file i have in /static into a style tag like this:

{{ $svg := partial "svg.html"  "sun" }}
<label for="theme-switch" style="{{ $svg | safeCSS}}" class="switch-label">
  <img id="switcher-image" width="22px" height="22px">
</label>

svg.html

{{ $svg := . }}
{{ $path := printf "/static/images/svg/%s.svg" $svg }}
{{ $file := $path | readFile | safeHTML | printf "mask-image: url(\"data:image/svg+xml;utf8,%s\");" | safeCSS }}
{{ $file }}

output:

    <label for="theme-switch" style="


mask-image: url(&amp;#34;data:image/svg&amp;#43;xml;utf8,&amp;lt;svg class=&amp;#34;light-icon&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; xmlns=&amp;#34;http://www.w3.org/2000/svg&amp;#34;&amp;gt;
    &amp;lt;path d=&amp;#34;M12 3V4M12 20V21M4 12H3M6.31412 6.31412L5.5 5.5M17.6859 6.31412L18.5 5.5M6.31412 17.69L5.5 18.5001M17.6859 17.69L18.5 18.5001M21 12H20M16 12C16 14.2091 14.2091 16 12 16C9.79086 16 8 14.2091 8 12C8 9.79086 9.79086 8 12 8C14.2091 8 16 9.79086 16 12Z&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;/&amp;gt;
&amp;lt;/svg&amp;gt;
&amp;#34;);" class="switch-label">

but the output contains formatted &#34 etc.., how can i make this partial do what i want >_< ty!

I see two issues:

  • the whole $svg := partial might only work (that might have changed recently without me knowing it yet) if the partial returns something instead of just printing it out. The {{ $file }} says “put everything in $file here” and not “hand everything in $file back”.
  • safeHTML plus safeCSS feels like a double encoding here. You either have safe HTML or safe CSS. and that url encoding is CSS in my opinion, so safeHTML prepares your CSS to be “read” instead of “executed”.

ty ill try that! and yeah the html thing i just never removed

I think the solution is to use ´safeHTMLAttr´, see safe.HTMLAttr

hey, thanks to both of you, i got it working with this:
partials/svg.html:

{{ $svg := . }}
{{ $path := printf "/static/images/svg/%s.svg" $svg }}
{{ $file := $path | readFile }}

{{ $file := replaceRE `(")` `'` $file }}
{{ $file := replaceRE `(\r?\n)` `` $file }}
{{ $inlined_svg := $file | printf "style=\"mask-image: url(&quot;data:image/svg+xml;utf8,%s&quot;);\"" }}
{{ return $inlined_svg }}

in the html:

{{ $svg := partial "svg.html"  "sun" }}
<label for="theme-switch" {{ $svg | safeHTMLAttr }} class="switch-label">
  <img id="switcher-image" width="22px" height="22px"> 
</label>

:3

I run your code through Claude and it suggested this.

First, move the SVGs to assets folder or mount static to assets.

Modified partials/svg.html

{{ $svg := . }}
{{ $path := printf "images/svg/%s.svg" $svg }}
{{ $resource := resources.Get $path }}
{{ if not $resource }}
  {{ errorf "svg.html: could not find resource %q" $path }}
{{ end }}
{{ $base64 := $resource.Content | base64Encode }}
{{ $inlined_svg := printf "style=\"mask-image: url(&quot;data:image/svg+xml;base64,%s&quot;);\"" $base64 }}
{{ return $inlined_svg }}

Haven’t tested. But you can try it.

What’s the advantage of that over the OP’s solution?