Nextjs comes with great out of the box techniques to improve web performance. One such optimization is provided by next/image
module, which exposes the Image
component.
Image
component can optimize the images by reducing size as per image container and by converting to better formats like webp
. All the images are cached in .next/cache/images
Although there is a caveat, If you want to use images from third-party domains we have to list those domains in next.config.js
. If image domains are unknown then there is no way to use a wildcard to allow this.
Solution: Create an image proxy #
⚠️ Warning: Do not use this technique if third party domains are known, List those in
next.config.js
Nextjs provides a way to create APIs, We can use that to create a proxy endpoint which passthrough the actual image URLs.
// pages/api/imageproxy.js
export default async (req, res) => {
const url = decodeURIComponent(req.query.url);
const result = await fetch(url);
const body = await result.body;
body.pipe(res);
};
Now we can use any third party image using url /api/imageproxy?url=${encodeURIComponent(imageURL)}
.
<Image
key={image}
src={`/api/imageproxy?url=${encodeURIComponent(imageURL)}`}
width="400px"
height="320px"
objectFit="cover"
quality={80}
/>
Voila now all the images should be optimized and you should see a better lighthouse score #
Abuse concern #
By using Image
component API requests will be made only from the server-side. But because API endpoint is publically accessible so it can be abused. Abuse will result in unnecessary CPU utilization and cache Disk space usage.
// pages/api/imageproxy.js
export default async (req, res) => {
const secret = req.query.secret;
if (secret !== 'mysecret') {
res.send('error');
return;
}
const url = decodeURIComponent(req.query.url);
const result = await fetch(url);
const body = await result.body;
body.pipe(res);
};
Provide the secret while using image /api/imageproxy?url=${encodeURIComponent(imageURL)}&secret=mysecret
.
Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated ! For feedback, please ping me on Twitter.
Published