khukuk
khukuk

Reputation: 67

How to get image height and width properties in Next.js?

I just want to know how can we let an image take its own height and width using <Image> component in Next.js, instead of defining height and width by ourselves?

Upvotes: 4

Views: 4586

Answers (1)

brc-dd
brc-dd

Reputation: 12954

Beginning from Next.js v11, you can simply do:

import Image from 'next/image';
import foo from 'path/to/foo.png';

// ...

<Image src={foo} alt="" /> // <-- no need to pass height/width

In the above example, foo will be an object containing src, height, width (and optionally blurDataURL). So, if you want to access them, you can do stuff like foo.height, etc.


Also, there are a few hacks that may interest you:

  1. Use layout="fill" and pass a handler to onLoadingComplete, where you will get naturalWidth and naturalHeight. Then you can set the state to adjust the container accordingly. But this approach is not recommended as it will likely increase CLS.

  2. In data fetching methods [getStaticProps (static generation) / getServerSideProps (SSR)], read your image files and pass their dimensions as a prop to your components. SSR may cause an overhead on your server resources, but that can be minimized significantly by caching.

  3. Simply use your good old img tag. Again not recommended, but will work if your files are already optimized. ESLint may throw some warning depending on your configuration, you would need to disable those rules.


PS: Just check once if your use-case can be handled by layout="fill" (without updating state).

Just a clarification - on older threads on SO, GitHub, etc., you may see an unsized prop being passed to next/image. It was deprecated in Next.js v10, and removed in v11. So, its probably not gonna work for you.


References:


A sample implementation of the second hack:

import fs from "fs";
import path from "path";

import Image from "next/image";
import probe from "probe-image-size";

const IndexPage = ({ mountains }) => (
  <Image
    src="/mountains.jpg"
    height={mountains.height}
    width={mountains.width}
    alt="Mountains"
  />
);

const getStaticProps = async () => {
  const mountains = await probe(
    fs.createReadStream(path.join(process.cwd(), "public/mountains.jpg"))
  );
  return { props: { mountains } };
};

export default IndexPage;
export { getStaticProps };

Upvotes: 6

Related Questions