Embedding data that survives a Microsoft Visio round-trip

Question: if you write custom data into a .vsdx, does it survive being opened and re-saved in the real Microsoft Visio desktop app?

Short answer: only if the data maps to something in Visio's object model. Visio re-serializes the whole package from memory on save, so it keeps native data (Shape Data, document properties) and its own Solution XML store, and discards everything else — including standard OOXML customXml parts, unreferenced parts, and incidental XML like comments.

This matters for this project: it's why "Export SVG" embeds the source drawing for our own round-trip (see usage.md) rather than relying on Visio to preserve a stashed blob. If you ever want data to survive a detour through Visio itself, use the Solution XML channel documented below.

The experiment

A .vsdx is an OPC ZIP package (like .docx/.xlsx): [Content_Types].xml, a _rels/ relationship graph, and parts under visio/. We planted six uniquely-tokenised markers in six different locations, opened the file in Microsoft Visio 16.0 (the 2016/2019/2021/365 desktop app), saved it, and checked which tokens remained in the bytes.

Results

Marker location Kind Survived?
Shape Property row (visio/pages/pageN.xml) Native Shape Data yes
docProps/custom.xml <property> Document custom property yes
visio/solutions/solution1.xml via a solutionxml relationship Visio Solution XML store yes, byte-intact
customXml/item1.xml (+ customXmlProps rel) Standard OOXML custom XML part dropped
vsdxtest/sidefile.txt (valid part, no relationship) Unreferenced OPC part dropped
XML comment inside visio/document.xml Incidental markup dropped

The rule

Visio keeps only what maps to a slot in its object model. On save it rebuilds the package from its in-memory document, so:

How this app uses it

This finding is not academic — it backs three features.

Layer tags (usage.md) attach free-form labels, and a colour per label, to layers. Visio's layer object model has no tag slot — an extra Cell in a Layer row is dropped the moment Visio re-serializes the page — so the labels go into visio/solutions/vsdxeditor-layer-tags.xml, wired with the solutionxml relationship. Layers are keyed by name rather than index, so tags stay attached across Visio renumbering. See readVsdxLayerTags and writeLayerTagsToZip in src/vsdx-parser.js; scripts/test-layer-tags.mjs asserts both the wiring and survival of a package rebuild that keeps only relationship-reachable parts.

Named views (usage.md). Each named view is a per-page snapshot of layer visibility, and it's persisted into the drawing as a visio/solutions/vsdxeditor-views.xml part wired with the solutionxml relationship. That's precisely the channel proven above to survive a Visio re-save, so a team's named views travel with the file and keep working even after someone edits the drawing in the real Visio desktop app. The payload is base64-encoded JSON inside a <SolutionXML> element. See readVsdxViewTemplates / saveVsdxLayerPermissions in src/vsdx-parser.js.

Layer folder settings (usage.md). Visio's layers are flat; drawings fake a hierarchy in the name (Electrical/HV). Which delimiter a drawing uses for that is a fact about the drawing rather than a preference of whoever opens it, so the setting — whether grouping is on, the delimiter, and which groups were left collapsed — goes into visio/solutions/vsdxeditor-layer-tree.xml on the same channel, and everyone who opens the file sees the tree its author saw. The groups themselves are still never written: they are derived from the layer names every time. See readVsdxLayerTree / writeLayerTreeToZip in src/vsdx-parser.js, and scripts/test-layer-tree-roundtrip.mjs for the wiring.

Practical guidance

Reproducing

The check is just: plant tokens → open+save in Visio → grep the saved bytes.

# every surviving token still greps out of the re-saved package:
for m in shapedata docprop customxml solution sidefile xmlcomment; do
  n=$(unzip -p resaved.vsdx | grep -a -c "TOKEN-$m")
  [ "$n" -gt 0 ] && echo "SURVIVED $m" || echo "DROPPED  $m"
done

Tested with Microsoft Visio 16.0 (docProps/app.xmlAppVersion 16.0000). Behaviour can differ across Visio versions — re-verify on your target if it matters.