react-svg icon indicating copy to clipboard operation
react-svg copied to clipboard

react-svg ssr compatibility with nextJs v14 App router

Open darktell opened this issue 1 year ago • 1 comments

It doesn't work as server component in new nextJs App Router. Only with "use client" I wrote simple component, and get error image

without turbo get this error

image

const Icon: FC<Props> = ({
  icon,
  svgClassName,
  alt,
  size = 20,
  width,
  height,
  role,
}) => {
  const src = `/images/icons/${icon}.svg`;

  const iconWidth = width ?? size;
  const iconHeight = height ?? size;

  return (
    <>
      <ReactSVG
        role={role || "presentation"}
        src={src}
        width={iconWidth}
        height={iconHeight}
        className={svgClassName}
        // evalScripts="always"
        fallback={() => <span>!</span>}
        title={alt || "icon"}
      />
    </>
  );
};

export default Icon;

honestly I think it can't be a server component because SVGInjector use document.. But just wanna get some thoughts about that

darktell avatar Apr 26 '24 10:04 darktell

I ran into this issue as well, but there's an easy work around for it. Just create a custom React Component that can use client and then you can call it even from SSG style components.

Server side component: RTEUtils.js

import DynamicSVG from "~/components/DynamicSVG/index.js";

export const processRTEVariables = (children) => {
        // ... yada yada yada
        return (
                <>
                    <DynamicSVG iconUrl={iconUrl} linkText={linkText} height='22px' />
                </>
        );
};

Client side component: DynamicSVG.js

'use client';

import React from 'react';
import { ReactSVG } from 'react-svg';

const DynamicSVG = ({ iconUrl = '', linkText = '', height = '', width = '' }) => (
    <>
        <ReactSVG
            src={iconUrl}
            wrapper='span'
            className='text-white'
            title={linkText}
            beforeInjection={(svg) => {
                svg.classList.add('pt-1');
                svg.setAttribute('style', `height: ${height}; width: ${width};`);
            }} /> {linkText}
    </>
);
export default DynamicSVG;

Works great!

Image

Psykoral avatar Apr 02 '25 19:04 Psykoral

You're right @darktell - this example is more like ssr compatibility rather than true ssr, since the lib loads the SVG on the client.

Thanks for the example @Psykoral 👍

Anyway, I've updated the example to use next latest, so will close the issue now.

tanem avatar Aug 17 '25 19:08 tanem