ueeieiie
ueeieiie

Reputation: 1562

How do you fetch an svg file and use it as <svg>?

My Question:

How do I fetch a .svg file and use it with <svg> tag, so I could also interactively style it (on hover for example), and not like I did in my example with <img> tag?

Goal:

Create a thumbnail view that shows the flag of each country (149 in number) on my main route '/'

Problem:

I've set a static route in my Express code, so all the flags to be available.

server.js:

app.use('/flags', express.static(FLAGS_FILES));
app.get('/flags', async (req, res) => {
    let myFlags;

    await readdir('data/flag-icons/')
        .then((flags) => myFlags = flags)
        .catch(err => console.log('Error:', err))

    res.json(myFlags)
});

On the client-side, I want to fetch each .svg file and inline it into my Component.

My React Component look like this:

MapThumbnail Component:

render(){
        const {flagcode} = this.props;
        const filepath = `/flags/${mapcode}/vector.svg`;

        console.log('filepath:', filepath);
        return (
            <MapThumbnailStyle>
                <img src={filepath} 
                     alt={flagcode} 
                     title={flagcode} 
                     width='40px' 
                     height='40px' 
                />
            </MapThumbnailStyle>
        );
    }

Upvotes: 3

Views: 7110

Answers (3)

Akhil Ramani
Akhil Ramani

Reputation: 465

Best way is Lazy load the SVG component

const SvgComponent = React.lazy(() => import('../filepath.svg'))

return (
  <React.Suspense fallback={<p>Loading...</P>}>
    <SvgComponent />
  </React.Suspense>
)

And this solution also works in React Native along with react-native-svg-transformer module.

Upvotes: 0

Boopathi Rajaa
Boopathi Rajaa

Reputation: 4729

You can in most of the cases directly inline the contents of the SVG file inside the render function, like -

TL;DR

react-svg-loader

It provides a webpack-loader, a CLI, and a few other tools that convert an SVG file to a React Component which contains the SVG file's contents inline in the render method.

The gist of the idea is the following -

vector.svg

<svg>
  <circle cx="50" cy="50" r="25" stroke-width="5" />
</svg>

Vector.js

Now create a vector.js and just copy the contents of the SVG like below

import React from "react"
export default () => (
  <svg>
    <circle cx="50" cy="50" r="25" stroke-width="5" />
  </svg>
);

and you can hand edit some elements here or assign ids to animate them.

MapThumbnail Component

And in your MapThumbnail component, you can import it as JS and style the SVG the way you want -

import Vector from "./path/to/vector";

// ...
// ...

render() {
  return <div>
    <Vector />
  </div>
}

This conversion of SVG to a React Component can be automated to some levels and is provided by a few tools - one such tool is react-svg-loader. Disclaimer - I'm the author of react-svg-loader.

Upvotes: 0

timotgl
timotgl

Reputation: 2925

https://github.com/gilbarbara/react-inlinesvg looks like it would help you.

Upvotes: 3

Related Questions