The function of this simple app is to indicate the object’s location in the image whenever the user clicks any of the labeled buttons. To begin with, first, I created a simple design layout. (Bootstrap 5 was installed). const ImageDetector = () =>{ return( <> <div className="row container"> <p className="text-center"><strong>SIMPLE IMAGE LABELING</strong></p> <div className="row mt-2 mb-3"> <div className="col-4"> {/*buttons here*/} </div> <div className="col-8"> <img id="image" src={`/img/foods.jpg`} alt="photo" className="w-100" /> </div> </div> </div> </> ) } export default ImageDetector; I declared a variable containing an array of objects. const objects = [ { "object": "juice", "x":1, "y":1, "w":230, "h":250 }, { "object": "oranges", "x":200, "y":230, "w":320, "h":230 }, { "object": "bread", "x":600, "y":280, "w":250, "h":250 }, ]; After declaration, I fetched the values from that variable, objects, and converted them into buttons. <div className="col-4"> {objects.map(item=>( <button className={"btn btn-secondary col-12 my-2"} key={item.object} > {item.object} </button> ))} </div> To display the square or rectangle shape, I declared width and height variables to get the natural width and height of the image. const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); useEffect(()=>{ const image = document.querySelector<HTMLImageElement>('#image'); if(image !== null){ let linkSource = image.src; const imageCopy = document.createElement("img"); imageCopy.src = linkSource; setWidth(imageCopy.width); setHeight(imageCopy.height); } },[]); Then, I inserted <svg/> below the <img/> and put them inside a <div/> then made its position relative. I defined the css style of the <svg/> to overlay the <img/>. The preserveAspectRatio and viewBox in <svg/> will help retain the x and y positions of rect and text elements even when the screen size changes. <div className="col-8"> <div style={{"position":"relative"}}> <img id="image" src={`/img/foods.jpg`} alt="photo" className="w-100" /> <svg preserveAspectRatio="none" className="image-map" viewBox={`0,0,${width},${height}`} <rect className="selected-object" rect> <rect className="wrap-text" ></rect> <text className="object-name"> </text> </svg> </div> </div> <style jsx> {` .image-map { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .selected-object{ position: absolute; top: 0; left: 0; } `} </style> I inserted variables to set values of the x,y,w,h in svg’s rect and text elements. const [xPosition, setXPosition] = useState(0); const [yPosition, setYPosition] = useState(0); const [objWidth, setObjWidth] = useState(0); const [objHeight, setObjHeight] = useState(0); const [selectedItem, setSelectedItem] = useState(""); Created handleClick() so when the user clicks a button the rect svg will appear. const handleClick = ( object:string ) =>{ objects.map(item =>{ if(item.object === object){ setXPosition(item.x); setYPosition(item.y); setObjWidth(item.w); setObjHeight(item.h); setSelectedItem(object.toUpperCase()); } }); } <div className="col-4"> {objects.map(item=>( <button className={"btn btn-secondary col-12 my-2"} key={item.object} onClick={() => handleClick(item.object)} > {item.object} </button> ))} </div> Then I set the values of rect and text elements and edited my style css. <rect className="selected-object" x={xPosition} y={yPosition} width={objWidth} height={objHeight}></rect> <rect className="wrap-text" x={xPosition} y={yPosition} width={objWidth} height="20"></rect> <text className="object-name" x={xPosition} y={yPosition+15}>{selectedItem}</text> <style jsx> {` .image-map { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .selected-object{ position: absolute; top: 0; left: 0; fill: transparent; stroke: #ff9e0d; stroke-width: 5px; } .wrap-text{ fill: #ff9e0d; } .object-name{ z-index:999; } `} </style> And it’s done. You can now run your simple app.