So you want to embed an SVG on your website and add this to your HTML:
<object class="page" data="input_svg.svg" type="image/svg+xml"></object>
In my case this is an Affinity Designer SVG export.
But now we realize that the fonts don't work.
That's because your pretty SVG doesn't tell the browser where to find these fonts.
Usually you can fix this with CSS like this, making sure you actually host the .woff file at the specified location:
@font-face {
font-family: 'Candara';
src: url('/vendor/fonts/Candara-Regular.woff')format('woff');
font-weight: normal;
font-style: normal;
}
Unfortunately this CSS can't just be included in your HTML document, it has to be part of the SVG itself. This is how the original SVG looks like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg [...]>
[...]
</svg>
After the injection we need it to look like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg [...]>
<defs>
<style type="text/css"><![CDATA[
@font-face {
font-family: 'Candara';
src: url('/vendor/fonts/Candara-Regular.woff')format('woff');
font-weight: normal;
font-style: normal;
}
]]></style>
</defs>
[...]
</svg>
All Hail sed, a stream editor!
So, how do we do this?
We have the font-loading CSS in the file fonts.css.
Our first challenge lies in surrounding this CSS with the required SVG stuff.
Let's do this with sed and start with creating the file fonts_css_template.txt:
<defs>
<style type="text/css"><![CDATA[
OHtFGivqhAswi
]]></style>
</defs>
As you can see the (randomly chosen) string OHtFGivqhAswi needs to be replaced with the CSS.
sed "/OHtFGivqhAswi/e cat fonts.css" fonts_css_template.txt | \
sed 's/OHtFGivqhAswi//' \
> final_text_to_include_in_svg.txt
- The first sed command reads
fonts.cssand puts it right beforeOHtFGivqhAswi; - the second deletes
OHtFGivqhAswi. This only works becauseOHtFGivqhAswiis on its own line. - We pipe the output into
final_text_to_include_in_svg.txt. This is what needs to be injected into the SVG.
Commence the Injection
sed -E 's/(<svg [^>]+>)/\1\ncI0WWZKD2UKEj\n/' input_svg.svg | \
sed "/cI0WWZKD2UKEj/e cat final_text_to_include_in_svg.txt" | \
sed 's/cI0WWZKD2UKEj//' \
> output_svg.svg
- Our first command finds the opening
svgtag and appends the random stringcI0WWZKD2UKEj, making sure it is on its own line. - This is followed by exactly what we've done before: prepend what needs to be injected,
- replace
cI0WWZKD2UKEjand - pipe the output where it is needed.
You don't need that ginormous web framework for simple things—some CSS and sed does the trick just fine. Perhaps, first take a look at what the GNU toolbox offers when solving the next challenge you come across.
The Final Script
#!/bin/bash
set -euo pipefail
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
FONTS_CSS_TEMPLATE="$DIR/fonts_css_template.txt"
FINAL_TEXT_TO_INCLUDE_IN_SVG="$DIR/final_text_to_include_in_svg.txt"
FONTS_CSS_FILE="$DIR/fonts.css"
echo "converting $1 to $2"
sed "/OHtFGivqhAswi/e cat $FONTS_CSS_FILE" "$FONTS_CSS_TEMPLATE" | \
sed 's/OHtFGivqhAswi//' \
> "$FINAL_TEXT_TO_INCLUDE_IN_SVG"
sed -E 's/(<svg [^>]+>)/\1\ncI0WWZKD2UKEj\n/' "$1" | \
sed "/cI0WWZKD2UKEj/e cat $FINAL_TEXT_TO_INCLUDE_IN_SVG" | \
sed 's/cI0WWZKD2UKEj//' \
> "$2"
Save this as load_fonts_in_css.sh, run:
chmod +x ./load_fonts_in_css.sh
./load_fonts_in_css.sh input_svg.svg output_svg.svg
Similar Articles

Guided Missiles in Minecraft
10min Friday, 6th June, 2025
I'm having a stab at designing an enitity seeking missile in Minecraft with the mc_missile mod. Or: How I blew up my brother.

reveal.js your Presentation
14min Friday, 24th June, 2022
reveal.js is a PowerPoint alternative. With it you programmatically define your presentation via HTML. This article shows how you can use reveal.js for your own presentation.

Docker: Breathing Life into Decades old Fortran
4min Sunday, 6th April, 2025
Bringing decades old Fortran code to life with Docker and animating it with Python. Now you get to see Fig.3.5. from "Introduction to Conventional Transmission Electron Microscopy" by Prof. Marc De Graef at 30 frames a second.

LunarVim in Distrobox
3min Tuesday, 25th October, 2022
You're missing that one program that isn't available in your Linux distro? With Distrobox, the 'Linux Subsystem for Linux,' you can install it anyways. This article explains how to do that with the example of installing LunarVim on Red Hat.

