Skip to main content

Inline SVG

Admin UI extensions can render inline SVG in extension markup. Any extension target that renders UI can use it.

Inline SVG isn't a Shopify web component and doesn't use an s-* tag. It's a supported subset of native SVG markup that can render alongside Shopify web components.

Use inline SVG for simple icons, diagrams, and decorative or informational graphics that aren't covered by the icon component.

  • Custom icons: Show a brand mark or a symbol that the icon component doesn't include.
  • Simple diagrams: Illustrate steps, flows, or relationships in a configuration screen.
  • Status graphics: Draw a progress ring or a small chart from your extension's data.
  • Decorative accents: Add visual interest that repeats what nearby text already says.

The following example shows an icon with an accessible name, drawn with a path that inherits the surrounding text color:

HTML

<svg
viewBox="0 0 20 20"
width="20"
height="20"
role="img"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<title>Shipping label</title>
<path
d="M4 3h12v14H4V3Z M7 7h6 M7 10h6 M7 13h4"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

The following SVG elements are supported:

CategoryElements
Root, grouping, and definitionssvg, g, defs
Shapespath, circle, line, rect, polygon, polyline, ellipse
Text and accessible namestext, title, tspan
Local paint, clipping, masks, and markersclipPath, mask, pattern, linearGradient, radialGradient, stop, marker
Filtersfilter, feDropShadow, feFlood, feGaussianBlur, feMerge, feMergeNode, feOffset

Other SVG elements aren't part of the supported subset.


Anchor to Supported attributesSupported attributes

The following SVG attributes are supported:

CategoryAttributes
Root and sizingviewBox, xmlns, width, height, preserveAspectRatio
Paint and effectsfill, stroke, opacity, mask, filter
Geometry and transformsd, cx, cy, r, rx, ry, x, y, x1, x2, y1, y2, points, pathLength, transform
GradientsgradientUnits, offset
Text, filters, and markersdx, dy, stdDeviation, refX, refY, orient, in, result
Identity and accessibilityid, role, aria-hidden

The following attributes can be written in either React-style camelCase or DOM-style kebab-case:

CategoryAttributes
Fill and clippingfillOpacity / fill-opacity, fillRule / fill-rule, clipRule / clip-rule, clipPath / clip-path
StrokestrokeWidth / stroke-width, strokeLinecap / stroke-linecap, strokeLinejoin / stroke-linejoin, strokeDasharray / stroke-dasharray, strokeDashoffset / stroke-dashoffset
Gradient stopsstopColor / stop-color, stopOpacity / stop-opacity
TexttextAnchor / text-anchor, dominantBaseline / dominant-baseline, fontSize / font-size, fontWeight / font-weight
FiltersfloodColor / flood-color, floodOpacity / flood-opacity
MarkersmarkerWidth / marker-width, markerHeight / marker-height, markerStart / marker-start, markerMid / marker-mid, markerEnd / marker-end

The role attribute accepts only img, presentation, and none. Use role="img" with a child <title> element when the SVG needs an accessible name. Use aria-hidden="true" for decorative SVGs.


Anchor to Refused elements, attributes, and valuesRefused elements, attributes, and values

Inline SVG uses an allowlist so that extensions can render graphics without gaining new script, style, network, or interaction capabilities. The following common SVG features aren't supported:

  • URL-bearing elements and attributes, including use, symbol, image, feImage, textPath, href, xlink:href, xlinkHref, and src, because they depend on URL loading.
  • foreignObject, because it embeds non-SVG content.
  • script, style, animation elements, inline style attributes, class, and className, because extensions can't add arbitrary scripts or borrow Shopify admin styles.
  • SVG event handlers such as onclick or other on* attributes, because the SVG subset is render-only.
  • aria-label and aria-labelledby. To name an SVG icon, use a child <title> element instead.
  • Role values other than img, presentation, and none. Interactive roles such as button or link are refused because inline SVG is render-only and doesn't support event handling.

Refused markup is ignored silently, without an error or a console warning. A refused attribute or value isn't applied, and the rest of the element still renders. If an update to an attribute that's already set is refused, the last accepted value stays in place, so remove the attribute when you need it cleared. A refused element renders nothing, including its children. If part of a graphic is missing, check its elements, attributes, and values against the lists on this page.


Anchor to URL references and IDsURL references and IDs

Same-document fragment references are supported in CSS-style url(#id) values, including url("#id") and url('#id'). For example, a shape can reference a gradient with fill="url(#gradient)".

External references are refused. Values such as url(https://example.com/image.svg), url(/admin/...), src(...), image-set(...), image(...), cross-fade(...), and element(...) aren't supported. Backslashes are also refused in CSS-parsed SVG values because CSS escapes can hide URL-loading functions.

IDs that you define inside inline SVG are rewritten each time your extension renders, and local url(#id) references are rewritten to match. Don't depend on the final DOM ID value. Treat IDs as local to a single render and use them only for references inside the same SVG tree.


Give an SVG an accessible name with a child <title> element and role="img". aria-label and aria-labelledby are refused, so <title> is how an icon gets its name.

Preview

html

<svg
viewBox="0 0 20 20"
width="20"
height="20"
role="img"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<title>Order fulfilled</title>
<circle cx="10" cy="10" r="9" stroke="currentColor" stroke-width="1.5" />
<path
d="M6 10.5 8.75 13 14 7.5"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

Anchor to Mark an SVG as decorativeMark an SVG as decorative

Hide an SVG from assistive technology with aria-hidden="true" when the graphic only repeats information that nearby text already carries.

Preview

html

<svg
viewBox="0 0 20 20"
width="20"
height="20"
aria-hidden="true"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M3 15.5 7.5 9l3.5 4 2.5-3 3.5 5.5H3Z" fill="currentColor" opacity="0.6" />
</svg>

Anchor to Reference a gradientReference a gradient

Reference a gradient defined in the same SVG with fill="url(#id)". Only same-document references are supported, and IDs are rewritten each time your extension renders, so use them only for references inside the same SVG tree.

Preview

html

<svg
viewBox="0 0 120 24"
width="120"
height="24"
role="img"
xmlns="http://www.w3.org/2000/svg"
>
<title>Sales over the last seven days</title>
<defs>
<linearGradient id="sales-sparkline-fill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="currentColor" stop-opacity="0.4" />
<stop offset="1" stop-color="currentColor" stop-opacity="0" />
</linearGradient>
</defs>
<path
d="M0 20 20 14 40 16 60 8 80 11 100 4 120 6 120 24 0 24Z"
fill="url(#sales-sparkline-fill)"
/>
<polyline
points="0,20 20,14 40,16 60,8 80,11 100,4 120,6"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

Anchor to Combine with web componentsCombine with web components

Inline SVG renders alongside Shopify web components. Paint with currentColor so the graphic inherits the surrounding text color instead of hardcoding a value.

Preview

html

<s-stack direction="inline" gap="base">
<svg
viewBox="0 0 20 20"
width="16"
height="16"
aria-hidden="true"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10 2.5 12.4 7.6 18 8.3l-4 3.9.9 5.3-4.9-2.6-4.9 2.6.9-5.3-4-3.9 5.6-.7Z"
fill="currentColor"
/>
</svg>
<s-text type="strong">Featured product</s-text>
</s-stack>

Was this page helpful?