A more efficient and organized workflow for SVGs

Steven Harley

SVGs can be messy to develop with, often times being exported from a graphics application and being pasted into a document. However, they become much more delightful to work with when you have a readable file and clean markup.

Optimizing SVG for the web

When an SVG is exported from an application, it usually comes with code that’s unnecessary for rendering it on the web. For example, in Sketch, they add code to allow for easier re-importing into Sketch. If you use Sketch and you’re just exporting for use on the web, you can run this command in your terminal:

defaults write com.bohemiancoding.sketch3 exportCompactSVG -bool yes

This will change the way Sketch exports the files, making them more compact and web-ready. You’ll need to log out of your Mac user account or restart your computer for this change to take effect.

It’s also a good idea to run generated SVGs through an optimizer in order to quickly strip it down to only what’s necessary to render it on the page. This becomes more important when embedding SVGs in your application because those extra lines of code and comments show up in the markup.

I’ve found SVGO to be a great addition to my SVG workflow. SVGO is a Nodejs-based tool for optimizing SVG files. A simple command removes or converts the insignificant information in SVGs, reducing the file size without affecting rendering. It has a plugin-based architecture, so you can enable or disable different optimizations to best fit your needs. It works great out of the box, but if you want to learn more about the individual optimizations, check out their github.

To get started, install SVGO:

npm install -g svgo

In my workflow, I’m usually adding SVGs as I go, and optimizing them after I export them from Sketch or Adobe Illustrator. To optimize a single SVG, it’s simply svgo followed by the relative path to the file and where to output it.

svgo --pretty ~/Desktop/ralph.svg app/assets/images/svg/ralph.min.svg

The --pretty option isn’t required, it just “pretty prints” the SVG to make diffing easier.

Embedding Inline SVG in Rails applications

Having your SVG inline, rather than referencing it via an <img> tag, is a great way to keep control over your document. Inlining means no additional HTTP requests to load the graphic and the ability to use CSS and JavaScript to manipulate individual parts of an SVG.

Rather than creating a partial that contains the SVG and including that, we can use a helper method. This lets us reference it cleanly, similar to an <img> tag, but with the benefits of having the code available in the markup.

I’ve been experimenting with a helper similar to what James Martin wrote here on coderwall. You can put the following code in app/helpers/application_helper.rb:

  def embedded_svg(filename, options = {})
    assets = Rails.application.assets
    file = assets.find_asset(filename).source.force_encoding("UTF-8")
    doc = Nokogiri::HTML::DocumentFragment.parse file
    svg = doc.at_css "svg"
    if options[:class].present?
      svg["class"] = options[:class]
    end
    raw doc
  end

This uses Sprockets to locate the file and reference it simply in your markup. All you need to do is call the helper method with the path to the SVG relative to app/assets/images directory:

= embedded_svg "svg/ralph.svg"

The helper also allows for CSS classes to be added for easier manipulation:

= embedded_svg "images/svg/ralph.svg", class: "ralph-logo"

These small changes in my workflow have helped me spend less time optimizing by hand and organizing my SVGs. What tips or tools do you use to improve your SVG workflow?