17

Next.js 13 is out. One of the refactored components is next/image.

I want to use it, but I want to set the image size using tailwind.

Here's my code:

import Image from 'next/image'

const Index = () => {
   return (
       <div>
           <Image
               src="https://picsum.photos/800/600"
               layout="fill"
               className="w-48 aspect-square md:w-72 xl:w-48"
           />
       </div>
   )
}

And I get this error:

Error: Image with src "https://picsum.photos/800/600" is missing required "width" property.

However, in docs it's said that it's possible to use fill without specifying the width and height.

What do I miss here?

Big boy
  • 1,113
  • 2
  • 8
  • 23
  • 1
    If i'm not mistaken, the new image component receives a `fill` prop which is a boolean, instead of a `layout` prop. Try ``. I believe this "new" component was known as `next/future/image` on Next.js 12.2+, you can check [this answer](https://stackoverflow.com/questions/69230343/nextjs-image-component-with-fixed-witdth-and-auto-height/73618982#73618982), might be helpful. – ivanatias Oct 30 '22 at 08:25
  • @ivanatias, yep, that did it. Thank you. Can you post your comment as an answer so that I can accept it? – Big boy Oct 30 '22 at 10:01

5 Answers5

35

Next.js v13 new image component receives a fill prop which is a boolean instead of the old layout prop. Example:

<Image
  src="https://picsum.photos/800/600"
  fill
  ...
/>

Also, you can now style the component's underlying image element using style or className.

Example using Tailwind CSS:

<Image
  src="some-image-url"
  width="0"
  height="0"
  sizes="100vw"
  className="w-full h-auto"
/>
ivanatias
  • 3,105
  • 2
  • 14
  • 25
  • 4
    using "fill" simply makes the image fullscreen which i don't want, and using width and height = 0 for some reason makes the image highly pixelated, can't simply replace with without encountering some error – Ariel Mirra Mar 26 '23 at 00:25
  • You are a Next.js god! The tailwind example fits my need for a cover image perfectly! (Nextjs13) – Ibra Apr 14 '23 at 20:23
  • Thanks. It's quite unfortunate that this isn't highlighted in their docs. – Victor Eke Jun 20 '23 at 08:45
  • 1
    @ArielMirra From nextjs docs: "The parent element must assign position: "relative", position: "fixed", or position: "absolute" style.". I was running into the same thing as you and fixed by adding css to make the container the image was in have a relative position. – kev1n Aug 20 '23 at 20:52
1

As per NextJS 13, 4 props are required(Mandatory), src, alt, width and height. Layout is removed as props

so either provide this props manually to image and remove layout props from your code

<Image
  src={logo.src}
  alt="logo"
  width={some number}
  height={some number} 
/>

or if you want layout fill, give height and width to parent component and write only fill like follows.

<Image
  src={logo.src}
  alt="logo"
  fill
  // sizes="100vw"
  style={{
    objectFit: 'cover',
  }}
/>

problem with first approach is that it asks for width and height in px and not relative values. So I will recommend second approach, i.e. give height and width to parents component and provide fill props(not layout="fill")

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
JTtime
  • 11
  • 1
1

Next.js will automatically determine the width and height if you import the image.

Local Images

import logoPic from "@/app/logo.png";
...
...       
   
<Image src={logoPic} alt="logo"/>
gellezzz
  • 1,165
  • 2
  • 12
  • 21
0

@ArielMirra I would use the fill prop on next image, and style the parent div to the image to be responsive, e.g:

<div className="w-[500px] h-[500px] lg:w-[1000px] lg:h-[1000px] relative">
 <Image src="/my-image.png" alt="My Image" fill />
</div>

I also think the parent needs the position of relative.

juicy j
  • 183
  • 5
  • 20
0

I would suggest a responsive approach that works nicely

The idea is to use the padding-top or padding-bottom property, which when given a percentage value, is calculated based on the width of the containing block. By using this fact, we can indirectly set an element's height based on its parent's width.

Among the advantages here are the fact we are using css only approach and not anything js that might cause a delay

      <div
    className="thumbnail"
    style={{
      position: "relative",
      width: "100%",
    }}
  >
    <div
      style={{
        paddingTop: "100%",
        height: 0,
        overflow: "hidden",
      }}
    >
      <Image
        itemProp="image"
        className={
          "game-cover-image lazy loaded object-cover border-radius"
        }
        fill
        src={'h}
        style={'https://via.placeholder.com/150'}
          position: "absolute",
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          objectFit: "contain",
          objectPosition: "left",
        }}
      />
    </div>
  </div>

<!DOCTYPE html>
<html>
<head>
  <style>
    .parent {
      position: relative;
      width: 100%;
    }

    .child {
      padding-top: 100%;
      height: 0;
      overflow: hidden;
    }

    .child-content {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: url('https://via.placeholder.com/350');
      background-size: cover;
      background-position: center;
    }
  </style>
</head>
<body>

<div class="parent">
  <div class="child">
    <div class="child-content">
      <!-- Content can go here -->
    </div>
  </div>
</div>

</body>
</html>
Vad.Gut
  • 521
  • 1
  • 5
  • 19