How to Render SVG Icons in Ruby on Rails
This post shows how I render SVG icons in my Ruby on Rails applications. Instead of littering your HTML with complicated SVG tags, keep them tucked away in a folder as an ERB partial, and use a Rails helper to insert it in your views. Result: reusable, customizable icons and readable HTML.
One of the first things I do whenever I start a new Rails project is create a helper method to render SVG icons.
module ApplicationHelper
def render_icon(icon, classes: nil)
classes ||= ""
render "icons/#{icon}", classes: classes
end
end
Then, whenever I want to add a new SVG icon to my application, I add it as an ERB partial under the views/icons directory. I also give it a class attribute that will be inserted dynamically via the partial parameter.
<%# views/icons/_register.html.erb %>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" class="<%= classes %>" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path ... />
<path ... />
</svg>
Finally, I use the above helper in my ERB view templates as follows:
<%= render_icon 'register', classes: 'h-24 w-24' %>
I stumbled on this solution a few months ago, and have been using ever since. The nice benefit of this approach is that it doesn't litter your HTML views with complex SVG code and keeps them readable. You can also easily re-use these icons elsewhere, customizing them by passing classes as needed.
Thought I'd share this with y'all as I haven't seen this approach mentioned online that much. Most of the articles and videos mention creating the SVG filetype in asset compilation, using external gems, rendering SVGs as images, or building custom ERB helpers to read and insert the SVG files, etc. which all seem too complicated to me.
What do you think?
Update: On Reddit, one commenter mentioned that using the inline_svg gem would allow me to keep the icons as SVG images (instead of ERB partials), what's the benefit, you ask? You can see them in your IDE!
Personally, I haven't had the need to see them so far (you can still see them in browser, if you need to), but it's a good point, still. Make sure you think about this trade-off before picking a solution.
Sign up for my newsletter
Let's learn to become better developers.
Comments (5)
But can you style the fill color of the svg?
Yes, you can pass the fill color as class (if using Tailwind CSS): https://tailwindcss.com/docs/fill, or pass additional parameters for special attributes.
You can also use the inline_svg gem that does all this and more while keeping your images as svg file assets in your app. https://github.com/jamesmartin/inline_svg
Thanks for sharing, what's the benefit of keeping the images as SVG file assets? is it that they can be cached by the web server or CDN?
Yeah that's the reasoning the company I work at follows to use Cloudflare caching. We use the partials approach if we need to style the SVG conditionally. A nice use case is if you have personalized colors for a resource you can pass it through to the partial