[Nextjs Tip] How to resize image URL dynamically with next/image component

blank sketchbook

In Next.js, To use the <image /> component, width and height(props) are required and the value should be integer in pixels unless layout(props) is ‘fill’

Let’s say you want to render images via image URL from a server. There is a big chance that you might not know the size of the images. Let’s have a look at what we can do in this case.

# Case 1

Next.js recommends getting image dimensions along with the URL from a server.

Modify your API calls

If your application is retrieving image URLs using an API call (such as to a CMS), you may be able to modify the API call to return the image dimensions along with the URL.

What If you’re in a position where you are unable to get dimensions from the server? You have to get the dimensions on your client-side.

To get dimensions, Refer to the code below. You can get image dimensions from the image URL.

// image.jsexport const getImageRef = (url) => {   return new Promise((resolve, reject) => {      const img = new Image();      img.onload = () => resolve(img);      img.onerror = () => reject();      img.src = url;   });};// Usageconst setImageSize = async () => {   const img = await getImageRef(src);   return { width: img?.width || 0, height: img?.height || 0 };};

# Case 2

What if you want to scale the image to fit the width of the container and auto-size the height along with the width. (width=’100%’; height=’auto’) You can use the getImageRef function from Case 1 and layout=’responsive’. For this case, I created a new component, <CustomImage />.

// CustomImage.tsimport { useEffect, useState } from 'react';import Image from 'next/image';import getImageRef from './image.ts';function CustomImage({ className, layout, src, ...props }) {   const [imgSize, setImgSize] = useState({ width: 0, height: 0 });   useEffect(() => {      const setImageSize = async () => {         const img = await getImageRef(src);         setImgSize({ width: img?.width || 0, height: img?.height || 
0 });
}; setImageSize(); }, []); return ( <div className={className}> <Image {...props} src={src} width={imgSize.width} height={imgSize.height} layout={layout} /> </div> );}CustomImage.defaultProps = { className: '', layout: 'responsive',};
// Usage<CustomImage src={randomImageUrl} alt='random alt'/>

When you insert the image URL into the <CustomImage />, it will get the original size of the image which means it will have the image dimensions. then, the layout=’responsive’ will scale the image to fit the width of the container.

Conclusion

I believe there are more ways to handle these cases. Please feel free to share your ways or better ways!

--

--

--

A Front-End Engineer in Korea. I am full of ideas, trying to make it happen.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

React to Angular: Use Redux for State Management in Angular with TypeScript

What happens when we type a URL in the address bar

JS 403 — 3 weeks into it

Server-Side Rendering a React App Using Express.js

Build and publish multiple react components to NPM

Lessons Learned in React Native (and other JS-based) Projects Development

How JavaScript works: the different types of conditional statements + 3 best practices

Figma tokens automatically turned into code: how we kickstarted our design system

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mijeong

Mijeong

A Front-End Engineer in Korea. I am full of ideas, trying to make it happen.

More from Medium

Passwordless Authentication in Next.js with NextAuth.js and MongoDB

How to self-host fonts in NextJS

How to add TypeScript to an existing Next.js project

React Modal Component Implementation