Embedding (inline) SVG in content / markdown

Quick question I’m struggling with:

Lets say I have an svg image triangle.svg with some contents, eg:

<svg height="210" width="500">
  <polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1" />

If I want to include the svg in a web page, I can use a shortcode like {{< figure src="triangle.svg" >}} inside my markdown. This will give me a figure that references triangle.svg.

Now, what if I want to embed (inline) the contents of triangle.svg inside the web page?

Been looking for a solution to this but no idea so far.

Any suggestions much appreciated!!

Thanks and warm regards from first time poster :slight_smile:

{{ readFile "static/triangle.svg" | safeHTML }}

Note that I have put the “static” root folder there to indicate that readFile reads relative to the project root.


Hi bep —

Thanks for your suggestion. This only works in templates, correct?

I’m looking for a solution to inline svg’s from inside a content (markdown) file. Is this impossible?


Sure, but you could put it in a shortcode, which is a template …

1 Like

So a custom shortcode. Gotcha :wink: I’ll give it a go. Perfect!

1 Like

To give you even more flexibility, I like this use of dict that @budparr showed me:

1 Like


Even that’s overkill for my needs. My current shortcode is stored in /layouts/shortcodes/svg.html and looks like

{{ readFile (print "svg/" (index .Params 0)) | safeHTML }}

I created the /svg folder under hugo root to hold the svg’s (since I don’t need them copied over from /static to /public).

Inside markdown I can just call {{< svg "triangle.svg" >}} and the svg is inlined.

Hopefully it’s good enough.

The only lingering question is whether, when I call readFile, there is a way inside the template to remove the first line of the svg in order to prevent the svg’s xml declaration from being embedded.

The typical contents of a standalone triangle.svg might be

<?xml version="1.0" encoding="UTF-8"?>
<svg height="210" width="500">
  <polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1" />

Anyone have an idea how I could go about getting just the svg tag? I don’t think it’s strictly necessary but would be cool!


Possibly using https://gohugo.io/functions/replacere ?

Bumping this with a quick question.
It works great by using inside templates something like this:
{{ readFile “static/icons/home.svg” | safeHTML }}

Is there a way to add a class name to this? Something like

<svg class="svg-black">


Probably not with readFile, but you can pass in those values using dict inside a partial call.

Here’s an example from the theme for the GoHugo site:

1 Like

I ended up passing in class to a parent element as an easy fix. Obv depends on how you’re planning to use the SVG (semantics dependant), but you could always pass in logic to decide which parent element to use.

<figure class="{{index .Params 1}}">
  {{ readFile (print "inline-svg/" (index .Params 0)) | safeHTML }}