typescriptsvgnext.js

svg change in next.js


I'm learning next.js and I'm faced with the task of changing svg while working

I tried via:

import Image from 'next/image'
import Svg from '../../public/Svg.svg'

<Image src={Svg}/>

but it didn't give any result, because I didn't find that it can be changed at all

and if it's even possible, you just need to shift the coordinates to the object with id=sun

<ellipse
  style="display:inline;fill:#febe22;fill-opacity:1;stroke-width:1.0889"
  id="sun"
  cx="696.67834"
  cy="374.86948"
  rx="150.91277"
  ry="152.97981" />

For the future, I want to know how to make this more readable, that is, not just paste the entire svg text into next.js, but take the basis from the file.


Solution

  • Enable SVGR support and restart server:

    // next.config.js
    const nextConfig = {
      webpack(config) {
        config.module.rules.push({
          test: /\.svg$/,
          issuer: /\.[jt]sx?$/,
          use: ['@svgr/webpack'],
        });
        return config;
      },
    };
    
    module.exports = nextConfig;
    

    Create a component for SVG

    // components/SunSvg.tsx
    import { forwardRef } from 'react';
    
    const SunSvg = forwardRef<SVGSVGElement>((_, ref) => (
      <svg
        ref={ref}
        viewBox="0 0 1000 1000"
        xmlns="http://www.w3.org/2000/svg"
      >
        <ellipse
          id="sun"
          cx="696.67834"
          cy="374.86948"
          rx="150.91277"
          ry="152.97981"
          style={{
            display: 'inline',
            fill: '#febe22',
            fillOpacity: 1,
            strokeWidth: 1.0889,
          }}
        />
      </svg>
    ));
    
    export default SunSvg;
    
    

    Modify the SVG:

    // app/page.tsx or pages/index.tsx (depending on Next.js setup)
    'use client';
    
    import { useRef, useEffect } from 'react';
    import SunSvg from '../components/SunSvg';
    
    export default function Page() {
      const svgRef = useRef<SVGSVGElement | null>(null);
    
      useEffect(() => {
        const sun = svgRef.current?.querySelector('#sun');
        if (sun) {
          sun.setAttribute('cx', '400'); // New x-coordinate
          sun.setAttribute('cy', '200'); // New y-coordinate
        }
      }, []);
    
      return (
        <main style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '2rem' }}>
          <h1>Move the Sun</h1>
          <SunSvg ref={svgRef} />
        </main>
      );
    }