<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Svg/icons</title>
    <description>The latest articles on DEV Community by Svg/icons (@svgicons).</description>
    <link>https://dev.to/svgicons</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3940768%2F093b279b-947a-4e08-b433-4da6f4e803c7.png</url>
      <title>DEV Community: Svg/icons</title>
      <link>https://dev.to/svgicons</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/svgicons"/>
    <language>en</language>
    <item>
      <title>From Icon Search to React Components: Building a Reusable Icon Collection</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Thu, 08 Oct 2026 22:15:54 +0000</pubDate>
      <link>https://dev.to/svgicons/from-icon-search-to-react-components-building-a-reusable-icon-collection-5mb</link>
      <guid>https://dev.to/svgicons/from-icon-search-to-react-components-building-a-reusable-icon-collection-5mb</guid>
      <description>&lt;p&gt;Finding an SVG icon is easy. Keeping a consistent set of icons across an evolving React application takes a little more planning.&lt;/p&gt;

&lt;p&gt;Consider a dashboard with navigation, billing, notifications, and account settings. Each screen needs icons, but downloading them one by one quickly leads to a folder of unrelated assets.&lt;/p&gt;

&lt;p&gt;A more practical approach is to build a collection specifically for the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create a collection for your UI
&lt;/h2&gt;

&lt;p&gt;On &lt;a href="https://svgicons.com/project-kits" rel="noopener noreferrer"&gt;SVGicons&lt;/a&gt;, you can create a named &lt;strong&gt;Icon Collection&lt;/strong&gt; and add icons directly from search results or individual icon pages.&lt;/p&gt;

&lt;p&gt;For a dashboard, you might create a collection called &lt;code&gt;Dashboard Navigation&lt;/code&gt; and select icons for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Home&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;li&gt;Billing&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The collection preserves the original icon references, including their source sets and license information.&lt;/p&gt;

&lt;p&gt;You can also reorder icons, remove unused entries, and review which icon families are represented.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Choose how your icons behave
&lt;/h2&gt;

&lt;p&gt;Before exporting, two settings are particularly useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Color policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a typical React interface, &lt;code&gt;currentColor&lt;/code&gt; allows compatible icons to inherit their color from CSS.&lt;/p&gt;

&lt;p&gt;That means a navigation icon can follow the color of its surrounding UI without requiring a separate colored SVG file.&lt;/p&gt;

&lt;p&gt;SVGicons also supports &lt;code&gt;preserve&lt;/code&gt; for original colors and &lt;code&gt;strip&lt;/code&gt; for workflows that require normalized paint attributes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Naming policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can choose consistent naming conventions, including &lt;code&gt;kebab&lt;/code&gt;, &lt;code&gt;camel&lt;/code&gt;, and &lt;code&gt;pascal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For React components, PascalCase is a natural choice: &lt;code&gt;ArrowLeft&lt;/code&gt;, &lt;code&gt;CreditCard&lt;/code&gt;, or &lt;code&gt;Settings&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Export components instead of converting every SVG
&lt;/h2&gt;

&lt;p&gt;Once the collection is ready, SVGicons can generate an archive containing React TypeScript components.&lt;/p&gt;

&lt;p&gt;Depending on the selected export options, the archive can also contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Individual SVG files and an SVG sprite&lt;/li&gt;
&lt;li&gt;JSON metadata and license manifests&lt;/li&gt;
&lt;li&gt;Vue, Svelte, Solid, or Blade components&lt;/li&gt;
&lt;li&gt;Storybook galleries and npm package scaffolds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This avoids manually converting every selected SVG into a frontend component.&lt;/p&gt;

&lt;p&gt;The exported files can then be added to your project and managed alongside your application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Keep the collection as your UI evolves
&lt;/h2&gt;

&lt;p&gt;A dashboard rarely stays unchanged.&lt;/p&gt;

&lt;p&gt;When a new feature needs an icon, you can return to the collection, review the existing visual style, and add another selection.&lt;/p&gt;

&lt;p&gt;SVGicons also provides a VS Code extension that lets Pro users access collections and add icons directly from the editor.&lt;/p&gt;

&lt;p&gt;The collection remains available for future exports, while the generated files live in your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small detail worth checking
&lt;/h2&gt;

&lt;p&gt;Before shipping, review the collection's icon sets and license summary. Grouping icons into one archive does not automatically make their licenses identical.&lt;/p&gt;

&lt;p&gt;Creating and organizing collections is free with a Member account. Adding icons and exporting collections use Pro credits, and free Member accounts include 15 credits to explore the workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;A reusable icon collection is not just a convenient way to download multiple SVG files.&lt;/p&gt;

&lt;p&gt;It gives your project a defined selection of icons, consistent export settings, and a practical route from visual selection to frontend components.&lt;/p&gt;

&lt;p&gt;Explore &lt;a href="https://svgicons.com/project-kits" rel="noopener noreferrer"&gt;SVGicons Project Kits&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>svg</category>
    </item>
    <item>
      <title>SVG 2 in 2026: What Icon Designers and Developers Should Know</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Thu, 08 Oct 2026 20:54:22 +0000</pubDate>
      <link>https://dev.to/svgicons/svg-2-in-2026-what-icon-designers-and-developers-should-know-58eh</link>
      <guid>https://dev.to/svgicons/svg-2-in-2026-what-icon-designers-and-developers-should-know-58eh</guid>
      <description>&lt;p&gt;SVG has been part of web development for years. It's lightweight, scalable, and particularly well suited for icons and interface graphics.&lt;/p&gt;

&lt;p&gt;On October 6, 2026, the W3C published an updated &lt;strong&gt;Candidate Recommendation Snapshot of SVG 2&lt;/strong&gt;, bringing corrections and clarifications intended to improve interoperability, especially between web browsers.&lt;/p&gt;

&lt;p&gt;It's a positive step for the SVG standard. But what does it actually mean for designers, developers, and icon libraries?&lt;/p&gt;

&lt;p&gt;And does everyone need to change the way they work with SVG?&lt;/p&gt;

&lt;h2&gt;
  
  
  SVG 2 is evolving, not starting from scratch
&lt;/h2&gt;

&lt;p&gt;SVG 2 builds on SVG 1.1, the specification behind many of the features developers already use today.&lt;/p&gt;

&lt;p&gt;The goal isn't to reinvent vector graphics. It's to modernize the specification, clarify existing behavior, and improve integration with other web technologies.&lt;/p&gt;

&lt;p&gt;The October 2026 publication continues that process.&lt;/p&gt;

&lt;p&gt;A Candidate Recommendation Snapshot is an important milestone in the W3C standards process, but it isn't the same as a final Recommendation.&lt;/p&gt;

&lt;p&gt;It also doesn't mean that every SVG 2 feature suddenly became available in every browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The specification defines how something should work. Browser implementations determine how reliably it works in practice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction matters when SVG graphics become part of a real application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's different in SVG 2?
&lt;/h2&gt;

&lt;p&gt;Several changes introduced during the development of SVG 2 are particularly relevant to people working with icons and user interfaces.&lt;/p&gt;

&lt;p&gt;These are broader developments since SVG 1.1, not features introduced specifically on October 6, 2026.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Closer integration with CSS
&lt;/h3&gt;

&lt;p&gt;SVG 2 brings SVG geometry and styling closer to the CSS model.&lt;/p&gt;

&lt;p&gt;For example, certain geometric attributes, including dimensions and positions, are defined as CSS geometry properties.&lt;/p&gt;

&lt;p&gt;This makes it possible to control more aspects of SVG graphics through stylesheets, where supported.&lt;/p&gt;

&lt;p&gt;For developers building adaptable interfaces, closer integration between SVG and CSS is a useful direction.&lt;/p&gt;

&lt;p&gt;However, support for individual properties still needs to be checked before relying on them in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Modernized references
&lt;/h3&gt;

&lt;p&gt;SVG 2 also modernizes how elements reference other resources.&lt;/p&gt;

&lt;p&gt;For example, older SVG markup may contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;xlink:href=&lt;/span&gt;&lt;span class="s"&gt;"#search-icon"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern SVG markup can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#search-icon"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The older &lt;code&gt;xlink:href&lt;/code&gt; syntax is deprecated, although it remains recognized for backward compatibility.&lt;/p&gt;

&lt;p&gt;This relatively small change illustrates how SVG continues to evolve alongside the rest of the web platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Clearer rules for reusable graphics
&lt;/h3&gt;

&lt;p&gt;Reusability has always been one of SVG's strengths.&lt;/p&gt;

&lt;p&gt;Elements such as &lt;code&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; allow developers to define graphics once and reference them elsewhere.&lt;/p&gt;

&lt;p&gt;SVG 2 refines the specification around reusable elements, including their sizing, styling, and rendering behavior.&lt;/p&gt;

&lt;p&gt;For icon systems, these details matter because the same graphical asset may appear in many different contexts.&lt;/p&gt;

&lt;p&gt;The goal is greater consistency, although actual behavior still depends on browser implementations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this mean for icon libraries?
&lt;/h2&gt;

&lt;p&gt;For most developers using SVG icons today, the immediate impact is limited.&lt;/p&gt;

&lt;p&gt;Existing SVG files don't suddenly become obsolete because the specification has been updated.&lt;/p&gt;

&lt;p&gt;Simple, well-structured SVG icons remain a practical choice for modern interfaces.&lt;/p&gt;

&lt;p&gt;What matters most is still familiar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Icons should remain sharp at different sizes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling:&lt;/strong&gt; Colors and strokes should behave predictably.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Icons should remain visually coherent across an interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; SVG assets should render reliably in the environments where they're used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility:&lt;/strong&gt; Icons should be implemented appropriately, whether decorative or meaningful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These requirements aren't new. But they remain just as important while the underlying standard evolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should developers start using every SVG 2 feature?
&lt;/h2&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;A feature being defined in a specification doesn't automatically make it the best choice for every project.&lt;/p&gt;

&lt;p&gt;Before adopting a newer SVG capability, it's worth asking a few practical questions.&lt;/p&gt;

&lt;p&gt;Does it solve a real problem? Is it supported in the browsers your users rely on? Can the same result be achieved with a simpler, well-established approach?&lt;/p&gt;

&lt;p&gt;For an icon library, predictability is often more valuable than using the newest available syntax.&lt;/p&gt;

&lt;p&gt;There's little benefit in introducing additional complexity if it doesn't improve the final experience.&lt;/p&gt;

&lt;p&gt;Developers interested in implementation progress can consult the &lt;a href="https://wpt.fyi/results/svg" rel="noopener noreferrer"&gt;Web Platform Tests results for SVG&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These results provide a useful starting point for understanding browser conformance, although application-specific testing remains important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking ahead
&lt;/h2&gt;

&lt;p&gt;The October 2026 update is a positive development for the SVG ecosystem.&lt;/p&gt;

&lt;p&gt;It demonstrates that SVG is still being refined as part of the modern web platform, with ongoing attention to interoperability and implementation consistency.&lt;/p&gt;

&lt;p&gt;For designers and developers, this is worth following even when there's no immediate need to change an existing workflow.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://svgicons.com" rel="noopener noreferrer"&gt;SVGicons.com&lt;/a&gt;, we believe that simple, reliable, and easy-to-use SVG icons remain essential, regardless of how the specification evolves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A more capable SVG standard is good news. But reliable rendering and predictable integration are what make SVG icons useful.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/news/2026/updated-candidate-recommendation-scalable-vector-graphics-svg-2/" rel="noopener noreferrer"&gt;W3C — Updated Candidate Recommendation: SVG 2 (October 6, 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/2026/CR-SVG2-20261006/" rel="noopener noreferrer"&gt;SVG 2 — Candidate Recommendation Snapshot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/2026/CR-SVG2-20261006/changes.html" rel="noopener noreferrer"&gt;W3C — Changes from SVG 1.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wpt.fyi/results/svg" rel="noopener noreferrer"&gt;Web Platform Tests — SVG&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Published by &lt;a href="https://svgicons.com" rel="noopener noreferrer"&gt;SVGicons.com&lt;/a&gt; — SVG icons for designers and developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>css</category>
    </item>
    <item>
      <title>Why Icon Shape Still Matters</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Wed, 07 Oct 2026 12:59:51 +0000</pubDate>
      <link>https://dev.to/svgicons/why-icon-shape-still-matters-2d56</link>
      <guid>https://dev.to/svgicons/why-icon-shape-still-matters-2d56</guid>
      <description>&lt;p&gt;Consistency is one of the foundations of a good icon system.&lt;/p&gt;

&lt;p&gt;Icons should share proportions, stroke weight, optical balance, and visual language. When they belong to the same interface, they should feel like members of the same family.&lt;/p&gt;

&lt;p&gt;But consistency can also remove information.&lt;/p&gt;

&lt;p&gt;A recent discussion around increasingly standardized app icon shapes highlights an interesting design tradeoff: when every icon is placed inside the same outer shape, the silhouette stops helping us recognize it.&lt;/p&gt;

&lt;p&gt;And that means the glyph inside has to work harder.&lt;/p&gt;

&lt;h2&gt;
  
  
  An icon is more than its glyph
&lt;/h2&gt;

&lt;p&gt;When we think about an icon, we often focus on the symbol itself.&lt;/p&gt;

&lt;p&gt;A magnifying glass means search.&lt;/p&gt;

&lt;p&gt;A trash can means delete.&lt;/p&gt;

&lt;p&gt;A gear suggests settings.&lt;/p&gt;

&lt;p&gt;But recognition does not come from the internal symbol alone.&lt;/p&gt;

&lt;p&gt;Several visual signals work together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the outer silhouette&lt;/li&gt;
&lt;li&gt;the internal glyph&lt;/li&gt;
&lt;li&gt;color&lt;/li&gt;
&lt;li&gt;negative space&lt;/li&gt;
&lt;li&gt;proportions&lt;/li&gt;
&lt;li&gt;visual weight&lt;/li&gt;
&lt;li&gt;sometimes even texture or depth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The brain does not necessarily process these elements separately. It recognizes the whole object.&lt;/p&gt;

&lt;p&gt;That makes silhouette surprisingly important.&lt;/p&gt;

&lt;p&gt;A circle, star, shield, folder, cloud, or irregular outline can often be recognized before we consciously inspect what is inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standardization removes one recognition cue
&lt;/h2&gt;

&lt;p&gt;Imagine six icons with completely different outer shapes.&lt;/p&gt;

&lt;p&gt;Even in monochrome, their silhouettes already give us six distinct visual objects.&lt;/p&gt;

&lt;p&gt;Now place those same concepts inside six identical rounded-square containers.&lt;/p&gt;

&lt;p&gt;The layout becomes cleaner.&lt;/p&gt;

&lt;p&gt;The icons align perfectly.&lt;/p&gt;

&lt;p&gt;The interface feels more controlled.&lt;/p&gt;

&lt;p&gt;But one layer of differentiation has disappeared.&lt;/p&gt;

&lt;p&gt;The outer shape now communicates almost nothing because it is identical everywhere.&lt;/p&gt;

&lt;p&gt;Recognition depends much more heavily on the internal glyph.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The more standardized the container becomes, the more distinctive the symbol inside needs to be.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistency and recognizability are different goals
&lt;/h2&gt;

&lt;p&gt;This is an important distinction for icon designers.&lt;/p&gt;

&lt;p&gt;Consistency answers questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do these icons look like they belong together?&lt;/li&gt;
&lt;li&gt;Do they use the same visual grammar?&lt;/li&gt;
&lt;li&gt;Do they align correctly?&lt;/li&gt;
&lt;li&gt;Do they have similar optical weight?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recognizability asks something different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can users distinguish one icon from another quickly?&lt;/li&gt;
&lt;li&gt;Can the icon still be identified at a glance?&lt;/li&gt;
&lt;li&gt;Does it remain recognizable at small sizes?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A perfectly consistent icon set can still contain icons that are difficult to distinguish.&lt;/p&gt;

&lt;p&gt;In fact, excessive standardization can sometimes make that problem worse.&lt;/p&gt;

&lt;p&gt;If every icon uses the same container, stroke weight, corner radius, visual density, and construction rules, individual symbols may begin to look too similar.&lt;/p&gt;

&lt;p&gt;Consistency reduces noise.&lt;/p&gt;

&lt;p&gt;But some visual differences are useful information.&lt;/p&gt;

&lt;h2&gt;
  
  
  The glyph has to carry more meaning
&lt;/h2&gt;

&lt;p&gt;When the silhouette is fixed, the internal glyph becomes more important.&lt;/p&gt;

&lt;p&gt;That has practical consequences.&lt;/p&gt;

&lt;p&gt;Small differences between symbols matter more.&lt;/p&gt;

&lt;p&gt;Negative space matters more.&lt;/p&gt;

&lt;p&gt;The overall mass of the glyph matters more.&lt;/p&gt;

&lt;p&gt;And at small sizes, unnecessary detail becomes even more expensive.&lt;/p&gt;

&lt;p&gt;Consider two icons that both use the same rounded-square container.&lt;/p&gt;

&lt;p&gt;If their internal symbols are also similar, perhaps both using three horizontal lines with only small differences, users may need additional time to distinguish them.&lt;/p&gt;

&lt;p&gt;But if one symbol has a strong diagonal structure and the other has a clear circular structure, recognition becomes much faster.&lt;/p&gt;

&lt;p&gt;The container may be identical.&lt;/p&gt;

&lt;p&gt;The internal visual signature is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  This matters beyond app icons
&lt;/h2&gt;

&lt;p&gt;The same principle applies to many interface systems.&lt;/p&gt;

&lt;p&gt;Toolbar icons often share the same bounding box.&lt;/p&gt;

&lt;p&gt;Sidebar icons usually occupy identical slots.&lt;/p&gt;

&lt;p&gt;Design systems frequently enforce consistent icon dimensions.&lt;/p&gt;

&lt;p&gt;Component libraries normalize padding and alignment.&lt;/p&gt;

&lt;p&gt;All of that is useful.&lt;/p&gt;

&lt;p&gt;But once the external geometry becomes standardized, differentiation must happen inside that structure.&lt;/p&gt;

&lt;p&gt;This is especially important for large icon libraries.&lt;/p&gt;

&lt;p&gt;As the number of icons grows, designers cannot rely only on aesthetic consistency.&lt;/p&gt;

&lt;p&gt;They also need sufficient visual distance between related symbols.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;import vs export&lt;/li&gt;
&lt;li&gt;upload vs download&lt;/li&gt;
&lt;li&gt;duplicate vs copy&lt;/li&gt;
&lt;li&gt;expand vs maximize&lt;/li&gt;
&lt;li&gt;archive vs inbox&lt;/li&gt;
&lt;li&gt;refresh vs sync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These concepts are already semantically close.&lt;/p&gt;

&lt;p&gt;If their silhouettes, proportions, and internal constructions are also too similar, recognition becomes harder.&lt;/p&gt;

&lt;h2&gt;
  
  
  A useful design question
&lt;/h2&gt;

&lt;p&gt;When reviewing an icon set, we often ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this icon fit the visual system?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It may be useful to add another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If every surrounding visual cue disappeared, would this symbol still be easy to recognize?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or more specifically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the container shape were identical for every icon, would the glyph still be distinctive enough?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question changes how we evaluate icons.&lt;/p&gt;

&lt;p&gt;It pushes us to think not only about visual consistency, but also about information density and recognition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistency should support meaning, not erase it
&lt;/h2&gt;

&lt;p&gt;Standardization is not the enemy of good icon design.&lt;/p&gt;

&lt;p&gt;Without shared rules, icon sets quickly become chaotic.&lt;/p&gt;

&lt;p&gt;But the goal of those rules should be to create a coherent visual language without eliminating the differences users rely on.&lt;/p&gt;

&lt;p&gt;An icon system has to balance two forces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency helps users understand that icons belong together.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distinctiveness helps users understand that they mean different things.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good icon design needs both.&lt;/p&gt;

&lt;p&gt;When the outer shape becomes standardized, the responsibility simply moves inward.&lt;/p&gt;

&lt;p&gt;The glyph has to work harder.&lt;/p&gt;

</description>
      <category>design</category>
      <category>uiux</category>
      <category>webdev</category>
      <category>icons</category>
    </item>
    <item>
      <title>When SVG Optimization Fails, Your Pipeline Shouldn’t</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Tue, 06 Oct 2026 15:22:00 +0000</pubDate>
      <link>https://dev.to/svgicons/when-svg-optimization-fails-your-pipeline-shouldnt-2ab7</link>
      <guid>https://dev.to/svgicons/when-svg-optimization-fails-your-pipeline-shouldnt-2ab7</guid>
      <description>&lt;p&gt;SVG optimization is usually treated as a simple step in an asset pipeline.&lt;/p&gt;

&lt;p&gt;An SVG comes in.&lt;br&gt;&lt;br&gt;
An optimizer removes unnecessary data.&lt;br&gt;&lt;br&gt;
A smaller SVG comes out.&lt;/p&gt;

&lt;p&gt;But real-world SVG files are not always simple.&lt;/p&gt;

&lt;p&gt;They may contain embedded styles, unusual selectors, metadata, generated markup, accessibility attributes, or constructs that an optimizer does not fully understand.&lt;/p&gt;

&lt;p&gt;When that happens, an important question appears:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should an optimization failure make the asset itself fail?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In many pipelines, the answer is effectively yes.&lt;/p&gt;

&lt;p&gt;It probably shouldn’t be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization and validity are different questions
&lt;/h2&gt;

&lt;p&gt;Consider four operations that are often mixed together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PARSE → OPTIMIZE → VALIDATE → RENDER TEST&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They may happen one after another, but they answer very different questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parse
&lt;/h3&gt;

&lt;p&gt;Can the system read the SVG structure?&lt;/p&gt;

&lt;p&gt;If parsing fails, the document may genuinely be malformed or unsupported.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimize
&lt;/h3&gt;

&lt;p&gt;Can parts of the document be simplified or removed safely?&lt;/p&gt;

&lt;p&gt;This is a transformation.&lt;/p&gt;

&lt;p&gt;Failure here does not necessarily mean anything is wrong with the original asset.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate
&lt;/h3&gt;

&lt;p&gt;Does the SVG satisfy the rules required by the application or project?&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;required &lt;code&gt;viewBox&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;forbidden external resources&lt;/li&gt;
&lt;li&gt;naming conventions&lt;/li&gt;
&lt;li&gt;accessibility requirements&lt;/li&gt;
&lt;li&gt;maximum dimensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are project constraints, not optimization rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Render test
&lt;/h3&gt;

&lt;p&gt;Does the SVG actually produce the expected visual result?&lt;/p&gt;

&lt;p&gt;This can reveal problems that neither parsing nor structural validation can detect.&lt;/p&gt;

&lt;p&gt;These four stages should not be treated as interchangeable.&lt;/p&gt;

&lt;h2&gt;
  
  
  A recent SVGO example
&lt;/h2&gt;

&lt;p&gt;A recent SVGO issue illustrates the distinction.&lt;/p&gt;

&lt;p&gt;An SVG containing CSS pseudo-element selectors such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.icon::before { content: ""; }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;can currently cause the default optimization process to throw an error because part of the internal CSS processing does not support those selectors.&lt;/p&gt;

&lt;p&gt;The interesting part is not whether pseudo-elements are common inside SVG files.&lt;/p&gt;

&lt;p&gt;The interesting part is what the failure means.&lt;/p&gt;

&lt;p&gt;The SVG can still be parseable.&lt;/p&gt;

&lt;p&gt;It may still be renderable.&lt;/p&gt;

&lt;p&gt;It may still satisfy every requirement of the application using it.&lt;/p&gt;

&lt;p&gt;Yet the optimization stage cannot process one part of its stylesheet.&lt;/p&gt;

&lt;p&gt;That is an &lt;strong&gt;optimizer limitation&lt;/strong&gt;, not automatically an &lt;strong&gt;asset failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Related issue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/svg/svgo/issues/2308" rel="noopener noreferrer"&gt;https://github.com/svg/svgo/issues/2308&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure state matters
&lt;/h2&gt;

&lt;p&gt;Automated pipelines often reduce everything to two states:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SUCCESS&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;FAILURE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But asset processing usually needs more nuance.&lt;/p&gt;

&lt;p&gt;A better model could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parsed successfully&lt;/li&gt;
&lt;li&gt;Optimization skipped or partially completed&lt;/li&gt;
&lt;li&gt;Validation passed&lt;/li&gt;
&lt;li&gt;Render test passed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The asset can then continue through the pipeline while the optimization warning is recorded separately.&lt;/p&gt;

&lt;p&gt;For many systems, this is more useful than rejecting the file completely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizers should be conservative transformers
&lt;/h2&gt;

&lt;p&gt;An optimizer performs transformations.&lt;/p&gt;

&lt;p&gt;That means its safest behavior when encountering something it cannot confidently transform is often:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;leave it unchanged.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is very different from silently rewriting unfamiliar syntax.&lt;/p&gt;

&lt;p&gt;A conservative optimizer can effectively say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I cannot safely optimize this rule, so I will preserve it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The rest of the SVG may still contain dozens of optimizations that can be performed safely.&lt;/p&gt;

&lt;p&gt;This creates a useful engineering boundary:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unknown syntax → Preserve → Continue processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;instead of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unknown syntax → Reject entire asset&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The second behavior can make automated workflows unnecessarily fragile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipelines should preserve the reason for failure
&lt;/h2&gt;

&lt;p&gt;There is another important consequence.&lt;/p&gt;

&lt;p&gt;When a build system reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SVG FAILED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;the developer has very little information.&lt;/p&gt;

&lt;p&gt;Was the XML invalid?&lt;/p&gt;

&lt;p&gt;Did optimization fail?&lt;/p&gt;

&lt;p&gt;Did validation reject the file?&lt;/p&gt;

&lt;p&gt;Did the renderer produce a broken result?&lt;/p&gt;

&lt;p&gt;Those are completely different problems.&lt;/p&gt;

&lt;p&gt;A better pipeline exposes the actual stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PARSE&lt;/strong&gt; ✓&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OPTIMIZE&lt;/strong&gt; ⚠ Unsupported CSS selector&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VALIDATE&lt;/strong&gt; ✓&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RENDER&lt;/strong&gt; ✓&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the developer knows that the asset works, but one optimization could not be applied.&lt;/p&gt;

&lt;p&gt;That distinction becomes increasingly important as asset pipelines grow more automated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat optimization as an enhancement
&lt;/h2&gt;

&lt;p&gt;The simplest design principle is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimization should usually improve a valid asset, not define whether the asset is valid.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are exceptions.&lt;/p&gt;

&lt;p&gt;A team may deliberately require every SVG to pass a particular optimizer before deployment.&lt;/p&gt;

&lt;p&gt;That can be a perfectly valid project policy.&lt;/p&gt;

&lt;p&gt;But it should be an explicit policy.&lt;/p&gt;

&lt;p&gt;It should not happen accidentally because one transformation tool became the de facto validator for the entire pipeline.&lt;/p&gt;

&lt;p&gt;For SVG workflows, keeping responsibilities separate produces clearer failures, safer transformations, and pipelines that are much easier to debug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parse → Optimize → Validate → Render test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Four stages.&lt;/p&gt;

&lt;p&gt;Four different responsibilities.&lt;/p&gt;

&lt;p&gt;And an optimization failure does not always mean the SVG has failed.&lt;/p&gt;

</description>
      <category>svg</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>performance</category>
    </item>
    <item>
      <title>Your Empty Icon Searches Are Product Data</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Mon, 05 Oct 2026 17:30:08 +0000</pubDate>
      <link>https://dev.to/svgicons/your-empty-icon-searches-are-product-data-222b</link>
      <guid>https://dev.to/svgicons/your-empty-icon-searches-are-product-data-222b</guid>
      <description>&lt;p&gt;An icon search returns nothing.&lt;/p&gt;

&lt;p&gt;The obvious conclusion is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We don't have that icon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a small library, that may be true.&lt;/p&gt;

&lt;p&gt;In a search engine spanning hundreds of icon sets, it becomes much less obvious.&lt;/p&gt;

&lt;p&gt;The icon may already exist several times.&lt;/p&gt;

&lt;p&gt;One set may call it &lt;code&gt;settings&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another may call it &lt;code&gt;sliders&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another may use &lt;code&gt;tune&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A fourth may describe it as &lt;code&gt;configuration&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The concept exists.&lt;/p&gt;

&lt;p&gt;The catalog simply failed to connect the user's language with the vocabulary used by its sources.&lt;/p&gt;

&lt;p&gt;That makes an empty search more than a disappointing result.&lt;/p&gt;

&lt;p&gt;It can be evidence that the &lt;strong&gt;aggregation layer failed&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-set search creates a different problem
&lt;/h2&gt;

&lt;p&gt;Searching one icon set is relatively simple.&lt;/p&gt;

&lt;p&gt;The search vocabulary and the icon vocabulary usually come from the same source.&lt;/p&gt;

&lt;p&gt;Aggregating many sets changes that.&lt;/p&gt;

&lt;p&gt;Consider a user searching for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;preferences
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The catalog might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set A → settings
Set B → sliders
Set C → tune
Set D → configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no shortage of relevant icons.&lt;/p&gt;

&lt;p&gt;There is a shortage of agreement.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;If the system treats every zero-result search as missing content, the natural reaction is to add more icons.&lt;/p&gt;

&lt;p&gt;But adding a fifth representation of the same concept does not solve the real problem.&lt;/p&gt;

&lt;p&gt;The catalog already had the answer.&lt;/p&gt;

&lt;p&gt;The search layer couldn't retrieve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero results need a diagnosis
&lt;/h2&gt;

&lt;p&gt;A failed search can come from several different causes.&lt;/p&gt;

&lt;p&gt;For an aggregated icon catalog, a useful classification might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ZERO RESULT
   │
   ├─ SOURCE VOCABULARY GAP
   │
   ├─ AGGREGATION GAP
   │
   ├─ FILTER GAP
   │
   ├─ LOCALE GAP
   │
   └─ COVERAGE GAP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These failures look identical to the user.&lt;/p&gt;

&lt;p&gt;They are not identical to the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source vocabulary gap
&lt;/h2&gt;

&lt;p&gt;Suppose a collection contains an icon named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;receipt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but the user searches for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The source itself does not expose the terminology the user chose.&lt;/p&gt;

&lt;p&gt;That is a vocabulary mismatch.&lt;/p&gt;

&lt;p&gt;It does not necessarily require changing the original asset or canonical identifier.&lt;/p&gt;

&lt;p&gt;The search layer can preserve the source name while learning additional ways to retrieve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregation gap
&lt;/h2&gt;

&lt;p&gt;This is more interesting.&lt;/p&gt;

&lt;p&gt;Suppose several sets contain relevant concepts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;settings
sliders
adjustments
tune
configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but none of them appear for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;preferences
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Individually, each source may be perfectly reasonable.&lt;/p&gt;

&lt;p&gt;The problem appears only when they are combined.&lt;/p&gt;

&lt;p&gt;A multi-set search engine has an opportunity that the original collections did not have:&lt;/p&gt;

&lt;p&gt;it can build a layer above their differences.&lt;/p&gt;

&lt;p&gt;That layer can learn that multiple upstream names may express the same user intent.&lt;/p&gt;

&lt;p&gt;This is not simply better tagging.&lt;/p&gt;

&lt;p&gt;It is part of the value of aggregation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filter gap
&lt;/h2&gt;

&lt;p&gt;Search failures are also contextual.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wind turbine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The catalog contains several matching icons.&lt;/p&gt;

&lt;p&gt;But the user has selected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Style: Filled
License: MIT
Set: Collection X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and none of the matching results survive those filters.&lt;/p&gt;

&lt;p&gt;The query itself worked.&lt;/p&gt;

&lt;p&gt;The catalog coverage was sufficient.&lt;/p&gt;

&lt;p&gt;The search context removed the answer.&lt;/p&gt;

&lt;p&gt;So logging only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"wind turbine" → 0 results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;throws away important information.&lt;/p&gt;

&lt;p&gt;A useful failed-search record should preserve the context that produced the failure.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query
filters
selected sets
locale
result count
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, the team may spend time fixing something that was never a search problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Locale gap
&lt;/h2&gt;

&lt;p&gt;Icon terminology also changes between languages, regions and professional contexts.&lt;/p&gt;

&lt;p&gt;Even in English, users may describe the same concept differently.&lt;/p&gt;

&lt;p&gt;A designer, developer and accountant may not search for the same icon using the same words.&lt;/p&gt;

&lt;p&gt;A large catalog amplifies this because its upstream sources were often created by different teams, for different audiences, using different naming conventions.&lt;/p&gt;

&lt;p&gt;Again, the underlying asset can already exist.&lt;/p&gt;

&lt;p&gt;The retrieval vocabulary may simply be incomplete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coverage gap
&lt;/h2&gt;

&lt;p&gt;And then there are genuine gaps.&lt;/p&gt;

&lt;p&gt;Suppose users repeatedly search for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;quantum chip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no convincing equivalent under another name.&lt;/p&gt;

&lt;p&gt;No filter is hiding it.&lt;/p&gt;

&lt;p&gt;No related concept is already represented.&lt;/p&gt;

&lt;p&gt;Then the diagnosis is different.&lt;/p&gt;

&lt;p&gt;This time, the catalog really may be missing something.&lt;/p&gt;

&lt;p&gt;Adding new content becomes justified.&lt;/p&gt;

&lt;p&gt;The key is that &lt;strong&gt;content expansion comes after diagnosis, not before it&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A large catalog should not confuse quantity with coverage
&lt;/h2&gt;

&lt;p&gt;This becomes increasingly important as an icon catalog grows.&lt;/p&gt;

&lt;p&gt;A catalog with 300,000 icons can still fail a simple search.&lt;/p&gt;

&lt;p&gt;Not because it lacks visual assets.&lt;/p&gt;

&lt;p&gt;Because the assets came from many independent vocabularies.&lt;/p&gt;

&lt;p&gt;More content can even make the problem harder.&lt;/p&gt;

&lt;p&gt;Each new source may introduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new names
new categories
new style labels
new abbreviations
new terminology
new metadata conventions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the search challenge changes as the catalog expands.&lt;/p&gt;

&lt;p&gt;At some point, growth is no longer only about collecting more icons.&lt;/p&gt;

&lt;p&gt;It is about making heterogeneous collections behave like one coherent search space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not count queries. Group intent.
&lt;/h2&gt;

&lt;p&gt;There is another trap.&lt;/p&gt;

&lt;p&gt;Consider these failed searches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dark mode
darkmode
night theme
dark theme
theme dark
night UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Counting them as six unrelated failures would miss the interesting part.&lt;/p&gt;

&lt;p&gt;They may all express one intent.&lt;/p&gt;

&lt;p&gt;That means the useful signal is often not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many times did this exact string fail?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many users were trying to express this concept?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This changes prioritization dramatically.&lt;/p&gt;

&lt;p&gt;One unusual query repeated twice may not matter.&lt;/p&gt;

&lt;p&gt;Twenty different phrasings around the same missing concept probably do.&lt;/p&gt;

&lt;p&gt;For search quality, &lt;strong&gt;intent clusters can matter more than exact query counts&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the failed queries
&lt;/h2&gt;

&lt;p&gt;Once a search problem has been identified, the obvious next step is to fix it.&lt;/p&gt;

&lt;p&gt;But there is another useful step:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;keep the query that exposed it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose this failed yesterday:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;preferences → 0 results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You improve the search layer.&lt;/p&gt;

&lt;p&gt;Now it returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;settings
sliders
adjustments
tune
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not throw away the original failure.&lt;/p&gt;

&lt;p&gt;It has become a test case.&lt;/p&gt;

&lt;p&gt;The same applies to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dark mode
bill
night theme
wind turbine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every meaningful failure can become part of a small regression set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's failures can become tomorrow's tests
&lt;/h2&gt;

&lt;p&gt;This creates a simple loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OBSERVE
   ↓
DIAGNOSE
   ↓
FIX
   ↓
KEEP THE QUERY
   ↓
REPLAY
   ↓
MEASURE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After changing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ranking
metadata
aliases
filters
indexing
normalization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;replay previous failed searches.&lt;/p&gt;

&lt;p&gt;Then ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did this query start returning useful results?
Did another query get worse?
Did ranking improve?
Did a filter still hide the expected result?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now zero-result analytics are doing more than generating product ideas.&lt;/p&gt;

&lt;p&gt;They are contributing to search regression testing.&lt;/p&gt;

&lt;p&gt;That is a useful shift.&lt;/p&gt;

&lt;p&gt;A query that once demonstrated a problem can later verify that the problem stays fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search quality becomes cumulative
&lt;/h2&gt;

&lt;p&gt;Without this loop, search improvements can be difficult to measure.&lt;/p&gt;

&lt;p&gt;You fix one vocabulary problem.&lt;/p&gt;

&lt;p&gt;Then another.&lt;/p&gt;

&lt;p&gt;Then change ranking.&lt;/p&gt;

&lt;p&gt;Then import another 20 icon sets.&lt;/p&gt;

&lt;p&gt;Months later, the same search may silently fail again.&lt;/p&gt;

&lt;p&gt;A retained set of real failed queries gives the search engine memory.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAILED SEARCH REGRESSION SET

preferences
dark mode
bill
wind turbine
download cloud
user settings
archive box
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run them again after meaningful search changes.&lt;/p&gt;

&lt;p&gt;Not every query needs a perfect answer.&lt;/p&gt;

&lt;p&gt;But important previously solved failures should not quietly return.&lt;/p&gt;

&lt;h2&gt;
  
  
  The search box becomes a sensor
&lt;/h2&gt;

&lt;p&gt;There is a broader lesson here.&lt;/p&gt;

&lt;p&gt;In a large aggregated catalog, the search box is not only a retrieval interface.&lt;/p&gt;

&lt;p&gt;It is also a sensor.&lt;/p&gt;

&lt;p&gt;It reveals where:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user language
     ≠
catalog language
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and where:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aggregated data
     ≠
coherent search experience
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those mismatches are product information.&lt;/p&gt;

&lt;p&gt;They tell you where the abstraction above the underlying icon sets is incomplete.&lt;/p&gt;

&lt;p&gt;Sometimes the fix is an alias.&lt;/p&gt;

&lt;p&gt;Sometimes it is metadata.&lt;/p&gt;

&lt;p&gt;Sometimes it is normalization between sources.&lt;/p&gt;

&lt;p&gt;Sometimes it is filter behavior.&lt;/p&gt;

&lt;p&gt;Sometimes the icon really is missing.&lt;/p&gt;

&lt;p&gt;The search failure alone cannot tell you which.&lt;/p&gt;

&lt;p&gt;The diagnosis can.&lt;/p&gt;

&lt;h2&gt;
  
  
  The useful question is not how many searches failed
&lt;/h2&gt;

&lt;p&gt;Zero-result rate is still useful.&lt;/p&gt;

&lt;p&gt;It tells you that users sometimes reach a dead end.&lt;/p&gt;

&lt;p&gt;But for a multi-set icon search engine, the more important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why did the search fail when the catalog may already contain the answer?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is where empty searches become valuable.&lt;/p&gt;

&lt;p&gt;Not because every failed query demands another icon.&lt;/p&gt;

&lt;p&gt;But because every meaningful failure can reveal something about the distance between hundreds of independent icon sets and the single search experience built on top of them.&lt;/p&gt;

&lt;p&gt;And once those failures are preserved and replayed, they become something else too:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tests for whether the search engine is actually getting better.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>search</category>
      <category>ux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>External SVGs May Finally Become Themeable: Meet CSS Linked Parameters</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Sat, 03 Oct 2026 17:02:41 +0000</pubDate>
      <link>https://dev.to/svgicons/external-svgs-may-finally-become-themeable-meet-css-linked-parameters-28i4</link>
      <guid>https://dev.to/svgicons/external-svgs-may-finally-become-themeable-meet-css-linked-parameters-28i4</guid>
      <description>&lt;p&gt;SVG icons have always forced developers into a trade-off.&lt;/p&gt;

&lt;p&gt;Keep the SVG inline and you get excellent control from CSS.&lt;/p&gt;

&lt;p&gt;Load it as an external image and you get a clean, reusable asset — but most of that styling control disappears.&lt;/p&gt;

&lt;p&gt;A new CSS feature called &lt;strong&gt;CSS Linked Parameters&lt;/strong&gt; could narrow that gap.&lt;/p&gt;

&lt;p&gt;The interesting part is not simply that an external SVG may become recolorable. It is that an SVG file could expose a small, explicit &lt;strong&gt;theming interface&lt;/strong&gt; while remaining an external resource.&lt;/p&gt;

&lt;p&gt;That changes how we can think about reusable icon assets.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with external SVGs
&lt;/h2&gt;

&lt;p&gt;Consider a simple icon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/icons/notification.svg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is convenient.&lt;/p&gt;

&lt;p&gt;The SVG lives in its own file, the markup stays small, and the browser can treat the icon like any other external image resource.&lt;/p&gt;

&lt;p&gt;But there is a boundary.&lt;/p&gt;

&lt;p&gt;CSS from the host page cannot normally reach inside that SVG and change its individual paths.&lt;/p&gt;

&lt;p&gt;Something as natural as this does not solve the problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.notification&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rebeccapurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the icon contains hard-coded fills or strokes, changing &lt;code&gt;color&lt;/code&gt; on the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element does not magically propagate into its internal SVG elements.&lt;/p&gt;

&lt;p&gt;Inline SVG behaves very differently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"notification"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"currentColor"&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;currentColor&lt;/code&gt; can participate directly in the surrounding page styles.&lt;/p&gt;

&lt;p&gt;That makes inline SVG ideal for buttons, menus, states, themes and interactive UI.&lt;/p&gt;

&lt;p&gt;But it also means the graphic becomes markup instead of remaining a standalone image asset.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS masks solve one important case
&lt;/h2&gt;

&lt;p&gt;For monochrome icons, CSS masks already provide a very useful alternative.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;currentColor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url("/icons/search.svg")&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;contain&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SVG provides the shape while CSS provides the visible color.&lt;/p&gt;

&lt;p&gt;This works especially well for interface icons that should simply follow the text color.&lt;/p&gt;

&lt;p&gt;But a mask reduces the SVG to a silhouette.&lt;/p&gt;

&lt;p&gt;That is exactly what you want for many icons — and exactly what you do &lt;strong&gt;not&lt;/strong&gt; want for an icon containing multiple meaningful colors.&lt;/p&gt;

&lt;p&gt;Imagine a notification icon with a neutral bell and a red status badge.&lt;/p&gt;

&lt;p&gt;A mask cannot independently theme both parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if the external SVG exposed parameters?
&lt;/h2&gt;

&lt;p&gt;This is where CSS Linked Parameters becomes interesting.&lt;/p&gt;

&lt;p&gt;Instead of allowing the page to reach arbitrarily into the external SVG, the SVG itself can define values it is willing to receive.&lt;/p&gt;

&lt;p&gt;For example, our external &lt;code&gt;notification.svg&lt;/code&gt; could contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 24 24"
&amp;gt;
  &amp;lt;path
    fill="env(--icon-primary, #1f2937)"
    d="..."
  /&amp;gt;

  &amp;lt;circle
    cx="18"
    cy="6"
    r="4"
    fill="env(--icon-accent, #e11d48)"
  /&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two interesting pieces here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--icon-primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#1&lt;/span&gt;&lt;span class="nt"&gt;f2937&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--icon-accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#e11d48&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SVG defines two parameters it knows how to use.&lt;/p&gt;

&lt;p&gt;It also defines fallback colors.&lt;/p&gt;

&lt;p&gt;Without any values coming from the host page, the icon still has a complete visual appearance.&lt;/p&gt;

&lt;p&gt;Now consider the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"notification-icon"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/icons/notification.svg"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The host page could supply values through &lt;code&gt;link-parameters&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.notification-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--theme-icon-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#334155&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--theme-icon-accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e11d48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="py"&gt;link-parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--icon-primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-icon-primary&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--icon-accent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-icon-accent&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The page chooses the values.&lt;/p&gt;

&lt;p&gt;The SVG chooses what those values control.&lt;/p&gt;

&lt;p&gt;That separation is important.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not CSS inheritance through a wall
&lt;/h2&gt;

&lt;p&gt;It is tempting to describe this feature as making external SVGs behave like inline SVGs.&lt;/p&gt;

&lt;p&gt;That is not quite the right mental model.&lt;/p&gt;

&lt;p&gt;The parent page still does not suddenly gain unrestricted styling access to every path inside the external image.&lt;/p&gt;

&lt;p&gt;Instead, the SVG exposes an explicit contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--icon-primary
--icon-accent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The document consuming the icon supplies values for that contract.&lt;/p&gt;

&lt;p&gt;This is much closer to a component API than normal CSS inheritance.&lt;/p&gt;

&lt;p&gt;And for reusable icon assets, that may actually be better.&lt;/p&gt;

&lt;p&gt;The page should not need to know whether the red badge happens to be the third &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt;, a &lt;code&gt;&amp;lt;circle&amp;gt;&lt;/code&gt;, or part of a group.&lt;/p&gt;

&lt;p&gt;It only needs to know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This icon accepts an accent color.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SVG remains responsible for its own structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Light and dark themes become more interesting
&lt;/h2&gt;

&lt;p&gt;That contract could make an external icon respond to a design system without duplicating the SVG file.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.notification-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--theme-icon-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#334155&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--theme-icon-accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#dc2626&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="py"&gt;link-parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--icon-primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-icon-primary&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--icon-accent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-icon-accent&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.notification-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--theme-icon-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e2e8f0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--theme-icon-accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fb7185&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SVG file itself does not change.&lt;/p&gt;

&lt;p&gt;The URL does not need to switch between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;notification-light.svg
notification-dark.svg
notification-red.svg
notification-blue.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, the asset describes its visual structure and the consuming page provides the theme values.&lt;/p&gt;

&lt;p&gt;That is a subtle but useful shift.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four different SVG strategies
&lt;/h2&gt;

&lt;p&gt;CSS Linked Parameters would not make the existing approaches obsolete.&lt;/p&gt;

&lt;p&gt;They solve different problems.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;External asset&lt;/th&gt;
&lt;th&gt;Page-controlled color&lt;/th&gt;
&lt;th&gt;Multiple colors&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Inline SVG&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Maximum styling and interaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; today&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Very limited&lt;/td&gt;
&lt;td&gt;Fixed inside SVG&lt;/td&gt;
&lt;td&gt;Stable image assets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS mask&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Monochrome UI icons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linked Parameters&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Parameterized reusable assets&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is why the feature is interesting.&lt;/p&gt;

&lt;p&gt;It does not introduce a universal “best way” to use SVG.&lt;/p&gt;

&lt;p&gt;It potentially adds a missing fourth option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use inline SVG when
&lt;/h3&gt;

&lt;p&gt;you need deep styling, animation, DOM access or individual element manipulation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a CSS mask when
&lt;/h3&gt;

&lt;p&gt;the icon is fundamentally monochrome and should follow &lt;code&gt;currentColor&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a normal &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; when
&lt;/h3&gt;

&lt;p&gt;the SVG should behave like a fixed image and does not need runtime customization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linked Parameters may eventually fit when
&lt;/h3&gt;

&lt;p&gt;the SVG should remain external but expose a controlled set of visual choices.&lt;/p&gt;

&lt;p&gt;That last category is something the platform has not handled particularly elegantly before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fallbacks matter
&lt;/h2&gt;

&lt;p&gt;A parameterized icon should still be a valid icon when no parameter is provided.&lt;/p&gt;

&lt;p&gt;That is why this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--icon-accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#e11d48&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is more robust than designing the SVG under the assumption that a host page will always configure it correctly.&lt;/p&gt;

&lt;p&gt;The fallback is part of the asset.&lt;/p&gt;

&lt;p&gt;A well-designed parameterized SVG could therefore have two layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Default visual identity
        +
Optional host customization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes the file useful both as an ordinary image and as a theme-aware asset.&lt;/p&gt;

&lt;h2&gt;
  
  
  This could change how icon libraries describe SVGs
&lt;/h2&gt;

&lt;p&gt;Today an icon catalog typically exposes an SVG as a file or a block of markup.&lt;/p&gt;

&lt;p&gt;But parameterized SVGs suggest another possibility.&lt;/p&gt;

&lt;p&gt;An icon could eventually declare something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;notification.svg

Parameters:
--icon-primary
--icon-accent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another icon might expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--icon-fill
--icon-stroke
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A larger illustration could expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--surface
--foreground
--highlight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At that point, an SVG is no longer just a graphic file.&lt;/p&gt;

&lt;p&gt;It has a small public styling interface.&lt;/p&gt;

&lt;p&gt;For an icon search engine or design system, that metadata could become useful: developers could know immediately whether an asset is fixed, monochrome-themeable, or fully parameterizable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't ship your production icon system around this yet
&lt;/h2&gt;

&lt;p&gt;CSS Linked Parameters is still experimental.&lt;/p&gt;

&lt;p&gt;The specification is a work in progress, browser implementation is still evolving, and support is nowhere near a production baseline.&lt;/p&gt;

&lt;p&gt;Firefox has an experimental implementation, and WebKit has also been actively implementing pieces of the specification.&lt;/p&gt;

&lt;p&gt;That is encouraging.&lt;/p&gt;

&lt;p&gt;It is not the same thing as broad browser support.&lt;/p&gt;

&lt;p&gt;For production applications today, inline SVG, regular external SVGs and CSS masks remain the practical choices.&lt;/p&gt;

&lt;p&gt;But Linked Parameters is worth watching because it targets a real limitation rather than inventing another SVG embedding technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bigger idea
&lt;/h2&gt;

&lt;p&gt;For years, choosing an SVG integration strategy has often meant deciding between two useful properties:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;keep the graphic external&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;let the page control its appearance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CSS masks found a clever compromise for monochrome graphics.&lt;/p&gt;

&lt;p&gt;CSS Linked Parameters could eventually extend that idea to richer SVGs.&lt;/p&gt;

&lt;p&gt;And perhaps the most interesting part is not dynamic recoloring itself.&lt;/p&gt;

&lt;p&gt;It is the possibility of treating an SVG asset as something with a deliberate interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here is the graphic.

Here are the parts you are allowed to theme.

Everything else remains encapsulated.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That feels less like styling an image.&lt;/p&gt;

&lt;p&gt;It feels more like using a very small visual component.&lt;/p&gt;

&lt;p&gt;And that could be a useful direction for SVG icons on the Web.&lt;/p&gt;




&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;W3C — &lt;em&gt;CSS Linked Parameters Module Level 1&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;MDN — &lt;em&gt;link-parameters CSS property&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;MDN — &lt;em&gt;param() CSS function&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Mozilla — &lt;em&gt;Firefox experimental web features&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>svg</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>SVG Serialization Is a Security Boundary</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Fri, 02 Oct 2026 20:26:35 +0000</pubDate>
      <link>https://dev.to/svgicons/svg-serialization-is-a-security-boundary-2hh1</link>
      <guid>https://dev.to/svgicons/svg-serialization-is-a-security-boundary-2hh1</guid>
      <description>&lt;p&gt;When an application generates an SVG, it is tempting to think of the result as an image.&lt;/p&gt;

&lt;p&gt;But before it becomes pixels, SVG is structured markup.&lt;/p&gt;

&lt;p&gt;That distinction matters whenever untrusted data is involved.&lt;/p&gt;

&lt;p&gt;A recent vulnerability in Satori — which also affected the Node.js &lt;code&gt;ImageResponse&lt;/code&gt; path in Next.js — provides a useful example of why SVG serialization should be treated as a security boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened?
&lt;/h2&gt;

&lt;p&gt;Satori converts HTML and JSX-like structures into SVG.&lt;/p&gt;

&lt;p&gt;A security issue was discovered in the way certain values were escaped before being inserted into generated SVG output.&lt;/p&gt;

&lt;p&gt;Under the right conditions, attacker-controlled values could be interpreted as SVG markup instead of remaining plain data.&lt;/p&gt;

&lt;p&gt;The issue was fixed in Satori &lt;code&gt;0.33.5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The interesting part is what can happen after that SVG is generated.&lt;/p&gt;

&lt;p&gt;Next.js uses this rendering pipeline in the Node.js implementation of &lt;code&gt;ImageResponse&lt;/code&gt; from &lt;code&gt;next/og&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For affected Next.js 16 versions, applications passing attacker-controlled values into SVG content, attributes or styles could ultimately expose themselves to remote code execution.&lt;/p&gt;

&lt;p&gt;The affected range for this specific advisory is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Next.js &amp;gt;= 16.2.0 and &amp;lt; 16.3.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The specific fix landed in Next.js &lt;code&gt;16.3.6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Applications using the Edge implementation of &lt;code&gt;ImageResponse&lt;/code&gt;, or applications that do not pass attacker-controlled values into SVG content, attributes or styles, are not affected by this issue.&lt;/p&gt;

&lt;p&gt;Next.js subsequently published its September 2026 security release and recommends upgrading to the current patched releases rather than stopping at the first version containing this specific fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interesting part is not Next.js
&lt;/h2&gt;

&lt;p&gt;For an affected application, the immediate action is straightforward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;patch the dependency.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But there is a broader lesson here for anyone building systems that generate SVG.&lt;/p&gt;

&lt;p&gt;Consider a simplified pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USER INPUT
    ↓
APPLICATION DATA
    ↓
SVG SERIALIZER
    ↓
&amp;lt;svg&amp;gt;...&amp;lt;/svg&amp;gt;
    ↓
RENDERER / CONVERTER / BROWSER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the important trust boundaries sits here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPLICATION DATA
    ↓
[ ESCAPE / VALIDATE ]
    ↓
SVG SERIALIZER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once application data becomes markup, the rules change.&lt;/p&gt;

&lt;p&gt;A string that is harmless as application data may have a completely different meaning when inserted into an XML element, attribute, style declaration or another serialized structure.&lt;/p&gt;

&lt;p&gt;This is not unique to SVG.&lt;/p&gt;

&lt;p&gt;Developers already think this way about HTML generation, SQL queries, shell commands and templating systems.&lt;/p&gt;

&lt;p&gt;SVG deserves the same mental model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generated SVG is not automatically trusted SVG
&lt;/h2&gt;

&lt;p&gt;There is an easy assumption to make:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We generated the SVG ourselves, so it must be trusted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the application may control the SVG structure while an external user controls some of the values inserted into it.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userProvidedTitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; structure belongs to the application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;userProvidedTitle&lt;/code&gt; does not.&lt;/p&gt;

&lt;p&gt;The serializer has to preserve that distinction.&lt;/p&gt;

&lt;p&gt;If escaping fails, data may cross the boundary and become syntax.&lt;/p&gt;

&lt;p&gt;That is the core issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context matters after serialization too
&lt;/h2&gt;

&lt;p&gt;There is another interesting lesson in this vulnerability.&lt;/p&gt;

&lt;p&gt;The Satori advisory rates the escaping issue itself as moderate severity.&lt;/p&gt;

&lt;p&gt;But the impact depends on what consumes the generated SVG afterward.&lt;/p&gt;

&lt;p&gt;In the affected Next.js Node.js path, the consequences can become much more serious.&lt;/p&gt;

&lt;p&gt;So a security review of an SVG pipeline should not stop at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can this library generate valid SVG?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should also ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Where does the generated SVG go next?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A generated SVG might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sent directly to a browser;&lt;/li&gt;
&lt;li&gt;rasterized into PNG;&lt;/li&gt;
&lt;li&gt;passed to another parser;&lt;/li&gt;
&lt;li&gt;converted by a native library;&lt;/li&gt;
&lt;li&gt;cached by a server;&lt;/li&gt;
&lt;li&gt;embedded into another document;&lt;/li&gt;
&lt;li&gt;processed by an image-generation service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same serialization weakness can have very different consequences depending on the next component in the pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three practical rules
&lt;/h2&gt;

&lt;p&gt;For developers generating SVG dynamically, three rules are worth keeping in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Treat serialization as a security boundary
&lt;/h3&gt;

&lt;p&gt;Do not assume that values are safe simply because your application created the SVG structure.&lt;/p&gt;

&lt;p&gt;Untrusted values remain untrusted until they have been correctly encoded for the context in which they are inserted.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Patch the whole pipeline
&lt;/h3&gt;

&lt;p&gt;Knowing which library creates your SVG is not enough.&lt;/p&gt;

&lt;p&gt;Track the components that parse, serialize, optimize, render and convert it.&lt;/p&gt;

&lt;p&gt;A vulnerability can originate in one component and become significantly more serious because of what happens later in the pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Minimize what untrusted input can control
&lt;/h3&gt;

&lt;p&gt;Where possible, avoid allowing external input to define arbitrary SVG markup, attributes or styles.&lt;/p&gt;

&lt;p&gt;For many applications, external data only needs to control a limited set of values such as text, predefined colors or numeric dimensions.&lt;/p&gt;

&lt;p&gt;Reducing that surface makes the pipeline easier to understand and easier to secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  SVG is an image format — and markup
&lt;/h2&gt;

&lt;p&gt;Developers often work with SVG alongside PNG, WebP or JPEG.&lt;/p&gt;

&lt;p&gt;That can hide an important architectural difference.&lt;/p&gt;

&lt;p&gt;Raster formats primarily describe pixels.&lt;/p&gt;

&lt;p&gt;SVG describes a document.&lt;/p&gt;

&lt;p&gt;And documents are parsed.&lt;/p&gt;

&lt;p&gt;When SVG is generated dynamically, the transition from &lt;strong&gt;data&lt;/strong&gt; to &lt;strong&gt;document syntax&lt;/strong&gt; deserves the same attention we already give other serialization boundaries.&lt;/p&gt;

&lt;p&gt;The recent Satori and Next.js vulnerabilities are specific bugs affecting specific versions.&lt;/p&gt;

&lt;p&gt;They do not mean that dynamically generated SVG is inherently unsafe.&lt;/p&gt;

&lt;p&gt;But they provide a useful reminder:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the moment untrusted data becomes SVG markup, serialization becomes part of your security model.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/advisories/GHSA-vcvr-r3jv-pc5j" rel="noopener noreferrer"&gt;GitHub Security Advisory — Next.js: Remote Code Execution in &lt;code&gt;next/og&lt;/code&gt; &lt;code&gt;ImageResponse&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vercel/satori/security/advisories/GHSA-wx4j-mvgx-mqwp" rel="noopener noreferrer"&gt;GitHub Security Advisory — Improper escaping in Satori-generated SVG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/blog" rel="noopener noreferrer"&gt;Next.js — September 2026 Security Release&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>svg</category>
      <category>security</category>
      <category>webdev</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>An Icon API Should Be Able to Say “RTL Behavior Unknown</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Thu, 01 Oct 2026 17:13:53 +0000</pubDate>
      <link>https://dev.to/svgicons/an-icon-api-should-be-able-to-say-rtl-behavior-unknown-3fhp</link>
      <guid>https://dev.to/svgicons/an-icon-api-should-be-able-to-say-rtl-behavior-unknown-3fhp</guid>
      <description>&lt;p&gt;Right-to-left support creates an interesting problem for icon libraries.&lt;/p&gt;

&lt;p&gt;Some icons clearly depend on reading direction. Others clearly do not. Some need a dedicated RTL drawing rather than a simple horizontal flip.&lt;/p&gt;

&lt;p&gt;But there is another case that matters when you work with icons from many different sources:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if nobody has documented the intended RTL behavior at all?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For an icon aggregator, that should be a valid state.&lt;/p&gt;

&lt;p&gt;Not an invitation to guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  RTL support is not just a rendering problem
&lt;/h2&gt;

&lt;p&gt;It is tempting to treat right-to-left support as something that happens at the CSS layer.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"rtl"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;.icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scaleX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Technically, this flips the icon.&lt;/p&gt;

&lt;p&gt;Semantically, however, it may be wrong.&lt;/p&gt;

&lt;p&gt;An icon representing navigation may need to change direction.&lt;/p&gt;

&lt;p&gt;A clock normally should not.&lt;/p&gt;

&lt;p&gt;A list icon may need a different composition.&lt;/p&gt;

&lt;p&gt;An icon containing letters or numbers may require a completely separate asset, because mirroring the SVG would also mirror its content.&lt;/p&gt;

&lt;p&gt;So the real question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can this SVG be flipped?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Was this icon intended to change in an RTL interface?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are very different questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some icon systems already encode this knowledge
&lt;/h2&gt;

&lt;p&gt;This is not purely theoretical.&lt;/p&gt;

&lt;p&gt;Microsoft's Fluent UI System Icons includes direction information in icon metadata. An icon can be marked as one that can be mirrored or one that has distinct RTL and LTR versions.&lt;/p&gt;

&lt;p&gt;Source:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/microsoft/fluentui-system-icons/blob/main/README.md" rel="noopener noreferrer"&gt;https://github.com/microsoft/fluentui-system-icons/blob/main/README.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wikimedia's Codex design system also documents that some icons should be mirrored, some should remain unchanged, and some require dedicated RTL assets.&lt;/p&gt;

&lt;p&gt;For example, Codex treats icons representing horizontal direction or text differently from icons representing concepts such as time.&lt;/p&gt;

&lt;p&gt;Source:&lt;br&gt;&lt;br&gt;
&lt;a href="https://doc.wikimedia.org/codex/latest/style-guide/icons.html" rel="noopener noreferrer"&gt;https://doc.wikimedia.org/codex/latest/style-guide/icons.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important lesson is not that every icon library must use the same rules.&lt;/p&gt;

&lt;p&gt;It is almost the opposite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Different icon systems may make different decisions.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The aggregator problem
&lt;/h2&gt;

&lt;p&gt;Things become more complicated when an icon service contains assets from many independent icon sets.&lt;/p&gt;

&lt;p&gt;Imagine four source libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set A → explicitly documents RTL behavior
Set B → provides separate LTR and RTL assets
Set C → contains directional icons but no metadata
Set D → says nothing about RTL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An aggregator cannot safely treat all four sources the same way.&lt;/p&gt;

&lt;p&gt;It may know that an icon from Set A can be mirrored.&lt;/p&gt;

&lt;p&gt;It may know that an icon from Set B has a dedicated RTL equivalent.&lt;/p&gt;

&lt;p&gt;But with Set C or Set D, the correct behavior may simply be unknown.&lt;/p&gt;

&lt;p&gt;That distinction should survive the import process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unknown is useful metadata
&lt;/h2&gt;

&lt;p&gt;A directionality model for a multi-source icon library could expose states such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;neutral
mirror
variant
unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;neutral
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the same icon should normally be used in both directions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mirror
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means horizontal mirroring is explicitly supported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means a separate RTL asset exists.&lt;/p&gt;

&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the source does not provide enough information to make that decision safely.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;unknown&lt;/code&gt; may look like incomplete data.&lt;/p&gt;

&lt;p&gt;In reality, it is valuable data.&lt;/p&gt;

&lt;p&gt;It tells developers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We do not have an authoritative directionality decision for this icon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is much better than silently inventing one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Absence of metadata is not permission
&lt;/h2&gt;

&lt;p&gt;Consider an icon named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arrow-turn-right
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An automated importer could decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It contains "right", therefore it must be mirrored in RTL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds reasonable until naming describes geometry rather than semantic direction.&lt;/p&gt;

&lt;p&gt;Or consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;reply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should it mirror?&lt;/p&gt;

&lt;p&gt;Possibly.&lt;/p&gt;

&lt;p&gt;But that decision may depend on how the source design system defines the metaphor.&lt;/p&gt;

&lt;p&gt;The same problem appears with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enter
exit
login
logout
forward
undo
redo
send
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Names provide hints.&lt;/p&gt;

&lt;p&gt;They do not provide authority.&lt;/p&gt;

&lt;p&gt;A large icon platform should therefore distinguish between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inferred behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source-defined behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ideally, automatic inference should never silently replace the latter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preserve provenance
&lt;/h2&gt;

&lt;p&gt;Directionality becomes much more useful when combined with provenance.&lt;/p&gt;

&lt;p&gt;Instead of returning only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mirror"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;an API could eventually expose something closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mirror"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"upstream"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes an important distinction visible.&lt;/p&gt;

&lt;p&gt;Did the original icon project specify this behavior?&lt;/p&gt;

&lt;p&gt;Was it added by the aggregation platform?&lt;/p&gt;

&lt;p&gt;Was it inferred?&lt;/p&gt;

&lt;p&gt;Was it manually reviewed?&lt;/p&gt;

&lt;p&gt;Once icon metadata is consumed automatically, provenance matters almost as much as the metadata itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for APIs
&lt;/h2&gt;

&lt;p&gt;Suppose an application requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /icons/back
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Today, an icon API might simply return an SVG.&lt;/p&gt;

&lt;p&gt;A direction-aware API could return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"back"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mirror"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A different icon could return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"document-numbered-list"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"variant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"variants"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ltr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rtl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"custom-arrow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the consumer has enough information to make a deliberate decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters even more for coding agents
&lt;/h2&gt;

&lt;p&gt;This becomes especially important when an AI agent is choosing assets.&lt;/p&gt;

&lt;p&gt;Imagine asking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add a back action suitable for an Arabic interface.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without metadata, the agent may:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;search for a back icon,&lt;/li&gt;
&lt;li&gt;retrieve an SVG,&lt;/li&gt;
&lt;li&gt;notice that the interface is RTL,&lt;/li&gt;
&lt;li&gt;decide by itself whether to mirror it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last step is where uncertainty is being hidden.&lt;/p&gt;

&lt;p&gt;A better workflow would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search icon
→ retrieve directionality metadata
→ choose RTL behavior
→ generate implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when the metadata says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the agent should not silently pretend otherwise.&lt;/p&gt;

&lt;p&gt;It could instead choose an icon with known RTL support or flag the decision for review.&lt;/p&gt;

&lt;p&gt;For automated UI generation, this distinction matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  CLI tools need the same information
&lt;/h2&gt;

&lt;p&gt;The same idea applies outside an HTTP API.&lt;/p&gt;

&lt;p&gt;A CLI could expose directionality during search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;svgicons search &lt;span class="s2"&gt;"back"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with results such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Back Arrow        mirror
Chevron Left      mirror
History Back      unknown
Navigation Back   variant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or allow filtering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;svgicons search &lt;span class="s2"&gt;"back"&lt;/span&gt; &lt;span class="nt"&gt;--rtl-safe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An MCP tool could expose the same property to IDE agents.&lt;/p&gt;

&lt;p&gt;Once this information exists as structured metadata, every interface can use it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web search&lt;/li&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;li&gt;CLI&lt;/li&gt;
&lt;li&gt;React components&lt;/li&gt;
&lt;li&gt;Vue components&lt;/li&gt;
&lt;li&gt;MCP tools&lt;/li&gt;
&lt;li&gt;coding agents&lt;/li&gt;
&lt;li&gt;design system pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Do not flatten upstream knowledge
&lt;/h2&gt;

&lt;p&gt;An aggregator creates value by making many icon sets searchable through one interface.&lt;/p&gt;

&lt;p&gt;But aggregation should not erase useful differences between those sets.&lt;/p&gt;

&lt;p&gt;If a source library provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;icon-x-ltr.svg
icon-x-rtl.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that relationship should ideally be preserved.&lt;/p&gt;

&lt;p&gt;If another source explicitly says an icon can be mirrored, that should also be preserved.&lt;/p&gt;

&lt;p&gt;And if a third source provides no information, that absence should remain visible.&lt;/p&gt;

&lt;p&gt;Otherwise, aggregation can accidentally turn carefully designed behavior into guesswork.&lt;/p&gt;

&lt;h2&gt;
  
  
  A possible metadata model
&lt;/h2&gt;

&lt;p&gt;A simple model might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"known"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"behavior"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mirror"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"provenance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"upstream"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a dedicated pair:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"known"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"behavior"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"variant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"provenance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"upstream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ltr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icon-id-ltr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rtl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icon-id-rtl"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when nothing reliable is known:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directionality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact schema is less important than the principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;uncertainty should be represented instead of hidden.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  This is bigger than RTL
&lt;/h2&gt;

&lt;p&gt;There is a broader lesson here for icon infrastructure.&lt;/p&gt;

&lt;p&gt;Modern icon libraries increasingly feed automated systems.&lt;/p&gt;

&lt;p&gt;SVG files are consumed by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build tools,&lt;/li&gt;
&lt;li&gt;component generators,&lt;/li&gt;
&lt;li&gt;APIs,&lt;/li&gt;
&lt;li&gt;IDE extensions,&lt;/li&gt;
&lt;li&gt;design systems,&lt;/li&gt;
&lt;li&gt;AI agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As this happens, an icon is no longer just vector geometry.&lt;/p&gt;

&lt;p&gt;It increasingly needs machine-readable context.&lt;/p&gt;

&lt;p&gt;Directionality is one example.&lt;/p&gt;

&lt;p&gt;Others might include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;theme compatibility
semantic role
filled/outline relationship
deprecated aliases
accessibility guidance
brand restrictions
source provenance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better metadata reduces the number of assumptions downstream tools need to make.&lt;/p&gt;

&lt;h2&gt;
  
  
  The safest default is sometimes “we don't know”
&lt;/h2&gt;

&lt;p&gt;Developers usually prefer APIs that return precise answers.&lt;/p&gt;

&lt;p&gt;But precision should not be manufactured.&lt;/p&gt;

&lt;p&gt;For an icon platform aggregating many independent sources, there will always be metadata that exists for some sets and not for others.&lt;/p&gt;

&lt;p&gt;RTL behavior is a good example.&lt;/p&gt;

&lt;p&gt;When the upstream project provides the answer, preserve it.&lt;/p&gt;

&lt;p&gt;When an explicit RTL variant exists, expose it.&lt;/p&gt;

&lt;p&gt;When mirroring is documented, expose that too.&lt;/p&gt;

&lt;p&gt;And when the information does not exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is a perfectly useful answer.&lt;/p&gt;

&lt;p&gt;Because when a tool does not know whether an icon should change direction, the safest behavior is not to guess more confidently.&lt;/p&gt;

&lt;p&gt;It is to preserve the uncertainty.&lt;/p&gt;




&lt;p&gt;At &lt;a href="https://svgicons.com/" rel="noopener noreferrer"&gt;SVGicons.com&lt;/a&gt;, we are interested in how icon metadata can make large multi-set libraries more useful to developers, APIs and automated workflows.&lt;/p&gt;

&lt;p&gt;RTL directionality is a small detail visually.&lt;/p&gt;

&lt;p&gt;But for machines choosing and transforming icons automatically, it is exactly the kind of detail that should not be left implicit.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>svg</category>
      <category>internationalization</category>
      <category>api</category>
    </item>
    <item>
      <title>AI Agents Need an Icon Contract</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Wed, 30 Sep 2026 16:43:23 +0000</pubDate>
      <link>https://dev.to/svgicons/ai-agents-need-an-icon-contract-not-just-an-icon-catalog-5m6</link>
      <guid>https://dev.to/svgicons/ai-agents-need-an-icon-contract-not-just-an-icon-catalog-5m6</guid>
      <description>&lt;p&gt;AI coding agents are getting much better at finding assets.&lt;/p&gt;

&lt;p&gt;Give an agent access to an icon library and it can search for &lt;code&gt;settings&lt;/code&gt;, &lt;code&gt;download&lt;/code&gt;, &lt;code&gt;database&lt;/code&gt;, or &lt;code&gt;user&lt;/code&gt; and return several usable SVGs in seconds.&lt;/p&gt;

&lt;p&gt;That solves an important problem.&lt;/p&gt;

&lt;p&gt;But it does not solve the whole problem.&lt;/p&gt;

&lt;p&gt;An interface can contain individually good icons and still feel inconsistent.&lt;/p&gt;

&lt;p&gt;The reason is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finding an icon is not the same as knowing which icon belongs in a project.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As agents take a larger role in generating interfaces, they need more than access to an icon catalog.&lt;/p&gt;

&lt;p&gt;They need an &lt;strong&gt;icon contract&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search solves discovery
&lt;/h2&gt;

&lt;p&gt;The first generation of AI-assisted icon workflows naturally focused on search.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;leaving the IDE,&lt;/li&gt;
&lt;li&gt;opening an icon website,&lt;/li&gt;
&lt;li&gt;searching manually,&lt;/li&gt;
&lt;li&gt;downloading an SVG,&lt;/li&gt;
&lt;li&gt;copying it into the project,&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;an agent can search the library directly.&lt;/p&gt;

&lt;p&gt;That is already useful.&lt;/p&gt;

&lt;p&gt;With APIs, CLIs, MCP servers, and other developer integrations, an agent can retrieve icons without interrupting the coding workflow.&lt;/p&gt;

&lt;p&gt;But consider what happens after the search.&lt;/p&gt;

&lt;p&gt;A query for &lt;code&gt;settings&lt;/code&gt; may return dozens or hundreds of valid results.&lt;/p&gt;

&lt;p&gt;Which one should the agent use?&lt;/p&gt;

&lt;p&gt;The answer depends on the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  A project contains rules that search cannot know
&lt;/h2&gt;

&lt;p&gt;Two icons can represent the same concept while belonging to completely different visual systems.&lt;/p&gt;

&lt;p&gt;One may be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16px&lt;/li&gt;
&lt;li&gt;filled&lt;/li&gt;
&lt;li&gt;geometric&lt;/li&gt;
&lt;li&gt;sharp&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another may be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;24px&lt;/li&gt;
&lt;li&gt;outlined&lt;/li&gt;
&lt;li&gt;rounded&lt;/li&gt;
&lt;li&gt;2px stroke&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are technically correct results for &lt;code&gt;settings&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Only one may belong in the current interface.&lt;/p&gt;

&lt;p&gt;The same problem exists at the implementation level.&lt;/p&gt;

&lt;p&gt;Should the icon be inserted as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Settings&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or loaded from a sprite?&lt;/p&gt;

&lt;p&gt;Should the project use individual package imports?&lt;/p&gt;

&lt;p&gt;Should SVGs inherit &lt;code&gt;currentColor&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Should decorative icons use &lt;code&gt;aria-hidden="true"&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;None of those decisions can be answered by search alone.&lt;/p&gt;

&lt;p&gt;They require &lt;strong&gt;project context&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four layers of an icon contract
&lt;/h2&gt;

&lt;p&gt;A useful way to think about this is to divide icon context into four layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Semantic rules
&lt;/h3&gt;

&lt;p&gt;The first layer defines what visual metaphor the product uses for a concept.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;settings       → gear
delete         → trash
external link  → arrow-up-right
notifications  → bell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may look obvious, but products often develop their own vocabulary over time.&lt;/p&gt;

&lt;p&gt;An agent should not replace an established metaphor just because another icon scored highly in search.&lt;/p&gt;

&lt;p&gt;Semantic consistency matters too.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Visual rules
&lt;/h3&gt;

&lt;p&gt;The next layer defines how icons should look.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;family      → Project Outline
style       → outline
canvas      → 24 × 24
stroke      → 2px
line caps   → round
line joins  → round
color       → currentColor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the difference between using icons individually and using them as a &lt;strong&gt;system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The agent should ideally search within those constraints instead of searching the entire catalog first and trying to fix inconsistencies later.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Implementation rules
&lt;/h3&gt;

&lt;p&gt;Visual consistency is only half the problem.&lt;/p&gt;

&lt;p&gt;The agent also needs to understand how the application consumes icons.&lt;/p&gt;

&lt;p&gt;A React project might define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;framework      → React
icon format    → components
imports        → individual imports
default size   → 20
color          → inherited
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A different project might prefer inline SVG.&lt;/p&gt;

&lt;p&gt;Another might use Vue components, a sprite, raw SVG files, or generated TypeScript components.&lt;/p&gt;

&lt;p&gt;An agent that knows these rules can produce code that fits the existing architecture instead of introducing a new icon pattern every time it touches the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Policy rules
&lt;/h3&gt;

&lt;p&gt;Finally, there are project rules that are neither visual nor technical.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allowed sources   → approved libraries only
license policy    → compatible with project distribution
accessibility     → decorative icons hidden from screen readers
provenance        → original source retained
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These rules become increasingly important when agents can search across very large catalogs.&lt;/p&gt;

&lt;p&gt;The easiest icon to retrieve is not necessarily the icon the project should use.&lt;/p&gt;

&lt;h2&gt;
  
  
  From icon search to icon selection
&lt;/h2&gt;

&lt;p&gt;This changes the role of an icon service.&lt;/p&gt;

&lt;p&gt;The basic workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query
↓
search results
↓
icon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A context-aware workflow looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user intent
↓
project icon contract
↓
candidate search
↓
constraint filtering
↓
implementation
↓
consistent UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search still matters.&lt;/p&gt;

&lt;p&gt;But it becomes one step inside a larger decision process.&lt;/p&gt;

&lt;p&gt;That distinction matters because AI agents operate repeatedly.&lt;/p&gt;

&lt;p&gt;A developer may ask an agent to build a toolbar today, a settings panel tomorrow, and a dashboard next week.&lt;/p&gt;

&lt;p&gt;If each session starts from an empty context, the agent may make slightly different decisions every time.&lt;/p&gt;

&lt;p&gt;Those differences accumulate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project should remember
&lt;/h2&gt;

&lt;p&gt;A useful icon contract does not necessarily require a complex new standard.&lt;/p&gt;

&lt;p&gt;It could simply be project-readable context.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;icons&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-outline&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;outline&lt;/span&gt;
  &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt;
  &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

&lt;span class="na"&gt;implementation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;react&lt;/span&gt;
  &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;component&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;currentColor&lt;/span&gt;

&lt;span class="na"&gt;semantics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;settings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gear&lt;/span&gt;
  &lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trash&lt;/span&gt;
  &lt;span class="na"&gt;external-link&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arrow-up-right&lt;/span&gt;

&lt;span class="na"&gt;policy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;accessibility&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;required&lt;/span&gt;
  &lt;span class="na"&gt;preserve-source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact syntax is not the important part.&lt;/p&gt;

&lt;p&gt;The important part is that these decisions live with the project rather than inside one temporary prompt.&lt;/p&gt;

&lt;p&gt;That gives future agents something stable to work from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for AI-generated interfaces
&lt;/h2&gt;

&lt;p&gt;AI agents are moving from isolated code generation toward longer-running work inside real codebases.&lt;/p&gt;

&lt;p&gt;That changes the problem.&lt;/p&gt;

&lt;p&gt;When an agent creates one button, picking a reasonable icon may be enough.&lt;/p&gt;

&lt;p&gt;When an agent contributes to hundreds of interface elements over weeks or months, local decisions need to follow global rules.&lt;/p&gt;

&lt;p&gt;The same principle already exists elsewhere in software development.&lt;/p&gt;

&lt;p&gt;Projects have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formatting rules&lt;/li&gt;
&lt;li&gt;linting rules&lt;/li&gt;
&lt;li&gt;dependency policies&lt;/li&gt;
&lt;li&gt;component conventions&lt;/li&gt;
&lt;li&gt;design tokens&lt;/li&gt;
&lt;li&gt;coding guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Icons need similar context.&lt;/p&gt;

&lt;p&gt;Not because icons are unusually complicated.&lt;/p&gt;

&lt;p&gt;Because &lt;strong&gt;consistency is a project property, not a search result&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The next step for icon tooling
&lt;/h2&gt;

&lt;p&gt;Large icon catalogs will remain useful.&lt;/p&gt;

&lt;p&gt;Better search will remain useful.&lt;/p&gt;

&lt;p&gt;Agent integrations will remain useful.&lt;/p&gt;

&lt;p&gt;But the next useful layer may be the connection between the catalog and the rules of the project consuming it.&lt;/p&gt;

&lt;p&gt;An agent should eventually be able to understand:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find me an icon for this concept — but only one that belongs in this interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much more interesting problem than retrieval alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search finds candidates.&lt;br&gt;&lt;br&gt;
Project context decides what fits.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And as agents generate more of our interfaces, that context may become just as important as the icon catalog itself.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>designsystems</category>
      <category>svg</category>
    </item>
    <item>
      <title>Animated Icons Need a Motion Contract</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Tue, 29 Sep 2026 22:02:19 +0000</pubDate>
      <link>https://dev.to/svgicons/animated-icons-need-a-motion-contract-4bgm</link>
      <guid>https://dev.to/svgicons/animated-icons-need-a-motion-contract-4bgm</guid>
      <description>&lt;p&gt;&lt;em&gt;Trigger, duration, looping, accessibility and reduced motion should travel with the asset.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An SVG icon is usually easy to describe.&lt;/p&gt;

&lt;p&gt;It has a name.&lt;br&gt;&lt;br&gt;
A size.&lt;br&gt;&lt;br&gt;
A viewBox.&lt;br&gt;&lt;br&gt;
A style.&lt;br&gt;&lt;br&gt;
Maybe a stroke width, a category and a license.&lt;/p&gt;

&lt;p&gt;But once that icon starts moving, those properties are no longer enough.&lt;/p&gt;

&lt;p&gt;An animated icon does not only have an appearance.&lt;/p&gt;

&lt;p&gt;It has &lt;strong&gt;behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And behavior needs rules.&lt;/p&gt;
&lt;h2&gt;
  
  
  The SVG file is only part of the asset
&lt;/h2&gt;

&lt;p&gt;Consider a download icon.&lt;/p&gt;

&lt;p&gt;The same basic icon could be used in several completely different ways.&lt;/p&gt;

&lt;p&gt;It could remain static:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;download
└── static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It could animate briefly when the user starts a download:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;download
└── interaction feedback
    ├── trigger: click
    ├── duration: 240ms
    └── loop: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or it could represent an operation that is still running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;download
└── progress
    ├── trigger: state-change
    ├── loop: while-pending
    └── semantic purpose: status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The geometry may be almost identical.&lt;/p&gt;

&lt;p&gt;The integration contract is not.&lt;/p&gt;

&lt;p&gt;That distinction matters when icons are distributed through libraries, APIs, component packages or automated development tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motion has a trigger
&lt;/h2&gt;

&lt;p&gt;An animation should not exist without knowing what starts it.&lt;/p&gt;

&lt;p&gt;Typical triggers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page or component load&lt;/li&gt;
&lt;li&gt;hover&lt;/li&gt;
&lt;li&gt;keyboard focus&lt;/li&gt;
&lt;li&gt;click or tap&lt;/li&gt;
&lt;li&gt;application state change&lt;/li&gt;
&lt;li&gt;explicit programmatic control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not interchangeable.&lt;/p&gt;

&lt;p&gt;A hover animation may make sense as optional feedback on desktop, but not as the only way to expose information.&lt;/p&gt;

&lt;p&gt;A loading animation should usually be controlled by application state rather than by pointer interaction.&lt;/p&gt;

&lt;p&gt;An animation associated with keyboard focus should behave correctly for keyboard users rather than simply reproducing &lt;code&gt;:hover&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;animated: true&lt;/code&gt; is not very useful metadata.&lt;/p&gt;

&lt;p&gt;Something like this is more useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;motion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;interaction&lt;/span&gt;
  &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hover&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;focus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the consumer knows something about how the asset is intended to behave.&lt;/p&gt;

&lt;h2&gt;
  
  
  One-shot and looping animations solve different problems
&lt;/h2&gt;

&lt;p&gt;There is another important distinction: &lt;strong&gt;does the animation finish?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A short animation after an action can acknowledge that something happened.&lt;/p&gt;

&lt;p&gt;A loop often communicates something different: activity, waiting, synchronization or an ongoing process.&lt;/p&gt;

&lt;p&gt;Those behaviors should not be confused.&lt;/p&gt;

&lt;p&gt;Imagine an icon rotating after the user presses a refresh button.&lt;/p&gt;

&lt;p&gt;A single rotation could mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your action was received.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Continuous rotation could mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Refresh is still in progress.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Same icon.&lt;/p&gt;

&lt;p&gt;Very different semantics.&lt;/p&gt;

&lt;p&gt;A useful motion description therefore needs to say whether the animation is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or perhaps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;while-active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That information belongs closer to the asset than many current icon formats allow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Duration is part of the component contract
&lt;/h2&gt;

&lt;p&gt;Developers frequently customize animation duration after importing an icon.&lt;/p&gt;

&lt;p&gt;But duration is not always merely decoration.&lt;/p&gt;

&lt;p&gt;A very short movement may feel like interaction feedback.&lt;/p&gt;

&lt;p&gt;A longer movement may communicate transition or progression.&lt;/p&gt;

&lt;p&gt;An infinite animation creates an entirely different runtime behavior.&lt;/p&gt;

&lt;p&gt;For reusable assets, it can therefore be useful to expose an intended duration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;240ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not necessarily mean consumers must use exactly 240 milliseconds.&lt;/p&gt;

&lt;p&gt;It means the asset communicates its intended behavior instead of forcing every implementation to reconstruct it from scratch.&lt;/p&gt;

&lt;p&gt;The same applies to easing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;easing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ease-out&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, the important idea is not that every icon library needs identical values.&lt;/p&gt;

&lt;p&gt;The important idea is that &lt;strong&gt;motion properties can be part of the asset definition&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motion should not carry important information alone
&lt;/h2&gt;

&lt;p&gt;Animation can reinforce meaning.&lt;/p&gt;

&lt;p&gt;It should be much more carefully treated when it becomes the only way to understand state.&lt;/p&gt;

&lt;p&gt;Suppose a download icon animates while a file is being transferred and stops when the transfer completes.&lt;/p&gt;

&lt;p&gt;If animation is the only indication of that state, removing the movement could also remove the information.&lt;/p&gt;

&lt;p&gt;A better implementation might combine motion with another state change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DOWNLOADING
animated arrow
+
accessible status
+
state change

COMPLETE
static check mark
+
accessible status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Font Awesome's accessibility documentation makes a similar practical point: animation should complement other indications of state rather than be the only indication.&lt;/p&gt;

&lt;p&gt;That principle becomes particularly important when reduced-motion preferences enter the picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduced motion is not just &lt;code&gt;animation: none&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Browsers expose the user's motion preference through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-reduced-motion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* reduced-motion behavior */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The W3C documents &lt;code&gt;prefers-reduced-motion&lt;/code&gt; as a technique for preventing motion triggered by user interactions when appropriate.&lt;/p&gt;

&lt;p&gt;But there is an important product-design question hidden behind that CSS rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What should replace the animation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes the answer really is a static icon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;reducedMotion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;static&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes the movement can be reduced while preserving another visual transition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;reducedMotion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fade&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And sometimes the animation communicates application state, in which case simply removing it may be insufficient.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;motion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;semanticPurpose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;progress&lt;/span&gt;
  &lt;span class="na"&gt;reducedMotion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;animation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;explicit-status&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is that the fallback is intentional.&lt;/p&gt;

&lt;p&gt;Reduced motion should not be an emergency patch applied after the asset has already shipped.&lt;/p&gt;

&lt;p&gt;It should be part of its behavior definition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility requirements are moving in this direction
&lt;/h2&gt;

&lt;p&gt;This is also becoming more relevant from a standards perspective.&lt;/p&gt;

&lt;p&gt;EN 301 549 V4.1.1, published in September 2026, updates the European accessibility standard for ICT and adopts WCAG 2.2 as its accessibility baseline. The revision also expands how user accessibility preferences are considered.&lt;/p&gt;

&lt;p&gt;There is an important legal distinction: V4.1.1 has been published, but it has not yet replaced V3.2.1 as the harmonized reference used for presumption of conformity under the relevant EU legislation. That requires formal citation in the Official Journal of the European Union.&lt;/p&gt;

&lt;p&gt;So the interesting takeaway for developers is not "a new law requires animated icons."&lt;/p&gt;

&lt;p&gt;It does not.&lt;/p&gt;

&lt;p&gt;The broader signal is that respecting user preferences is becoming increasingly explicit in accessibility practice.&lt;/p&gt;

&lt;p&gt;Motion-aware components should be designed accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  An animated icon needs a motion contract
&lt;/h2&gt;

&lt;p&gt;This leads to a useful abstraction.&lt;/p&gt;

&lt;p&gt;Instead of treating an animated icon as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;icon.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we could treat it as an asset plus a &lt;strong&gt;motion contract&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;download&lt;/span&gt;
&lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;outline&lt;/span&gt;

&lt;span class="na"&gt;motion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;state-change&lt;/span&gt;
  &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;240ms&lt;/span&gt;
  &lt;span class="na"&gt;loop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;semanticPurpose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;feedback&lt;/span&gt;

  &lt;span class="na"&gt;reducedMotion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;static&lt;/span&gt;
    &lt;span class="na"&gt;preserveState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;formats&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;svg&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;animated-svg&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;lottie&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a proposed standard.&lt;/p&gt;

&lt;p&gt;It is simply a way of making implicit behavior explicit.&lt;/p&gt;

&lt;p&gt;A production schema would probably need more detail: interruption behavior, easing, supported interaction modes, state mapping and runtime requirements could all matter.&lt;/p&gt;

&lt;p&gt;But even a small contract already answers questions that the SVG geometry cannot answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Format also changes the runtime contract
&lt;/h2&gt;

&lt;p&gt;An animated SVG, a Lottie animation and a video export may look similar on screen.&lt;/p&gt;

&lt;p&gt;They are not equivalent assets.&lt;/p&gt;

&lt;p&gt;An animated SVG may expose DOM elements that can be styled or controlled.&lt;/p&gt;

&lt;p&gt;A Lottie file brings its own animation model and runtime.&lt;/p&gt;

&lt;p&gt;WebM or MP4 is fundamentally media playback.&lt;/p&gt;

&lt;p&gt;That means &lt;code&gt;format&lt;/code&gt; is no longer just an export preference.&lt;/p&gt;

&lt;p&gt;It can change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;runtime dependencies&lt;/li&gt;
&lt;li&gt;styling possibilities&lt;/li&gt;
&lt;li&gt;interaction control&lt;/li&gt;
&lt;li&gt;accessibility implementation&lt;/li&gt;
&lt;li&gt;reduced-motion handling&lt;/li&gt;
&lt;li&gt;bundle and network cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A catalog that offers animated assets should therefore describe not only what formats are available, but what those formats imply.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should an icon catalog expose?
&lt;/h2&gt;

&lt;p&gt;For static icons, common metadata might include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name
category
style
viewBox
stroke/fill
license
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For animated icons, I would add another layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;motion
├── trigger
├── duration
├── easing
├── loop behavior
├── semantic purpose
├── reduced-motion behavior
└── available animation formats
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Potentially also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interaction
├── hover
├── focus
├── press
└── programmatic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This turns animation from a visual preview into something developers can actually reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  APIs should return behavior, not just files
&lt;/h2&gt;

&lt;p&gt;This becomes even more important when assets are retrieved programmatically.&lt;/p&gt;

&lt;p&gt;Imagine an icon API returning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"download"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"svg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"animated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client still knows almost nothing about how to use the animation.&lt;/p&gt;

&lt;p&gt;Compare that with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"download"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"motion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"state-change"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"durationMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;240&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"loop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"semanticPurpose"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"feedback"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reducedMotion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"static"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the result can be evaluated before the asset is inserted into an interface.&lt;/p&gt;

&lt;p&gt;The same principle applies to a CLI.&lt;/p&gt;

&lt;p&gt;And it becomes especially interesting for agent-based development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding agents need these rules even more than humans do
&lt;/h2&gt;

&lt;p&gt;A developer looking at an animated icon can usually infer some of its intended behavior.&lt;/p&gt;

&lt;p&gt;An automated coding agent has a harder problem.&lt;/p&gt;

&lt;p&gt;Suppose an agent receives the instruction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Add an animated download icon to the toolbar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which asset should it choose?&lt;/p&gt;

&lt;p&gt;Should the animation run continuously?&lt;/p&gt;

&lt;p&gt;On hover?&lt;/p&gt;

&lt;p&gt;When the download begins?&lt;/p&gt;

&lt;p&gt;Should keyboard focus trigger it too?&lt;/p&gt;

&lt;p&gt;What happens when the operating system requests reduced motion?&lt;/p&gt;

&lt;p&gt;Without structured information, the agent has to guess.&lt;/p&gt;

&lt;p&gt;With a motion contract, it can reason against explicit constraints.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request:
"Show feedback when the user starts downloading."

Candidate A
trigger: hover
purpose: decorative

Candidate B
trigger: state-change
purpose: feedback
loop: false
reducedMotion: static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Candidate B matches the requested behavior for reasons that are machine-readable.&lt;/p&gt;

&lt;p&gt;That is much safer than selecting an asset because its preview simply "looks appropriate."&lt;/p&gt;

&lt;h2&gt;
  
  
  The catalog becomes part of the design system
&lt;/h2&gt;

&lt;p&gt;This is the larger consequence.&lt;/p&gt;

&lt;p&gt;Once icons contain behavioral metadata, an icon catalog stops being only a repository of files.&lt;/p&gt;

&lt;p&gt;It begins to describe part of the interface system.&lt;/p&gt;

&lt;p&gt;The catalog can answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which icons are suitable for interaction feedback?&lt;/li&gt;
&lt;li&gt;Which animations loop?&lt;/li&gt;
&lt;li&gt;Which require runtime support?&lt;/li&gt;
&lt;li&gt;Which have static fallbacks?&lt;/li&gt;
&lt;li&gt;Which respond to reduced-motion preferences?&lt;/li&gt;
&lt;li&gt;Which animations communicate state?&lt;/li&gt;
&lt;li&gt;Which formats are available for each environment?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those answers are useful to developers.&lt;/p&gt;

&lt;p&gt;They are even more useful to tools operating on behalf of developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical checklist
&lt;/h2&gt;

&lt;p&gt;Before shipping an animated icon, ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What starts the animation?&lt;/li&gt;
&lt;li&gt;Does keyboard interaction receive equivalent behavior?&lt;/li&gt;
&lt;li&gt;Can application state control it directly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Timing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How long does it run?&lt;/li&gt;
&lt;li&gt;Does it loop?&lt;/li&gt;
&lt;li&gt;Can it be interrupted?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Meaning&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the motion decorative, feedback, progress or state communication?&lt;/li&gt;
&lt;li&gt;Would the interface still communicate correctly if movement disappeared?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens under &lt;code&gt;prefers-reduced-motion&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Is there a static or reduced-motion alternative?&lt;/li&gt;
&lt;li&gt;Is important state communicated by something other than motion?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Runtime&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the asset animated SVG, CSS, JavaScript, Lottie or video?&lt;/li&gt;
&lt;li&gt;Does it introduce a runtime dependency?&lt;/li&gt;
&lt;li&gt;Can the application control its state?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Distribution&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can an API expose these properties?&lt;/li&gt;
&lt;li&gt;Can a CLI inspect them?&lt;/li&gt;
&lt;li&gt;Could a coding agent use them when selecting an asset?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these questions cannot be answered, the animated icon may be visually complete but &lt;strong&gt;operationally underspecified&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The icon is not just what it looks like
&lt;/h2&gt;

&lt;p&gt;Static icon systems taught us to treat properties such as size, stroke, style and licensing as structured information.&lt;/p&gt;

&lt;p&gt;Motion introduces another dimension.&lt;/p&gt;

&lt;p&gt;When an icon moves, developers need to know more than what the file contains.&lt;/p&gt;

&lt;p&gt;They need to know &lt;strong&gt;why it moves, when it moves, how long it moves, whether it repeats, and what should happen when movement should be reduced&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That information should not have to be reverse-engineered from a preview.&lt;/p&gt;

&lt;p&gt;An animated icon needs more than an SVG file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It needs a motion contract.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>webdev</category>
      <category>a11y</category>
      <category>frontend</category>
    </item>
    <item>
      <title>The Price Tag Is Not the License</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Tue, 29 Sep 2026 16:23:42 +0000</pubDate>
      <link>https://dev.to/svgicons/the-price-tag-is-not-the-license-35hh</link>
      <guid>https://dev.to/svgicons/the-price-tag-is-not-the-license-35hh</guid>
      <description>&lt;p&gt;Downloading an icon is easy.&lt;/p&gt;

&lt;p&gt;Understanding what you are allowed to do with it six months later is much harder.&lt;/p&gt;

&lt;p&gt;A developer finds an SVG, downloads it, optimizes it, renames the file and adds it to a repository.&lt;/p&gt;

&lt;p&gt;The icon now looks like every other asset in the project.&lt;/p&gt;

&lt;p&gt;What may no longer be visible is where it came from, under which license it was obtained, whether attribution is required, or whether redistribution is allowed.&lt;/p&gt;

&lt;p&gt;That is the real problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The price of an asset does not describe its usage rights.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;$0&lt;/code&gt; download tells you how much you paid.&lt;/p&gt;

&lt;p&gt;It does not tell you what you can do with the file.&lt;/p&gt;




&lt;h2&gt;
  
  
  An SVG can lose its context very quickly
&lt;/h2&gt;

&lt;p&gt;Imagine a typical workflow.&lt;/p&gt;

&lt;p&gt;You download:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dashboard.svg
search.svg
settings.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;optimize the SVG&lt;/li&gt;
&lt;li&gt;normalize its dimensions&lt;/li&gt;
&lt;li&gt;change its color handling&lt;/li&gt;
&lt;li&gt;rename it&lt;/li&gt;
&lt;li&gt;move it into your application repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few weeks later, the files may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;icons/
  analytics.svg
  search.svg
  preferences.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The graphics survived perfectly.&lt;/p&gt;

&lt;p&gt;But the original context may not have.&lt;/p&gt;

&lt;p&gt;Where did &lt;code&gt;analytics.svg&lt;/code&gt; come from?&lt;/p&gt;

&lt;p&gt;Which collection?&lt;/p&gt;

&lt;p&gt;Which version?&lt;/p&gt;

&lt;p&gt;Which license applied at the time?&lt;/p&gt;

&lt;p&gt;Was attribution required?&lt;/p&gt;

&lt;p&gt;Could the file be modified?&lt;/p&gt;

&lt;p&gt;Could it be redistributed inside another downloadable product?&lt;/p&gt;

&lt;p&gt;If the answers live only in someone's browser history, the workflow is fragile.&lt;/p&gt;




&lt;h2&gt;
  
  
  Free is a price condition, not a usage model
&lt;/h2&gt;

&lt;p&gt;Developers often use words such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;free icon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as if "free" described the asset itself.&lt;/p&gt;

&lt;p&gt;It does not.&lt;/p&gt;

&lt;p&gt;It describes one dimension of the transaction.&lt;/p&gt;

&lt;p&gt;There are other questions that matter just as much:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Where did it come from?
What license applies?
Is attribution required?
Can it be modified?
Can it be redistributed?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those questions become especially important when assets move between projects, teams and products.&lt;/p&gt;

&lt;p&gt;An icon can be perfectly appropriate for one use case and require additional attention for another.&lt;/p&gt;

&lt;p&gt;That is why a useful asset pipeline should preserve more than pixels and paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  The asset should carry its usage context
&lt;/h2&gt;

&lt;p&gt;A more robust way to think about an icon is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;icon
+ origin
+ license
+ obligations
+ permitted use
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SVG file is only one part of the asset.&lt;/p&gt;

&lt;p&gt;The rest is metadata.&lt;/p&gt;

&lt;p&gt;In practical terms, a project could retain information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"analytics.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"collection"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-icons"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/icons/analytics"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example License"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attribution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"modification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"redistribution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"check terms"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact format is less important than the principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The information should stay close to the asset.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not in an old bookmark.&lt;/p&gt;

&lt;p&gt;Not in a Slack message.&lt;/p&gt;

&lt;p&gt;Not in the memory of the developer who originally downloaded it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Modification should not break traceability
&lt;/h2&gt;

&lt;p&gt;Icon workflows rarely keep source files untouched.&lt;/p&gt;

&lt;p&gt;Developers optimize SVGs.&lt;/p&gt;

&lt;p&gt;Designers adjust paths.&lt;/p&gt;

&lt;p&gt;Build systems convert them into components.&lt;/p&gt;

&lt;p&gt;Applications may generate sprites, symbol sets or framework-specific assets.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;original SVG
    ↓
optimized SVG
    ↓
React component
    ↓
application bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The representation changes.&lt;/p&gt;

&lt;p&gt;The provenance should not.&lt;/p&gt;

&lt;p&gt;The same applies to usage information.&lt;/p&gt;

&lt;p&gt;A transformed asset should still be traceable back to the conditions under which it entered the project.&lt;/p&gt;

&lt;p&gt;Otherwise optimization becomes an accidental metadata deletion step.&lt;/p&gt;




&lt;h2&gt;
  
  
  Redistribution is where missing context becomes expensive
&lt;/h2&gt;

&lt;p&gt;During development, an icon may simply appear inside an interface.&lt;/p&gt;

&lt;p&gt;Later, the same project may become:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a reusable component library&lt;/li&gt;
&lt;li&gt;a design system&lt;/li&gt;
&lt;li&gt;a downloadable template&lt;/li&gt;
&lt;li&gt;an SDK&lt;/li&gt;
&lt;li&gt;a commercial application&lt;/li&gt;
&lt;li&gt;an open-source repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The asset has not necessarily changed.&lt;/p&gt;

&lt;p&gt;The way it is distributed has.&lt;/p&gt;

&lt;p&gt;At that point, knowing only that the icon was "free" is not very useful.&lt;/p&gt;

&lt;p&gt;The team needs the original context.&lt;/p&gt;

&lt;p&gt;This is why license information should be considered part of dependency management rather than something checked once during download.&lt;/p&gt;




&lt;h2&gt;
  
  
  Treat icons more like dependencies
&lt;/h2&gt;

&lt;p&gt;Software teams already preserve metadata for code dependencies.&lt;/p&gt;

&lt;p&gt;A package manager does not simply download files and forget where they came from.&lt;/p&gt;

&lt;p&gt;Projects retain information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package
version
source
license
dependency tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Icon assets deserve a similar level of discipline.&lt;/p&gt;

&lt;p&gt;Not because every icon workflow needs a complex compliance system.&lt;/p&gt;

&lt;p&gt;But because provenance becomes much easier to maintain when it is captured at the moment the asset enters the project.&lt;/p&gt;

&lt;p&gt;The best time to record usage rights is not six months later.&lt;/p&gt;

&lt;p&gt;It is during acquisition.&lt;/p&gt;




&lt;h2&gt;
  
  
  A simple rule for icon pipelines
&lt;/h2&gt;

&lt;p&gt;Before an icon becomes part of a project, capture at least:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SOURCE
LICENSE
ATTRIBUTION
MODIFICATION
REDISTRIBUTION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then keep that information with the asset or with the project's asset manifest.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;discover
   ↓
verify
   ↓
record
   ↓
transform
   ↓
ship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;download
   ↓
forget
   ↓
investigate later
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That small change makes future decisions much easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  The useful question is not "Is this icon free?"
&lt;/h2&gt;

&lt;p&gt;A better question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do we still know what we are allowed to do with this asset?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That question remains useful long after the download button has disappeared.&lt;/p&gt;

&lt;p&gt;Good asset pipelines preserve more than the file.&lt;/p&gt;

&lt;p&gt;They preserve the information required to use the file responsibly.&lt;/p&gt;

&lt;p&gt;Because the price tag is not the license.&lt;/p&gt;

&lt;p&gt;And usage rights should travel with the asset.&lt;/p&gt;

</description>
      <category>svg</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Your SVG Has No Scripts. Is It Safe to Process?</title>
      <dc:creator>Svg/icons</dc:creator>
      <pubDate>Fri, 25 Sep 2026 14:37:10 +0000</pubDate>
      <link>https://dev.to/svgicons/your-svg-has-no-scripts-is-it-safe-to-process-3di</link>
      <guid>https://dev.to/svgicons/your-svg-has-no-scripts-is-it-safe-to-process-3di</guid>
      <description>&lt;p&gt;An application accepts an SVG icon, removes scripts and event handlers, then generates a preview. Has it made the file safe?&lt;/p&gt;

&lt;p&gt;It has addressed one category of risk. The next question is what happens inside the software that reads and renders the file.&lt;/p&gt;

&lt;p&gt;Two recent vulnerability reports show why that distinction matters for developers building icon importers, asset pipelines and preview services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two bugs that do not need JavaScript
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;librsvg&lt;/strong&gt;, CVE-2026-96889 concerns nested XML inclusions with duplicate entity declarations. During processing, an XML entity could be freed while the parser was still using it: a &lt;strong&gt;use-after-free&lt;/strong&gt; error.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://rustsec.org/advisories/RUSTSEC-2026-0305.html" rel="noopener noreferrer"&gt;RustSec advisory&lt;/a&gt;, issued on September 23, 2026, lists fixes in versions &lt;strong&gt;2.63.2&lt;/strong&gt; and &lt;strong&gt;2.62.4&lt;/strong&gt; for the respective release branches.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/memononen/nanosvg/issues/294" rel="noopener noreferrer"&gt;NanoSVG report&lt;/a&gt; describes a different failure. Extreme arc radius values can make an intermediate calculation produce &lt;strong&gt;NaN&lt;/strong&gt; — “not a number.” Converting that value to an integer without checking it introduces undefined behavior.&lt;/p&gt;

&lt;p&gt;The report demonstrates the problem with a runtime sanitizer; the associated CVE, &lt;strong&gt;CVE-2026-88366&lt;/strong&gt;, describes a potential denial of service.&lt;/p&gt;

&lt;p&gt;Neither mechanism requires JavaScript.&lt;/p&gt;

&lt;p&gt;These are issues in specific implementations and versions. They do not establish that every SVG renderer is vulnerable. They do show why “contains no scripts” is an incomplete security test.&lt;/p&gt;

&lt;h2&gt;
  
  
  The file passes through more than one component
&lt;/h2&gt;

&lt;p&gt;Consider a typical icon upload feature. Before an icon reaches the interface, it might pass through an XML parser, a sanitizer, an optimizer and a rasterizer that creates thumbnails.&lt;/p&gt;

&lt;p&gt;Each component processes input supplied by someone else.&lt;/p&gt;

&lt;p&gt;Even the sanitizer has to read the original file. A later filter cannot protect an earlier component that has already encountered a malicious input.&lt;/p&gt;

&lt;p&gt;For teams handling untrusted SVGs, four layers deserve attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Sanitize for the intended use
&lt;/h2&gt;

&lt;p&gt;Define which elements, attributes and references your application needs.&lt;/p&gt;

&lt;p&gt;A static icon usually requires a smaller feature set than an interactive SVG document. Use a maintained sanitizer with an explicit policy.&lt;/p&gt;

&lt;p&gt;Sanitization remains useful, but its output should not be treated as proof that every downstream parser can safely process the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Track and patch the actual dependencies
&lt;/h2&gt;

&lt;p&gt;Identify what parses and renders SVGs in your deployed application, including libraries bundled inside converters or image-processing tools.&lt;/p&gt;

&lt;p&gt;Check affected versions and available fixes. Updating your own code does not necessarily update the library inside a thumbnail generator or conversion service.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Bound the work
&lt;/h2&gt;

&lt;p&gt;Set limits on upload size, rendering dimensions, execution time and memory.&lt;/p&gt;

&lt;p&gt;A small file is not necessarily cheap to process. Complex geometry or other expensive input can demand more work than its file size suggests.&lt;/p&gt;

&lt;p&gt;Limits help contain excessive resource consumption; they do not repair memory-safety bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Isolate untrusted processing
&lt;/h2&gt;

&lt;p&gt;Where practical, run conversion and preview generation in a restricted worker with minimal permissions and no unnecessary network or filesystem access.&lt;/p&gt;

&lt;p&gt;Design the application to handle a failed worker without taking down the main service.&lt;/p&gt;

&lt;p&gt;Apply these protections from the first component that reads untrusted input, including sanitization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask what happens when processing fails
&lt;/h2&gt;

&lt;p&gt;These layers address different failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sanitization&lt;/strong&gt; restricts content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Patches&lt;/strong&gt; fix known defects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limits&lt;/strong&gt; bound resource use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt; reduces the consequences of a failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an SVG icon pipeline, the useful question is broader than “Did we remove the scripts?”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which components read this file, and what happens if one of them fails?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://rustsec.org/advisories/RUSTSEC-2026-0305.html" rel="noopener noreferrer"&gt;RustSec: librsvg use-after-free advisory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/memononen/nanosvg/issues/294" rel="noopener noreferrer"&gt;NanoSVG: original arc conversion bug report&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://secalerts.co/vulnerability/CVE-2026-88366" rel="noopener noreferrer"&gt;CVE-2026-88366 details&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>svg</category>
      <category>security</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
