I am using dangerouslySetInnerHTML to render a script but I'm getting Hydration errors

592 Views Asked by At

I am using dangerouslySetInnerHTML as a last resort as I cannot get my script to work. It needs to be in this format in order for the plugin to appear on the frontend, otherwise the console says that ImageMapPro is undefined.

ImageMap.jsx

'use client'
import { useEffect, useState } from "react";

export default function ImageMapPro() {
  const [render, setRender] = useState(false);
  const script = `
  <div id="image-map-pro"></div>
  <script src="image-map-pro/image-map-pro.min.js"></script>
  <script>ImageMapPro.init('#image-map-pro', {"id":"5256f3ec-3b42-4614-bd33-7332a713cac7","artboards":[{"children":[{"id":"27b1e6ba-0de4-49a0-a732-0d6824f84d17","title":"Ellipse","type":"oval","x":9.433962264150944,"y":32.239583333333336,"width":50.35377358490566,"height":54.583333333333336,"default_style":{"background_color":"#ff0000"},"x_image_background":9.433962264150944,"y_image_background":32.239583333333336},{"id":"1e6ab53b-a4c2-4a2f-a2fd-6fa8df37c642","title":"Rect","type":"rect","x":22.995283018867923,"y":18.90625,"width":61.910377358490564,"height":55,"tooltip_content":[{"type":"Heading","text":"test","heading":"h3","other":{"id":"","classes":"","css":""},"style":{"fontFamily":"sans-serif","fontSize":20.8,"lineHeight":"normal","color":"#ffffff","textAlign":"left"},"boxModel":{"width":"auto","height":"auto","margin":{"top":0,"bottom":0,"left":0,"right":0},"padding":{"top":10,"bottom":10,"left":10,"right":10}},"id":"ffbed5ee-255b-41a6-8229-c3f6f693497b"}],"x_image_background":22.995283018867923,"y_image_background":18.90625}]}],"version":"6.0.8","general":{"name":"Untitled"}})</script>
  `
  useEffect(() => {
    setRender(true);
  }, []);

  return (
    <div dangerouslySetInnerHTML={{ __html: script }}></div>
  );
}

page.jsx

 return (
        <>
            <ImageMapPro />
        </>
     );

The plugin shows for a second just how I want it, and then there is hydration errors in the console :

app-index.js:31 Warning: Prop `dangerouslySetInnerHTML` did not match. Server: "\n  <div id=\"image-map-pro\" data-image-map-id=\"5256f3ec...
1

There are 1 best solutions below

0
Jimmy On

I got it to work using this method

'use client'
import React, { useEffect, useRef } from "react";

export default function ImageMapPro() {
  const containerRef = useRef(null);

  useEffect(() => {
    // Dynamically load the ImageMapPro library
    const script = document.createElement("script");
    script.src = "image-map-pro/image-map-pro.min.js";
    script.async = true;
    script.onload = () => {
      // Initialize ImageMapPro when the script is loaded
      window.ImageMapPro.init(containerRef.current, {
        id: "5256f3ec-3b42-4614-bd33-7332a713cac7",
        artboards: [
          {
            children: [
              {
                id: "27b1e6ba-0de4-49a0-a732-0d6824f84d17",
                title: "Ellipse",
                type: "oval",
                x: 9.433962264150944,
                y: 32.239583333333336,
                width: 50.35377358490566,
                height: 54.583333333333336,
                default_style: {
                  background_color: "#ff0000",
                },
                x_image_background: 9.433962264150944,
                y_image_background: 32.239583333333336,
              },
              {
                id: "1e6ab53b-a4c2-4a2f-a2fd-6fa8df37c642",
                title: "Rect",
                type: "rect",
                x: 22.995283018867923,
                y: 18.90625,
                width: 61.910377358490564,
                height: 55,
                tooltip_content: [
                  {
                    type: "Heading",
                    text: "test",
                    heading: "h3",
                    other: {
                      id: "",
                      classes: "",
                      css: "",
                    },
                    style: {
                      fontFamily: "sans-serif",
                      fontSize: 20.8,
                      lineHeight: "normal",
                      color: "#ffffff",
                      textAlign: "left",
                    },
                    boxModel: {
                      width: "auto",
                      height: "auto",
                      margin: {
                        top: 0,
                        bottom: 0,
                        left: 0,
                        right: 0,
                      },
                      padding: {
                        top: 10,
                        bottom: 10,
                        left: 10,
                        right: 10,
                      },
                    },
                    id: "ffbed5ee-255b-41a6-8229-c3f6f693497b",
                  },
                ],
                x_image_background: 22.995283018867923,
                y_image_background: 18.90625,
              },
            ],
          },
        ],
        version: "6.0.8",
        general: {
          name: "Untitled",
        },
      });
    };

    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, []);

  return <div ref={containerRef}></div>;
}