Skip to content
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

Importing an svg file from JS does not return a resolved URL string #15208

Closed
7 tasks done
Alixhan opened this issue Dec 1, 2023 · 14 comments
Closed
7 tasks done

Importing an svg file from JS does not return a resolved URL string #15208

Alixhan opened this issue Dec 1, 2023 · 14 comments

Comments

@Alixhan
Copy link

Alixhan commented Dec 1, 2023

Describe the bug

Importing an svg file from JS does not return a resolved URL string

import Sun from '@/assets/icon/sun.svg'

actually:
return data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?.....

expect:
return resolved URL string like /src/assets/icon/sun.svg

In vite4 works fine, this problem occurs in vite5

Reproduction

no

Steps to reproduce

No response

System Info

windows11 
Microsoft Edge 版本 119.0.2151.93 (正式版本) (64 位) 
[email protected] 
[email protected]
[email protected]

Used Package Manager

pnpm

Logs

No response

Validations

@ArnaudBarre
Copy link
Member

This works as expected and is more a fix of Vite 5 where before SVG where not inlined. This can happen for small images too. See https://vitejs.dev/config/build-options.html#build-assetsinlinelimit to configure this globaly.
Having ?url to opt-out in a case by case bases is something I would be in favor @bluwy (surprisingly I didn't find an open feature request for it).

@ArnaudBarre ArnaudBarre closed this as not planned Won't fix, can't repro, duplicate, stale Dec 1, 2023
@bluwy
Copy link
Member

bluwy commented Dec 2, 2023

I think we talked about an ?inline query to opt-in or out of it. Technically the data:image string is already a URL, but more specifically a data url.

@Alixhan
Copy link
Author

Alixhan commented Dec 2, 2023

This works as expected and is more a fix of Vite 5 where before SVG where not inlined. This can happen for small images too. See https://vitejs.dev/config/build-options.html#build-assetsinlinelimit to configure this globaly. Having ?url to opt-out in a case by case bases is something I would be in favor @bluwy (surprisingly I didn't find an open feature request for it).

Thank you, I need to get the raw string of the svg file through the url and use this to dynamically change the color of the svg icon,I want to exclude svg files, but I don't know how to do.

@ArnaudBarre
Copy link
Member

@bluwy yeah you're right this would be confusing, so maybe a ?no-inline one?

(Yeah I did only bring up the other way around but I think both cases can be added without too much effort and can allow people to choose on a case by case bases, depending on if the asset change often and where its display on the page)

@Alixhan not sure to understand your use-case, the data URL you get have all the same functionality as the previous one when used in an image tag.

@bluwy
Copy link
Member

bluwy commented Dec 4, 2023

I was thinking ?inline and ?inline=false, but I haven't really thought deep about it.

@ArnaudBarre
Copy link
Member

No opinion, let's discuss this in a PR! Do you plan to work on it after your current one? If no I can work on it!

@bluwy
Copy link
Member

bluwy commented Dec 4, 2023

Yeah feel free to work on it, greatly appreciated 😄 I'll circle back on my existing "stepping-stone" PR and clean it up today

@freakzlike
Copy link

It seems to be an issue in the latest Chrome version (120.0.6099.71) together with <svg> and <use>.

This is working

<svg viewBox="0 0 24 24">
   <use xlink:href="/assets/UserIcon-b1492dc3.svg#icon"></use>
</svg>

This not

<svg viewBox="0 0 24 24">
  <use xlink:href="data:image/svg+xml,..."></use>
</svg>

As far as I remember there were some issues with data:image/svg in Safari too.
I've reverted back to Vite 4 as quick fix.

@ArnaudBarre
Copy link
Member

ArnaudBarre commented Dec 8, 2023

This is strange because SVG with fragments should not be inlined, can you create an issu with a stackblitz repro?

@rktyt
Copy link

rktyt commented Dec 11, 2023

It seems to depend on where you write the fragments.
https://stackblitz.com/edit/vitejs-vite-ym4btp?file=main.js

It seems that only the following formats are expanded as URLs.

new URL('./path/to/file.svg#id', import.meta.url)

If you are not using Typescript, the following format seems to be fine.

import imageUrl from './path/to/file.svg?url#id'
// or
import imageUrl from './path/to/file.svg#id'

But in this case it doesn't work on dev server.


NOTE:
The following format does not work as intended.

import image from './path/to/file.svg'
const imageUrl = new URL(`${image}#id`, import.meta.url) 

@freakzlike
Copy link

freakzlike commented Dec 11, 2023

In general my project looks like this:

https://stackblitz.com/edit/vitejs-vite-s2alea?file=main.js

It's either working with npm run dev or npm run build && npm run preview but not both.

import logo from './javascript.svg';
import logoWithHash from './javascript.svg#icon';

export const Icons = {
  // is working in dev, but not build
  append: `${logo}#icon`,
  // is working in build, but not dev
  hash: logoWithHash,
};

With Vite v4 the first logo with append was working in both cases.

@rktyt
Copy link

rktyt commented Dec 11, 2023

If an SVG URL is required in v5, it is practically impossible to use the import syntax, and it seems necessary to avoid using it.

So you need to do as follows.

export const Icons = {
  javascript: new URL('./javascript.svg#icon', import.meta.url).toString(), 
};

Please note that if there is no hash property, it will become a data uri depending on the size.


I don't know if this is by design or a bug.
This issue is closed as "not planned", so it's probably by design.
It's not explicitly stated in the documentation, so I couldn't figure it out without looking into it, but I personally don't have any problems with this so I won't dig into it any further.

@freakzlike
Copy link

I've added your case in my repro and it's working in both cases. Maybe a vite member can confirm this is the way to go or if import is still an option

@ArnaudBarre
Copy link
Member

I will look at some point into these edge cases, but in order to have more workaround available I've open a PR for better controlling the beaviour for this: #15366

@github-actions github-actions bot locked and limited conversation to collaborators Dec 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants