The name keychain is where this whole product line started. You type a name, pick a font and two colors, and you get a print-ready 3D keychain with your name raised off the plate. The preview you spin around in the browser is the exact geometry that gets printed — no separate “render” and “real” model.
The interesting part isn’t the keychain. It’s the typography. Turning typed letters into a single, watertight, printable object is harder than it sounds, and one font family broke it in a way that took a real fix.
From letters to geometry
This post is about the name mode specifically. The shared plumbing — design in the browser with React and Three.js, generate a .3mf on add-to-cart, store it via a REST endpoint, move it onto the WooCommerce order at checkout, fixed €4,50 enforced server-side — is the same across every product and is covered in how we built the keychain configurator. Here I want to dig into the one problem unique to typed text: getting from a string to a solid.
On the live keychain the font menu is a curated four — Chewy, Bangers, Roboto Slab and Oswald. Behind that menu the engine can load any TrueType font, and during development the set was wider, including flowing script faces like Pacifico — which is where the interesting bug lived. Each font is a real .ttf loaded with opentype.js. When you type, we ask opentype for the glyph outlines, then walk every drawing command and flatten the quadratic and cubic Béziers into closed polygon contours (opentype hands back y-down coordinates, so we flip them into a y-up model frame). At that point a letter is no longer typography — it’s a list of points.
Those contours go through a chain that turns flat outlines into a solid:
- Union the glyph outlines into one clean filled region (more on this below).
- Resolve holes — the inside of an “o” or “a” stays a hole; the outer shapes become solids — by nesting depth.
- Build a backing plate by growing the text outward with rounded joins, so the letters sit on something printable.
- Extrude the plate and the letters to their thicknesses with Three.js
ExtrudeGeometry.
The cursive seam bug
This is the hard case. Block fonts like Roboto Slab keep their letters apart — each glyph is its own island, with clean air between them. Script fonts don’t. In Pacifico the letters flow into each other: the tail of one glyph physically overlaps the start of the next. That’s the whole point of cursive, and it’s exactly what breaks a naive mesh.
The original code unioned the glyph outlines by re-orienting each contour according to its containment depth: a contour with nothing around it is an outer (even depth, solid), a contour sitting inside one other contour is a hole (odd depth), and so on. That logic is correct for block text, where the only thing inside a letter is its own counter.
With cursive it falls apart. When two letters overlap, the test point we use to probe one glyph can land inside its neighbor’s outline. Now that letter looks like it’s contained by another shape — odd depth — so it gets flagged as a hole. The union then carves that “hole” straight through the word, leaving a visible seam where the two letters meet. On screen it’s an ugly notch. In a print it’s a fracture line: the keychain can snap right there.
A cursive name isn’t separate letters — it’s one shape that happens to look like letters.
The fix (commit 5f80b3a) was to stop second-guessing the font. Instead of re-orienting contours by depth, we union the glyphs using the font’s natural winding — a nonzero fill rule. Type designers already wound their outlines correctly: outer shapes one way, counters the other. Trust that, and overlapping glyphs merge into one clean body while the counters in “a”, “o” and “g” stay as proper holes. No seam, no carved notch. We verified it watertight on Pacifico “Lau” and “good”, Chewy “Bao” and Fredoka “Hello” — text boundary defect zero — and deleted the old depth-reorientation helpers entirely. Less code, correct result.
Two lines, two colors, one file
A name is often two lines — a first and last name, or a name and a date. Line two is built exactly like line one, then stacked underneath it with a configurable gap measured between the facing edges of the two plates, so the spacing stays even no matter how tall the glyphs are.
Color is where the geometry pays off. The plate and the raised letters are separate extrusions in separate colors — and each line can carry its own text color. When we write the .3mf, each color becomes its own part, merged into one geometry per filament slot, with the slot’s display color baked into the file. So a two-tone name on a black plate exports as clean, separated bodies a multi-material printer can assign filaments to directly. The preview’s colors and the print’s colors are the same data.
The widget also pushes back when a design won’t print well: if the backing plate splits into disconnected islands, or if the text strokes drop below roughly 0.5 mm at the chosen font size, it warns you before you ever download it. That’s only possible because the preview is the print model — we can measure the actual geometry, not a guess.
What it costs
All of this runs in your browser. Flattening Béziers, unioning contours, growing the plate, triangulating and extruding to a mesh — for a typical name it’s tens to hundreds of milliseconds. To keep typing and slider drags smooth, the preview rebuild is debounced: instead of recomputing on every keystroke, it coalesces rapid edits and rebuilds a fraction of a second after you pause. The file you actually download is built separately from live state, so that preview debounce never changes the file you get.
The rebuild still happens on the main thread, so a long entry in a heavy font can cost a visible beat. That’s a known, honest cost. The fix is to move the geometry rebuild into a Web Worker so the main thread stays smooth while the mesh recomputes off to the side. It’s on the roadmap. For a keychain the current behaviour is fine — but it’s exactly the kind of detail that separates a demo from a product, and this product line is the live showcase for that standard.
Try it yourself
Type a name, pick a font and two colors, and watch it take shape as one solid object you can spin around and download. If you want a working custom product like this in your own shop — real geometry, real files, real orders — disip can build it.