I found a solution to my own problem, it may be a little overengineered but it works pretty well imo.
So I've made a custom Image tag that can be called this way :
<ProfileImage urlAPI={urlAPI} url={`/profile/${pictureId}`} token={token}/>
And works like so :
import React, {useState, useEffect} from 'react';
import Image from 'next/image'
export default function ProfileImage({urlAPI, url, token}) {
const [image, setImage] = useState(false);
useEffect(() => {
(async () => {
//Get if url already exists in local storage
let cached = window.localStorage.getItem(url);
if(cached){
setImage(cached);
//If not, get it from API
} else {
const response = await fetch(urlAPI+url, {
headers: {
'Method': 'GET',
'Authorization': `${token}`
}
});
//Extract image from response body
let base64Image = await response.json();
let imageObject = await fetch(`data:image/webp;base64,${base64Image}`);
imageObject = await imageObject.blob();
//Create an Url that stores the image
const objectURL = URL.createObjectURL(imageObject);
//Save in local storage and component state
setImage(objectURL);
window.localStorage.setItem(url, objectURL);
}
})();
() => {
// clear memory if needed
URL.revokeObjectURL(image);
window.localStorage.removeItem(src);
}
}, [])
return (
<>
{ image ?
<Image src={image} alt="profile" className="rounded-full" width={90} height={90}/>
:
<div className=""></div>
}
</>
)
}
The thing i did not know is that the browser can have urls generated on the go to store and cache images, so I've used this feature because the component kept asking api for images and recreated local urls every time the component was rendered.
I will upgrade this component and make cache invalidation.