Home > front end >  Change colors for imported images in next.js
Change colors for imported images in next.js

Time:10-20

I've created a custom icon and imported it as SVG on my next.js app. I want to implement a feature where users can customize the color of this icon, like red to yellow or black, etc. But this is static image, is there a way I can achieve this?

enter image description here

CodePudding user response:

You can use the SVGR package(https://react-svgr.com/docs/next/) and convert the SVG to a React component. And then change the fill with either the fill attribute or style prop.

CodePudding user response:

There are a few possible ways to approach this:

  • Webpack via @svgr/webpack
  • Babel via babel-plugin-inline-react-svg
  • Next.js Image via Dangerously Allow SVG in next.config.js (Not a recommended approach)

First off, your SVG image needs to be fillable. How to do this is beyond the scope of the question, but there are many resources online to help you.

Applies to each approach below (not repeated for spacing saving)

In the file you want the SVG to show

import Star from './star.svg'

const Example = () => (
  <div>
    // set your color in fill and stroke is optional
    <Star height="100" width="100" fill="#6973ff" stroke="black" />
  </div>
)

Webpack (recommended choice)

I made a demo with this approach on Codesandbox

Snippet code pulled from react-svgr

  1. Install yarn add --dev @svgr/webpack
  2. In the next.config.js file add the following:
module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/i,
      issuer: /\.[jt]sx?$/,
      use: ['@svgr/webpack'],
    })

    return config
  },
}
  1. Review In the file you want the SVG to show code above

Babel

Snippet code pulled from plugin repo

  1. yarn add -D babel-plugin-inline-react-svg

  2. Add following to your .babelrc file:

{
  "plugins": [
    "inline-react-svg"
  ]
}
  1. Review In the file you want the SVG to show code above

Next.js Image (Not recommended)

Excerpt from Next.js as to why you shouldn't use this approach:

The default loader does not optimize SVG images for a few reasons. First, SVG is a vector format meaning it can be resized losslessly. Second, SVG has many of the same features as HTML/CSS, which can lead to vulnerabilities without proper Content Security Policy (CSP) headers.

Because of what was said from Next.js I won't be coding this example as it's redundant given the other approaches.

If you still want to follow this process you can view their documentation.

  • Related