DEV Community

Alireza Razinejad
Alireza Razinejad

Posted on

Building Custom SVG Icons with Color Replacement in Next.js

In this tutorial, we will explore how to create a custom SVG icon component in Next.js that allows us to dynamically replace the fill color of the SVG using a provided color value. We will leverage the Next.js framework, React, and basic SVG manipulation techniques to achieve this functionality.

Prerequisites

Before we begin, make sure you have the following prerequisites:

  • Basic understanding of Next.js, React, and JavaScript.
  • Familiarity with SVG syntax and concepts.

Step 1: Setting up the Project

  1. Create a new Next.js project by running the following command:
   npx create-next-app icon-color-replacement
Enter fullscreen mode Exit fullscreen mode
  1. Navigate into the project directory:
   cd icon-color-replacement
Enter fullscreen mode Exit fullscreen mode
  1. Install and enable the svg-inline-loader package, which will help us load and manipulate SVGs:
   npm install svg-inline-loader --save-dev
Enter fullscreen mode Exit fullscreen mode
  1. Update next.config.js to have the following webpack config changes:
   const nextConfig = {
       webpack: (config) => {
           config.module.rules.push({
               test: /\.svg$/,
               loader: 'svg-inline-loader'
           });
           return config;
       }
   }

   module.exports = nextConfig;
Enter fullscreen mode Exit fullscreen mode
  1. Create a new file named icons.type.ts inside the ./components directory and define the IconsType type to hold the available icon names.

  2. Similarly, create another file named colors.type.ts inside the ./styles directory and define the ColorsType type to hold the available color values.

Step 2: Building the Icon Component

  1. Create a new file named Icon.tsx inside the ./components directory.

  2. Import the required dependencies:

   import React, { useEffect, useRef } from 'react';
   import { IconsType } from './icons.type';
   import { ColorsType } from '@/styles/colors.type';
Enter fullscreen mode Exit fullscreen mode
  1. Define the IconProps interface which extends React.SVGAttributes<HTMLOrSVGElement> and includes additional properties like name, width, height, and an optional color:
   interface IconProps extends React.SVGAttributes<HTMLOrSVGElement> {
       name: IconsType;
       width: number;
       height: number;
       color?: ColorsType;
   }
Enter fullscreen mode Exit fullscreen mode
  1. Create the replaceColor function that takes the SVG string and the new color as arguments. This function replaces the fill attribute with the provided color value using regex:
   const replaceColor = (svgString: string, newColor: string) => {
       const regex = /fill="#[A-Fa-f0-9]{6}"/g;
       const replacement = `fill="var(${newColor})"`;
       return svgString.replace(regex, replacement);
   };
Enter fullscreen mode Exit fullscreen mode
  1. Export the Icon functional component. Inside the component, define a useRef hook to access the SVG element, and a useEffect hook to fetch the SVG and handle the color replacement logic:
   export const Icon: React.FC<IconProps> = ({ name, width, height, color = '--c-oxford-blue-500', ...props }) => {
       const svgRef = useRef<SVGSVGElement>(null);

       useEffect(() => {
           const svgElement = async () => await import(`../../../public/icons/${name}.svg`);

           svgElement().catch(e => {
               console.error('<strong

>On loading the SVG</strong>', e);
           });

           svgElement().then(svg => {
               svgRef!.current!.innerHTML = replaceColor(svg.default, color);
           });

       }, [name, color]);

       return <svg width={width} height={height} ref={svgRef} {...props}></svg>;
   };
Enter fullscreen mode Exit fullscreen mode

Step 3: Using the Icon Component

  1. Open the pages/index.tsx file.

  2. Import the Icon component:

   import { Icon } from '@/components/Icon';
Enter fullscreen mode Exit fullscreen mode
  1. Use the Icon component in your JSX code, providing the required props like name, width, and height, as well as an optional color prop:
   const HomePage: React.FC = () => {
       return (
           <div>
               <h1>Icon Color Replacement Example</h1>
               <Icon name="example-icon" width={24} height={24} color="--c-crimson-red-500" />
           </div>
       );
   };
Enter fullscreen mode Exit fullscreen mode

Congratulations! You have successfully created a custom SVG icon component in Next.js that allows you to replace the fill color dynamically. You can now customize the color of your SVG icons by passing different color values to the color prop of the Icon component.

Remember to import the necessary dependencies and define the required types before using the code in your Next.js project.

That's it! Have fun exploring and customizing your SVG icons with ease!

Top comments (0)