Error: Unable to find the definition for Image (Next.js)

This new component in my next js project allows me to write a quote on an image and display it on the canvas. However, I am encountering an issue with the Image() function in JavaScript which typically runs on the browser. It seems that Next.js first executes the code on the server side before it reaches the browser, resulting in a ReferenceError: Image is not defined error.

"use client";
import { useState } from "react";
import User from "@/app/services/operations/user";
import { useRef } from "react";
import Head from "next/head";
import { useSelector } from "react-redux"; 
import ShineButton from "../button/button";

const Canvas = ({ tag,init,setinit }) => {
  
  if(tag.imageurl!=='')
    setinit(1)
  const { email } = useSelector((state) => state.User);
  const [imagename, setimagename] = useState("");
  const { uploadtocloud } = User();
  async function handleonsubmit(e) {
    e.preventDefault();
    const canvas = ref.current;
    let imageBlob = await new Promise((resolve) =>
      canvas.toBlob(resolve, "image/png")
    );
    uploadtocloud(imageBlob, imagename, email);
  }
  const ref = useRef();
  // setinit(1)
  const pixelRatio = typeof window!=='undefined'? window.devicePixelRatio : 1;
  const image = new Image();
  image.src = tag.imageurl ? tag.imageurl : "";
  image.addEventListener("load", () => {
    
    const canvas = ref.current;
    const context = canvas.getContext("2d");
    canvas.width = canvas.offsetWidth * pixelRatio;
    canvas.height = canvas.offsetHeight * pixelRatio;
    canvas.style.width = "900" + "px";
    canvas.style.height = "600" + "px";
    context.scale(pixelRatio, pixelRatio);
    context.font = "30px Arial";
    context.textAlign = "center";
    context.drawImage(image, 0, 0, 900, 600);

    var data = tag.quotedata[0]?.quote;
    var arr = data?.split(" ");
    var str = "";
    var farr = [];
    for (var i = 0; i < arr?.length; i++) {
      if (str?.length < 30) {
        str += arr[i];
        str += " ";
      } else {
        farr.push(str);
        str = arr[i];
        str += " ";
      }
    }
    farr.push(str);
    console.log("modified array is:", farr);
    let x = canvas.width / 2 - 200; // Center horizontally
    let y = canvas.height / 2 - 220;
    for (let i = 0; i < farr.length; i++) {
      context.fillText(farr[i], x, y);
      y += 50;
    }
  });
  image.setAttribute("crossorigin", "anonymous");
  const handleDownload = () => {
    const canvas = ref.current;
    const dataURL = canvas.toDataURL("image/jpeg");
    console.log("dataurl is:", dataURL);
    const link = document.createElement("a");
    link.href = dataURL;
    link.download = Date.now() + ".jpg";
    link.click();
  };

  return (
    <div>
      <canvas ref={ref} className={init===0?"dnone":"normal"} />;
      <div
        style={{
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
        }}
      >
        <div onClick={handleDownload} download={Date.now() + ".jpg"}  >
        <ShineButton value="Download"/&>
      </div>
      <form onSubmit={handleonsubmit} style={{display:"flex",flexDirection:"column" ,alignItems:"center"}}>
        <div style={{color:"white"}}>Upload To My Creations</div>
        <input
          type="text"
          onChange={(e) => setimagename(e.target.value)}
          value={imagename}
        />
       <ShineButton value="Upload"/>
      </form>
    </div>
  );
};
export default Canvas;

How can I resolve this situation?

Answer №1

It appears that you are utilizing the incorrect Image component, which is not supported on the server-side. You should consider using this one instead.

import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
    />
  )
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating HTML input elements dynamically using Javascript

<body> <form action="insertquestion.php" method="POST"> <script> function generateInputs(){ var prefix = "answer"; var number = 1; for(var i = 0; i < 5; i++){ ...

Typescript encountering onClick function error during the build process

My current challenge involves creating a submit function for a button in my application. However, when I attempt to build the project, I encounter a typing error that is perplexing me. Despite trying various methods, I am unable to decipher how to resolve ...

Ways to resolve the issue with the information window on Google Maps

I have a problem with displaying infowindows in Google Maps; currently, it only shows the information for the last marker added. let myLatlng = new window.google.maps.LatLng(-33.890542, 151.274856 ); let mapOptions = { zoom: 13, cent ...

What is the best method for storing a JavaScript widget with analytics - should it be done dynamically or statically?

My widget comes with a customizable boot loader that is used on websites. The boot loader file retrieves the settings for the widget and generates it accordingly. Normally, the content of the bootloader file remains static unless there are modifications ma ...

Tips for efficiently updating state within a loop using the settimeout function in a React application

As I work on my react app to visualize sorting algorithms, I've encountered an issue that has me stumped. I am currently iterating through all elements of the array stored in the 'bars' state and attempting to swap them for testing purposes. ...

Contrasting the impact of declaring a function inside document.ready versus outside of it

Is there a distinction between declaring a function within document.ready and outside of it? How does the location of defining a function impact when it can be called? For example, are there any considerations or discrepancies to keep in mind when placin ...

Connecting to a specific mui-tab with react-router-dom

How can I link to a specific tab in my material ui-based tabs setup within a React application? I want to be able to navigate directly to a particular tab when landing on the page, but I'm struggling with integrating this functionality. Is there a way ...

Vue.js is failing to re-render the component even after a change is made to

Utilizing Vue.js for my project. I am working with two object arrays, category and categoryPar. The category array contains names and parent names, while the categoryPar array only contains names. My goal is to display only the categories that belong to t ...

Encountering the following error message: "Received error: `../node_modules/electron/index.js:1:0 Module not found: Can't resolve 'fs'` while integrating next.js with electron template."

I am utilizing the electron template with next.js, and I am trying to import ipcRenderer in my pages/index.tsx file. Below is the crucial code snippet: ... import { ipcRenderer } from 'electron'; function Home() { useEffect(() => { ip ...

Is it acceptable to bring in the Router from 'next/router'?

In the documentation for Next.js, there are two ways to access the router object: useRouter for functional components and withRouter for class-based components. However, there is something I have encountered a few times which is accessing the Router objec ...

Looking to pass multiple props and run a function for each one? Here's how!

There is a scenario where I have two separate times in minutes format that need to be converted to 24-hour format without separators. I am currently using a function for this conversion and then using momentjs to transform it into the required format. Whil ...

Using Jquery Chosen Plugin to Dynamically Populate One Chosen Selection Based on Another

Good evening to all, please excuse any errors in my English. I have successfully integrated a jQuery Chosen plugin with my 'estado' field (or province). My goal is to populate another jQuery Chosen plugin with the cities corresponding to that s ...

Displaying gratitude message using AJAX and executing PHP script

I've created a form where I want the "thank you" message to be displayed after submission and also run a PHP script to insert data into the database. However, currently, although the values are being passed correctly via the URL, the upis.php script i ...

Send the user to a customized dashboard depending on their user role permissions using Vue.js

Currently, I am developing a system that involves handling multiple role-permissions for users. To provide some context, there are 3 distinct users in this scenario: User1 (customer), User2 (employee), and User3 (admin). For each of these user types, I ha ...

Pass information from an array of objects to a visual component

My objective is to display 3 instances of the SearchItem component from locations[0].results[0] and 3 instances from locations[0].results[1] I have an array containing objects with data that I want to display in my SearchItem component: const locations = ...

Is it possible to leverage both functions and variables within the ng-options expression in Angularjs?

I am faced with a situation where I have 2 select boxes. The first one is used to choose the user type (such as groups or individual), and the second one displays the options based on the selection made in the first box. I was wondering if it is possible t ...

Unable to transfer data from Laravel's Blade template to a Vue component

Need help passing a value from Laravel to Vue. I'm facing an issue where the props I receive are always showing as undefined in the console.log output. I've double-checked for camel case errors but can't seem to find the root cause of the pr ...

Preventing Bull Queue from automatically re-starting jobs upon server restart

Currently, I am utilizing the bull queue system for processing jobs. Imagine a scenario where a job is in progress with an active status and I restart my development server. Upon restarting the worker script, the job remains in the active state within the ...

Using jQuery to load and parse a JSON file stored on a local system

I am a beginner in scripting languages and recently searched for ways to load and parse JSON files using jQuery. I found helpful resources on Stack Overflow. The JSON file I am working with is called new.json. { "a": [ {"name":"avc"}, ...

How can you create an animation that plays forward on the first click and then reverses on the second

After coming across numerous similar questions, I realize that most of them refer to the outdated .toggle() function. My main challenge lies in achieving the desired effect where div#p moves right on the first click and then returns to its original positio ...