A designer asked me for a logo word as an SVG path β not a PNG, not "the font file," an actual <path> they could drop into Figma and a cutting machine. My first instinct was to screenshot it and trace it. Don't do that. If you have the font file, the outlines are already vectors β you just have to ask for them. Here's how I do it client-side with opentype.js.
The idea
A font glyph is a set of BΓ©zier curves. opentype.js parses a .ttf/.otf and hands you those curves as an SVG path string. No tracing, no quality loss, no server.
Load the font and get a path
import opentype from "opentype.js";
const font = await opentype.load("/fonts/MyFont.ttf");
// getPath(text, x, y, fontSize) β a Path object
const path = font.getPath("Hello", 0, 150, 120);
// .toSVG() gives you the <path d="..."/> markup
const pathMarkup = path.toSVG(2); // 2 = decimal precision
That pathMarkup is a real vector outline of your text in that font. Wrap it in an <svg> and you're done.
Size the viewBox correctly
The gotcha is the canvas/viewBox. getPath draws from a baseline, so you need the bounding box to avoid clipping:
const bb = path.getBoundingBox(); // {x1, y1, x2, y2}
const pad = 16;
const w = (bb.x2 - bb.x1) + pad * 2;
const h = (bb.y2 - bb.y1) + pad * 2;
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${bb.x1 - pad} ${bb.y1 - pad} ${w} ${h}">
${path.toSVG(2)}
</svg>`;
Now the SVG is tightly cropped to the glyphs, whatever the text.
Download it from the browser
No backend needed β make a Blob and click a link:
const blob = new Blob([svg], { type: "image/svg+xml" });
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "text.svg";
a.click();
URL.revokeObjectURL(a.href);
Things that bit me
- CORS on the font fetch. opentype.load does an XHR/fetch under the hood; the font has to be same-origin or CORS-enabled or it silently fails. Self-host the file.
- Licensing. Converting a glyph to a path is still using the font. Check the license allows it before you ship outlines of a commercial font.
-
Right-to-left / complex shaping.
getPathdoes basic layout, not full HarfBuzz shaping. For Latin display text it's perfect; for Arabic/Indic you'll want a shaping engine. -
Precision vs file size.
toSVG(2)is plenty for cutting/printing. Higher precision just bloats the path string.
Why client-side is nice here
The whole thing runs in the browser: the user picks a font, types text, and gets an SVG without a single byte hitting a server. That's exactly how I wired up the font-to-SVG tool on FontBoxDL β handy if you want to see it in action or grab a quick cut file (it pulls from a library of 60k+ free fonts you can use as the source).
opentype.js is one of those libraries that makes a "hard" task almost embarrassingly short. If you're doing anything with fonts in JS β metrics, kerning, glyph inspection β it's worth an afternoon.
Anyone else using it in production? Curious what you've built.












