SVG Export Color Spec

The platform reads processing intent from colour: stroke cuts in #FE0002, stroke engravings in #2366FF, fill engravings in #2366FF. Every other colour still exports — the user just assigns its processing type by hand.

Your colours are read, never rewritten: colour is only used to identify, and the only thing written into the file is the processing type, data-processing-type.

Two colours, five groups

GroupHow to draw it
Red linestroke= #FE0002
Blue linestroke= #2366FF
Fill vectorfill= #2366FF
Bitmap<image> elements, colour-independent
Other vectorevery other visible vector, split into one row per colour

However many elements a group holds, it takes one row and the user configures it once. This is the dialog they get after picking Open in Studio from the dropdown (Download saves straight to disk with no dialog).

Export Settings
MachineP3 Processing modeFlat
Material Plywood / Basswood Plywood 3mm
Processing type8 elements
  • Red line#FE0002 · 1 elementsCut
  • Blue line#2366FF · 1 elementsLine engraving
  • Fill vector#2366FF · 1 elementsFill engraving
  • Bitmap2 elementsFill engraving Fill engraving is supported and locked
  • Other vector#22c55e · 2 elementsSelect a processing type
  • Other vector#a855f7 · 1 elementsSelect a processing type
6 groupsCancel Open in Studio

Machine, processing mode and material sit at the top; together they decide which processing types this machine supports. The dropdown on the right of each row is that group's processing type.

A complete example

Your export hook returns an SVG like this:

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <rect x="4" y="4" width="192" height="92" fill="none" stroke="#FE0002"/>
  <path d="M20 30h160" fill="none" stroke="#2366FF"/>
  <circle cx="100" cy="65" r="20" fill="#2366FF"/>
</svg>

It only uses the first three groups, so the dialog shows three rows — Red line, Blue line and Fill vector, one element each. The user picks a processing type for each, and on confirm your file becomes:

<rectstroke="#FE0002" data-processing-type="VECTOR_CUTTING"/>
<pathstroke="#2366FF" data-processing-type="VECTOR_ENGRAVING"/>
<circlefill="#2366FF"   data-processing-type="FILL_VECTOR_ENGRAVING"/>

The attribute goes on each element that is actually processed, never on a <g> to be inherited. The file carries the processing type and nothing else — no power, speed or similar parameters. Studio applies the recommended parameters for whichever material the user picked in the dialog.

That is everything you need to make export work. The three sections below are detail — reach for them when an export does not come out the way you expected.

The colour was not recognised

First check the notation is one the platform reads. Each element resolves in the order inline style → <style> rule → element attribute, and only inherits from its parent when all three are absent. That order follows SVG 2: a presentation attribute has specificity 0, so any CSS rule beats it.

Every one of these is recognised as a cut line:

<path stroke="#FE0002" fill="none"/>
<path stroke="#fe0002" fill="none"/>
<path style="stroke:#FE0002" fill="none"/>
<g stroke="rgb(254, 0, 2)" fill="none"><path/></g>

<style>.st0{fill:none;stroke:#FE0002}</style>
<path class="st0"/>

<defs><style><![CDATA[.str0{stroke:#FE0002;fill:none}]]></style></defs>
<path class="str0"/>

<style> works anywhere in the document — inside <defs>, or even after the elements it styles. CDATA wrapping is supported, as are class / id / type / attribute / descendant selectors and comma-grouped lists, ordered by specificity then document order. The one exception is !important, which does not participate: an inline value always wins.

Only these colour notations are parsed: #RGB, #RGBA, #RRGGBB, #RRGGBBAA, and numeric rgb() / rgba(). Alpha is ignored when matching, so #FE0002FF, #FE000280 and rgba(254,0,2,.5) all group as #FE0002 — a translucent red is still a cut line.

Colour cannot be read in four cases:

  • external stylesheets (<link> / @import)
  • declarations inside conditional rules such as @media
  • CSS variables and currentColor
  • unrecognised notations: named colours, hsl(), percentage rgb()

Those elements are not lost. They land in "Other vector", and the user assigns the processing type themselves.

The groups do not match what you drew

"Other vector" splits by colour. Off-spec colours are not lumped together — each distinct colour gets its own row, which is where the green and purple rows at the bottom of the dialog above come from:

  • the grouping colour takes stroke over fill
  • the same colour written differently (#22C55E / rgb(34,197,94)) stays one row
  • the same colour across several SVG files merges into one row
  • every row's processing type is empty by default — the platform never guesses
  • order: the four spec groups first, then other-vector rows by element count, most first

A shape that is both blue-filled and red-stroked is split in two. fill="#2366FF" plus stroke="#FE0002" expresses two operations — fill-engrave the interior, cut the outline — but the protocol allows only one processing type per element:

<!-- what you exported -->
<rect fill="#2366FF" stroke="#FE0002"/>

<!-- after the platform processes it -->
<rect fill="#2366FF" stroke="none" data-processing-type="FILL_VECTOR_ENGRAVING"/>
<rect fill="none"    stroke="#FE0002" data-processing-type="VECTOR_CUTTING"/>

The fill copy is inserted before the stroke copy, preserving the original fill-then-stroke paint order, so nothing looks different. The copy carries no id, and marker-* stays on the stroke copy only. The shape appears in both groups, so the element counts add up to more than you drew.

The split only happens when both sides are spec colours. A red stroke on a green fill is not split — green expresses no processing intent, so the whole shape groups as a cut line by its stroke.

The shape did not appear at all

Elements that participate: path rect circle ellipse line polyline polygon text, plus image for bitmaps.

Elements that do not:

  • shapes inside <defs> <clipPath> <mask> <marker> <pattern> <symbol> — they are definitions, nothing is painted
  • elements with display: none or visibility: hidden, whether written as an attribute, an inline style, or a <style> rule
  • elements with both fill="none" and stroke="none"

<use> is the easiest trap to fall into. The shape it draws never appears in any group, so it never receives a processing type: <use> itself is not a vector shape, and a referenced original sitting inside <defs> / <symbol> does not count either. If the whole drawing is assembled from <use>, the dialog shows no rows at all.

The sneakier case is a referenced original that is itself painted. With <path id="p" …/> plus <use href="#p" x="20"/>, the original groups normally and gets a processing type while the copy drawn by <use> gets none — one shape is cut, its duplicate is not. Emit the real shapes instead.

Multi-file exports: identical groups merge across files and an unparsable SVG is skipped on its own. With Open in Studio, standalone bitmap files (PNG / JPEG / WebP / GIF / BMP) are wrapped into an SVG <image>, so they show up under the "Bitmap" group too; anything else passes through untouched. Download always delivers your bytes as-is — no wrapping, no attributes. When no group can be produced at all — no SVG, or SVGs made entirely of the elements above — the dialog hides the "Processing type" section.

Esc
Search all docs · to navigate · to open