Reference
Data Attributes

Data Attributes

Most of Mirage's behaviour is driven from markup rather than JavaScript, so it survives re-renders from any framework.

Overview

AttributeValuesPurpose
data-mirage-domhide | showFade the original DOM element out
data-mirage-filterfilter tokensInclude/exclude from the visible layer
data-mirage-selectfilter tokensInclude/exclude from the selection layer
data-mirage-traveltraveler / native + layer + JSONRender-target capture and style overrides
data-mirage-shaderJSON ShaderHooksInject custom GLSL
data-mirage-sandwichfrontLift the element above the canvas
data-mid(auto)Stable id Mirage assigns; do not set it yourself

data-mirage-dom

<div id="target" data-mirage-dom="hide">…</div>

Applies opacity: 0 !important through a stylesheet Mirage injects once (#mirage-engine-styles). The element keeps its layout box, pointer events and accessibility tree — only the paint is suppressed.

Mirage also compensates internally: a hidden element's mesh is drawn at opacity: 1 rather than inheriting the zeroed value.


data-mirage-filter

Controls membership in USER_LAYER — whether the mesh is drawn at all.

TokenEffect
include-treeInclude this element and all descendants
exclude-treeExclude this element and all descendants
include-selfInclude only this element
exclude-selfExclude only this element
endStop traversal here; skip this element and its subtree entirely

Tokens are whitespace-separated and combine:

<!-- Mirror the wrapper but not its contents -->
<section data-mirage-filter="exclude-tree include-self">
  <p>Not mirrored</p>
</section>
 
<!-- Mirror the contents but not the wrapper -->
<section data-mirage-filter="include-tree exclude-self">
  <p>Mirrored</p>
</section>
🚫

include-tree with exclude-tree, or include-self with exclude-self, on the same element throws. An unknown token also throws. This is intentional — silent typos in markup are hard to debug.

end returns null immediately, so it is the cheapest way to keep a heavy subtree (a video player, a map, a virtualized list) out of extraction.

<div data-mirage-filter="end">
  <iframe src="https://example.com"></iframe>
</div>

data-mirage-select

Identical token grammar, but toggles SELECT_LAYER instead. Combine it with layer: "selected" to render an isolated pass containing only these elements — useful for outline, glow or picking effects.

<div data-mirage-select="include-tree">…</div>
new Mirage(target, { layer: "selected" });

data-mirage-travel

The most powerful attribute. Two independent tokens plus an optional JSON object.

data-mirage-travel="traveler <layer> native <layer> { …styles }"

traveler

Marks the element as sampling a render target rather than a flat color.

<div data-mirage-travel="traveler"></div>
<div data-mirage-travel="traveler 2"></div>

The number is the capture layer (default 1, max 10). Everything on layers at or above the traveler's own captureLayer gets captured into the buffer it samples, which is how you nest travelers.

🚫

A traveler's layer must not be smaller than the inherited capture layer. Violating this throws with the two layer numbers in the message.

native

Creates a second mesh for the same element on a different capture layer.

<div data-mirage-travel="native 2 { backgroundColor: 'red' }"></div>

The visible scene keeps the real CSS appearance; the copy on layer 2 uses the override. So an element can look normal to the user and different inside a traveler's capture.

Style overrides

The JSON-ish block is evaluated with new Function("return " + json), so unquoted keys and single quotes are fine.

KeyApplies to
backgroundColor, backgroundImage, opacity, zIndexBox appearance
borderRadius, borderColor, borderWidth, boxShadowBox appearance
transformscale, scaleX/Y, translate, translateX/Y (parsed manually)
x, y, width, heightOverride the native mesh's rect
color, fill, strokeSVG re-rasterization for the native copy
<svg
  data-mirage-travel="native 2 { color: '#00ffcc', opacity: 0.4 }"
  viewBox="0 0 24 24"
>…</svg>
⚠️

Because the value is evaluated as JavaScript, never build this attribute from untrusted user input.


data-mirage-shader

Parsed with JSON.parse — strict JSON, double quotes required.

<div
  data-mirage-shader='{
    "uniforms": { "uTime": 0, "uAmp": 0.02 },
    "uvModifier": "resultUv.x += sin(resultUv.y * 20.0 + uTime) * uAmp;",
    "colorModifier": "finalColor.rgb *= 1.2;"
  }'
></div>
FieldTypeInjected at
uniformsRecord<string, number | number[]>#INJECT_DECLARATIONS
uvModifierGLSL string#INJECT_UV_MODIFIER
colorModifierGLSL string#INJECT_COLOR_MODIFIER

Changing this attribute changes the material's shader hash, which forces Mirage to rebuild the mesh. Drive per-frame values with updateUniforms() instead of rewriting the attribute.

See Custom Shaders.


data-mirage-sandwich

<nav data-mirage-sandwich="front">…</nav>

Moves the element into a fixed layer at z-index: 9999, above the Mirage canvas, leaving an invisible placeholder behind so the page layout does not shift. Positions re-sync every frame.

See Sandwich Layering.


data-mid

Assigned automatically during extraction as a stable identifier. Read it if you find it useful; do not write it.


Mirage Engine — MIT Licensed © 2026 dltldn333