Hanami Icons
Add any icon library to a Hanami app. Support for Lucide, Phosphor, Heroicons and others
Install
Add the gem:
bundle add hanami_icons
Install, choosing one of the supported libraries:
hanami generate icons --library=heroicons
Example
hanami generate icons --library=heroicons
# Or multiple at once
hanami generate icons --libraries=heroicons lucide
# Or only specific variants
hanami generate icons --library=heroicons --variants solid outline
This creates config/providers/icons.rb, registers the provider with the app container and adds the view helpers into app/views/helpers.rb.
Usage
# Uses the default library and variant defined in config/providers/icons.rb
icon "check"
# Use another variant
icon "check", variant: "solid"
# Set library explicitly
icon "check", library: "heroicons"
# Add CSS
icon "check", class: "text-green-500"
# Add data attributes
icon "check", data: { controller: "swap" }
# Set the stroke-width
icon "check", stroke_width: 2
# Base64-encoded data URI
encoded_icon "check"
The helpers return Hanami::View::HTML::SafeString, so they are safe to output in templates (<%== … %> or &= …).
Sprites
Hanami Icons supports SVG sprites for improved performance. Instead of inlining each icon’s full SVG, sprite icons reference a shared set of <symbol> definitions via <use href="…">.
Configuration
# config/providers/icons.rb
HanamiIcons.configure do |config|
config.default_library = "heroicons"
config.default_variant = "outline"
# Where `sprite_icon` references symbols. Set to nil to use inline mode (`<%== icons_sprite %>` in layout).
config.default_sprite_location = "/sprite.svg"
# Set to true to validate that referenced icons exist on disk
config.validate_sprite_icons = false
# Define which icons to include in the sprite
config.sprite = {
heroicons: {
outline: %w[check chevron-down menu search x],
mini: %w[check chevron-down]
}
}
end
External sprite
Generate a static sprite file and reference it with sprite_icon:
hanami generate icons:sprite
<%== sprite_icon "check" %>
<%# renders: <svg><use href="/sprite.svg#heroicons_outline_check"></use></svg> %>
Point at a precompiled file or a CDN by changing the location:
config.default_sprite_location = "https://cdn.example.com/sprite_icons.svg"
Override per icon:
<%== sprite_icon "check", sprite_location: "/assets/sprites.svg" %>
Inline sprite
Set the location to nil and embed the sprite directly in your layout:
config.default_sprite_location = nil
<body>
<%== icons_sprite %>
<%== sprite_icon "check" %>
<%== sprite_icon "search", class: "text-blue-500" %>
<%== sprite_icon "menu", data: { controller: "nav" } %>
</body>
You can also generate a sprite for a specific set of icons:
<%== icons_sprite ["check", "search"], library: "heroicons", variant: "outline" %>
Sync icons
To sync all libraries, run:
hanami generate icons:sync
To sync only a specific library, run:
hanami generate icons:sync --library=heroicons
# Or multiple at once:
hanami generate icons:sync --libraries=heroicons lucide
To sync only specific variants for a library:
hanami generate icons:sync --library=heroicons --variants solid outline
Custom icon libraries
Hanami Icons pulls SVGs straight from the path <icons_path>/<library_name>/<name>.svg. No generator is required for custom icons. Configuration is optional and only used to define defaults.
To add a custom library, create its directory and drop in your SVGs:
app/assets/svg/icons/simple_icons/apple.svg
(alternatively, scaffold it with hanami generate icons --library=simple_icons, which creates the directory and adds config.custom_library :simple_icons in the provider.)
Use them like any other library:
icon "apple", library: "simple_icons"
To add a git source for syncing, edit the provider:
HanamiIcons.configure do |config|
config.custom_library :my_icons, source: {
url: "https://github.com/user/icons.git",
variants: { default: "." }
}
end
Then sync:
hanami generate icons:sync --library=my_icons