-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support inlining SVG assets #1204
Comments
While this is in the process of getting fixed, here is my current patchy solution (leveraging webpack's svg-inline-loader 😅 ) Add
|
THANKS! you are awesome! |
For now, this does not support svg files in styles. |
Hi guys, I am experimenting with package vite-svg-loader to make our SVG icons inline. Although SVG icons have already inline HTML when server-side render, the browser still downloads SVG icons through network when rehydrate. Do you know any package like html-loader for Vite/Rollup ecosystem? |
How about something like this?
Will not work for the |
Custom SVG are now supported in You can find the documentation here: https://github.com/antfu/unplugin-icons#custom-icons |
I actually had to get the inlined svg to use in import svgToMiniDataURI from "mini-svg-data-uri";
import type { Plugin } from "rollup";
import fs from "fs";
import { optimize, OptimizeOptions } from "svgo";
type PluginOptions = { noOptimize?: boolean; svgo?: OptimizeOptions };
//TODO: remove this once https://github.com/vitejs/vite/pull/2909 gets merged
export const svgLoader: (options?: PluginOptions) => Plugin = (
options?: PluginOptions
) => {
// these options will always be overridden
const overrideOptions: PluginOptions = {
svgo: {
// set multipass to allow all optimizations
multipass: true,
// setting datauri to undefined will get pure svg
// since we want to encode with mini-svg-data-uri
datauri: undefined,
},
};
options = options ?? overrideOptions;
options.svgo = Object.assign(options.svgo ?? {}, overrideOptions.svgo);
return {
name: "vite-svg-patch-plugin",
transform: function (code, id) {
if (id.endsWith(".svg")) {
const extractedSvg = fs.readFileSync(id, "utf8");
const optimized = options.noOptimize
? extractedSvg
: optimize(extractedSvg, options.svgo).data;
const datauri = svgToMiniDataURI.toSrcset(optimized);
return `export default "${datauri}"`;
}
return code;
},
};
}; (makes using dynamic import such as in this gist really powerful) EDIT: added optional svgo optimizations |
How do you remove those assets from being emitted by Vite? |
Any updates on this? Currently, I have a few websites that load multiple SVG images, which make them load pretty slowly. |
There's a fairly dead PR open for it, I think it mainly just needs maintainer approval at this point |
Does |
Not nearly as cleanly as just adapting the |
I wrote a plugin to exclude files ending in .svg to prevent them from emitted.
Usage: |
In 2023, what is the recommended solution for this? Is this in scope for vite? |
For @nikeee and anyone coming after that, it seems you can append
Docs: https://vitejs.dev/guide/assets.html#explicit-url-imports |
@hugoatmooven i think the motivation for this issue is inlining in the sense of the SVG object that can be styled, etc etc, rather than a base64 string |
@hugoatmooven so inlining SVGs works now? If so, this issue could be closed, or am I getting something wrong? |
However the goal would be to have |
I upgraded to the latest version 4.3.0 but even with adding ?inline the respective SVG doesn't get inlined as an data URI in my (S)CSS. |
I think that is also available with
|
@hugoatmooven Well I'll be damned, I think this issue can (finally) be closed out, or perhaps left open as an FAQ/documentation issue? |
@madeleineostoja While the Also preferably this should just work out-of-the-box, like how inlining works for every(?) other format. |
Ah apologies I didn't notice the discussion regarding goals and motivation before. It'd be great to be able to embed the SVG element into HTML, but that feature feels more like a future expansion to me, rather than the solution to the current problem described in this issue. I feel this way because:
|
It seems this could be done by appending import MyLogo from 'path/to/svg?raw&inline';
{@html MyLogo} Or if you want to use it for a favicon or <link rel="icon" href="data:image/svg+xml;base64,{btoa(MyLogo)}" type="image/svg+xml" />
<img src="data:image/svg+xml;base64,{btoa(MyLogo)}" alt="" /> Here’s my code: sveltia/sveltia-cms@4dc8c63 All these files are bundled into one single JavaScript file |
Doing I think vite should not do magic and emit Also, this approach doesn't work for imports in CSS files (which is what I am using this for): .a {
background-image: url("./path/to/image.svg?inline");
/*
expected result:
background-image: url("data:image/svg+xml;base64,...");
actual result:
background-image: url("/path/to/image-hash.svg?inline");
*/
} This is currently broken, too. Probably the logic between the include implementations is shared. |
as a workaround for inlining SVGs in CSS files i'm now using the |
Thanks @oberhamsi for that suggestion! I'll use it now too! |
This is so great! Thank you for this. Out of the box support for PostCSS in Vite is amazing as well. So I added "postcss-inline-svg" as dev dependency, and then created a "postcss.config.cjs" config file ( I had to use .cjs extension) that references the plugin with the usual syntax, for example:
Then in CSS I load svgs like
When built, all the svg are automatically inlined and are not outputted to the dist. Finally! |
For automatic inlining in CSS, see my previous reply. For img src inlining, here is how I do:
then in the app, when you need to inline a svg in a img src load it with:
|
I was asked to open another issue for this.
Describe the bug
Vite doesn't inline svg files when the documentation says it would.
Reproduction
https://bitbucket.org/andylizi/test-vite-svg-inline/
Expected behavior
logo.svg
should be inlined, asassetsInlineLimit
claims to inline any static asset files under the default 4kb limit.vite/src/node/config.ts
Lines 315 to 320 in 9904cb1
Actual behavior
logo.svg
is not inlined.System Info
vite
version: v1.0.0-rc.13Related code
vite/src/node/build/buildPluginAsset.ts
Lines 60 to 63 in 480367b
Preferred solution
Adding support for svg inlining would be great.
Unfortunately extra steps are required to do it properly, as #1197 mentioned: Probably Don’t Base64 SVG and Optimizing SVGs in data URIs.
Alternative solution
Document this behavior in
config.ts
so users wouldn't be surprised by this.Workaround
Rename
.svg
to uppercase.SVG
. This isn't ideal but it works for now.The text was updated successfully, but these errors were encountered: