Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference image in React Component NPM module?

I have made a date picker in react and I am trying to upload it to NPM, and it uses an external svg, but I am having trouble correctly referencing that svg.

So my file directory looks like this:

+-- imgs
|   +-- arrow.svg
+-- src
|   +-- Datepicker.jsx
|   +-- index.js

Then in Datepicker.jsx I have
<object style={STYLES.arrow} data="../imgs/arrow.svg" type="image/svg+xml" />

But then when I install it through npm and try to use it in a project, it says:
GET http://localhost:8000/imgs/arrow.svg 404 (Not Found)

It looks like it is looking for the imgs directory in the root of the project instead of in the module itself, but I'm not sure how to fix this.

like image 881
Alex Avatar asked Jan 09 '16 02:01

Alex


2 Answers

I would probably use webpack to simply require the data before it compiles:

const data = require('../imgs/arrow.svg');

<object style={STYLES.arrow} data={data} type="image/svg+xml" />

You will need to do npm install --save-dev webpack url-loader or something similar. The webpack docs should let you know what you need (linked above).

Your problem is that it's trying to find the data path at runtime, when what works better is for it find the data path at compile time.

like image 77
Josh Beam Avatar answered Oct 25 '22 11:10

Josh Beam


The accepted answer really helped me out here, just wanted to show how I got it to work for me. I have a few React projects that need to share a component, so I've built that component in its own standalone library. Originally, I had been referencing some images in the library via the "typical" src method where those static files are being grabbed from a public directory, such as <img src='icons/down-arrow.svg' /> but, as the OP noted, that doesn't work when the library is imported into the parent project because the parent project will end up looking for the icons based on its own root, not that of the library.

Importing those icons and setting those imports as the src attribute did the trick -

// src/components/component.js
import React from 'react';
import downArrow from '../../../public/icons/down-arrow.svg';
import rightArrow from '../../../public/icons/right-arrow.svg';

const MyComponent = (props) => {
    const icon = props.selected ? downArrow : rightArrow;

    return (
        <div>
            <img src={icon} />
        </div>
    );
};

export default MyComponent;

In this case, the component would be at /src/components/component.js and one of the icons would be at /public/icons/down-arrow.svg

Alternately, you could alias the public directory in your Webpack config like so

// ...
    resolve: {
        alias: {
            public: path.resolve(__dirname, 'public/')
        }
    },
// ...

And remove the leading ../s from your import paths.

like image 26
skwidbreth Avatar answered Oct 25 '22 11:10

skwidbreth