Open jamesst20 opened 2 weeks ago
module ViteInlineSvgFileLoader
class << self
def named(filename)
vite = ViteRuby.instance
vite_asset_path = vite.manifest.path_for(filename)
if vite.dev_server_running?
fetch_from_dev_server(vite_asset_path)
else
Rails.public_path.join(vite_asset_path.sub(%r{^/}, "")).read
end
end
private
def fetch_from_dev_server(path)
config = ViteRuby.config
dev_server_uri = URI("#{config.protocol}://#{config.host_with_port}#{path}")
response = Net::HTTP.get_response(dev_server_uri)
raise "Failed to load inline SVG from #{dev_server_uri}" unless response.is_a?(Net::HTTPSuccess)
response.body
end
end
end
InlineSvg.configure do |config|
config.asset_file = ViteInlineSvgFileLoader
end
Source: https://mattbrictson.com/blog/inline-svg-with-vite-rails
Thanks for the suggestion. Given the small amount of code required to build a Vite loader (as you demonstrated), and Vite's relatively small following, I'm not sure if it's worth building support directly into the gem.
Will leave this open so other Vite enthusiasts can upvote this idea.
Thanks for sharing your code, @jamesst20! I was able to get it working in my app without much fuss.
The only hiccup I had was related to the filenames provided to inline_svg
. Previously, code like <%= inline_svg("foo.svg") %>
would know to look in app/assets/images/
. These filenames stopped working after the switch to Vite Ruby, which makes sense–the images now live in app/frontend/images
.
I had to update the filenames to match the asset manifest entries instead. So, given a manifest entry like:
// public/vite-dev/.vite/manifest-assets.json
{
"images/foo.svg": {
"file": "assets/foo-yC27NFda.svg",
"src": "images/foo.svg",
"integrity": "sha384-[sha]"
},
// ...
}
...I would now have to use the following value to reference the image:
- <%= inline_svg("foo.svg") %>
+ <%= inline_svg("images/foo.svg") %>
Not a huge change, but definitely a difference. I suspect that I could have dug a bit further and added some Vite configuration to avoid the change, but the impact was small enough for my current concerns that it was faster to just update the filenames.
Thanks for sharing your code, @jamesst20! I was able to get it working in my app without much fuss.
The only hiccup I had was related to the filenames provided to
inline_svg
. Previously, code like<%= inline_svg("foo.svg") %>
would know to look inapp/assets/images/
. These filenames stopped working after the switch to Vite Ruby, which makes sense–the images now live inapp/frontend/images
.I had to update the filenames to match the asset manifest entries instead. So, given a manifest entry like:
// public/vite-dev/.vite/manifest-assets.json { "images/foo.svg": { "file": "assets/foo-yC27NFda.svg", "src": "images/foo.svg", "integrity": "sha384-[sha]" }, // ... }
...I would now have to use the following value to reference the image:
- <%= inline_svg("foo.svg") %> + <%= inline_svg("images/foo.svg") %>
Not a huge change, but definitely a difference. I suspect that I could have dug a bit further and added some Vite configuration to avoid the change, but the impact was small enough for my current concerns that it was faster to just update the filenames.
My pleasure! The path change is indeed something that comes with Vite. All view helpers requires the folder name in the path. This is indeed a difference from shakapacker or sprockets.
This is also true for all these methods
image_tag -> vite_image_tag("images/...")
asset_path -> vite_asset_path("images/...")
It would be nice to support Vite: https://github.com/ElMassimo/vite_ruby