'how to load Svg components in remix run application
I have some Svg files which i want to load as react components in remix run app. for example in create-react-app your could do something like this
import { ReactComponent as Logo } from './logo.svg';
function App() {
return (
<div>
{/* Logo is an actual React component */}
<Logo />
</div>
);
}
is there any similar way in remix-run do achieve the same ?
Solution 1:[1]
Unfortunately there is no way currently to import an SVG file in your component file directly like in create react app.
And maintainers do not allow currently manipulating the esbuild config to add features like that via plugins (cf. the discussion in this merge request).
If you don't need to style your SVG, you could simply put it in the public/
folder and include it with an img
element in your component.
Smaller JS bundles, faster page hydration, and immutable .svg's over the network that are only ever downloaded once. (cf. this message)
function App() {
return (
<div>
<img src="/logo.svg" alt="My logo" />
</div>
);
}
You could also create yourself a JSX component and put your SVG code inside it (with some manual conversion for prop names), or even put your SVG file in a folder, and use an external automatic conversion tool like SVGR to generate optimized JSX component from it with a simple CLI command.
In that case you have a component that you can import like any other component:
import Logo from './Logo.svg';
function App() {
return (
<div>
<Logo />
</div>
);
}
Solution 2:[2]
For me, it only worked by creating a component with the SVG tag and then importing it
const HomeLogo = () => {
return (
<div>
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<g fill="none" fill-rule="evenodd">
<circle cx="24" cy="24" r="24" fill="#FFF"/>
<path fill="#0B0D17" d="M24 0c0 16-8 24-24 24 15.718.114 23.718 8.114 24 24 0-16 8-24 24-24-16 0-24-8-24-24z"/>
</g>
</svg>
</div>
)
}
export default HomeLogo
Solution 3:[3]
I created a workflow to convert the icons to react components in development using svgr
and npm-watch
. For good measure you will probably want to run the icons
script before building for production too.
Install dependencies:
npm install -D @svgr/cli @svgr/plugin-svgo @svgr/plugin-jsx @svgr/plugin-prettier npm-watch npm-run-all
Update package.json
scripts:
{
//...
"scripts": {
//...
// task to convert icons to components
"icons": "npx @svgr/cli --out-dir app/icons -- ./icons",
// watch task
"icons:watch": "npm-watch icons",
// compile once and start watching for changes
"dev:svg": "run-s icons icons:watch",
// remix dev
"dev:remix": "remix dev",
// run all dev: scripts including `dev:svg` (depending on the remix template you might neet to replace the default `dev` script)
"dev": "run-p dev:*"
},
// npm-watch configuration
"watch": {
"icons": {
"patterns": [
"icons"
],
"extensions": "svg",
"quiet": false
}
},
//...
}
The svg
icon files are located in the project root in icons/
and the react components are generated in the app/icons/
folder.
svgr.config.js
(optional)
module.exports = {
plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx", "@svgr/plugin-prettier"],
typescript: true, // optional
};
svgo.config.js
module.exports = {
plugins: [
{
name: "preset-default",
params: {
overrides: {
removeViewBox: false,
},
},
},
],
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Fabricio Cunha |
Solution 3 |