4

I've created a simple app with create-react-app. This configures webpack loaders for svg files to copy the files and put a public file into the constant. So the following code

import mysvg from "./img/my.svg";
console.log(mysvg)

prints /static/media/my.svg. That's fine.

But when editing/running the same project in codesandbox it tries to read the svg file (e.g. printing errors about ReactComponent if it's not a proper svg), and makes the handling different. Obviously, I could use the "public" folder instead, but I'd like to use the hash feature of production builds etc.

So my question is, how can I allow to use the same mechanism to get a resolving url path (e.g. valid for img src) in codesandbox and use the default create-react-app configuration?

Christian
  • 13,285
  • 2
  • 32
  • 49
  • The sandbox URL is returning 404. Could you post a new one? – Jackyef Apr 13 '20 at 16:30
  • Oh, sorry, recovered it. – Christian Apr 13 '20 at 17:49
  • Note, you can download the sandbox, run npm install && npm start and see it will print ```Path of svg: /static/media/my.080ef5f5.svg``` which actually is downloadable in webpack or production build (while ```/src/img/my.svg``` is not in codesandbox) – Christian Apr 13 '20 at 18:59

3 Answers3

1

I did some digging, and I think this is definitely a bug with codesandbox.

When we use a .png image, the string path looks like this:

path: https://uploads.codesandbox.io/uploads/user/ff71cfab-643a-41c7-8358-d13e8ce686c9/U6zD-unsplash1.png

But when we use an SVG, things fail.

Some similar issues opened on their github repo: #1664, #3825.

The maintainer said that svg-react-loader is included in CRA v2 template, and you can import them as ReactComponent, I assume this is what you were talking about initially. I think this is what caused svg files to be treated differently by codesandbox.

For now, I guess you can do this hacky workaround:

import mysvg from "!raw-loader!./img/my.svg.txt";

// inside render
<span dangerouslySetInnerHTML={{ __html: mysvg }} />

sandbox here

You would need to add raw-loader as dependency and rename the file to .txt extension so that it doesn't get handled like an .svg.

Long term, I think the best we could do is to participate in #3825 and hope that this can get fixed by codesandbox.

Jackyef
  • 4,734
  • 18
  • 26
  • Sure, where the "default" comes from is clear. Unfortunately one cannot use the path starting with /src/ as opposed to the one generated in the standalone app (/static/media/...), which really resolves to the file content. – Christian Apr 13 '20 at 18:36
  • I've updated the question and sandbox to sort out the require vs. import stuff. – Christian Apr 13 '20 at 18:57
  • @Christian Ah, forgive me for misunderstanding. I have updated my answer, but you are probably not going to like it... – Jackyef Apr 14 '20 at 03:17
  • Thanks for digging into it. The loader syntax is not supported with create-react-app setup (fails with an explicit message that it's not supported). Also, it does load the svg into the bundle, which I want to avoid. Seems I need to wait for a fix for #3825. – Christian Apr 14 '20 at 10:14
  • Weird, I could get a working sandbox with loader [here](https://codesandbox.io/s/brave-shadow-e4j30). – Jackyef Apr 14 '20 at 10:20
  • Yes, in codesandbox it works. But not in the standalone version (download zip and run npm install && npm start). – Christian Apr 14 '20 at 15:17
  • 1
    Even though the answer did not help me, I award the bounty for finding #3825 before their support team did :) – Christian Apr 15 '20 at 17:23
1

Answer from the codesandbox team: it is a known issue tracked on their github repository.

Christian
  • 13,285
  • 2
  • 32
  • 49
0

If you're want to use svg images,only importing them as React Components, like this,import {ReactComponent as MySvg} from './img/my.svg' usually always works. There are other ways as well but I think this one is simplest. Check out my solution - myVersionOfCodesandbox

Thet Aung
  • 485
  • 5
  • 11