afaqrashid.com  ·  portfolio · 2026 ed.

Next.js Image "Missing Required Width Property": Tested Fixes

next/image needs to know an image's size before it loads, so the browser can reserve the space and the page doesn't jump. If it can't work the size out, you get "Error: Image with src "/hero.png" is missing required "width" property." (or "height").

I tested it on Next.js 16.4.4 with a 1200×600 PNG in public/, in next dev and in a production build, along with fill and a remote image.

What happened

<Image ...>                               tsc     next build   next dev   production
src="/hero.png", no width                passes  passes       500        200, no width/height on <img>
static import, no width                  passes  passes       200        200, width="1200" height="600"
fill, parent position: relative          passes  passes       200        200
fill, parent not positioned              passes  passes       200 + warn image covers the viewport
remote host not in next.config           passes  passes       500        page 200, image 400

Two things surprised me. TypeScript didn't flag the missing width: width and height are optional in the type, because fill and static imports don't need them. And the production build didn't fail either. The page rendered with no width or height on the <img>, which means no reserved space and a layout shift when the image arrives. The error only showed in next dev, as a 500 for the whole page.

⨯ Error: Image with src "/hero.png" is missing required "width" property.
 GET /i-nowidth 500 in 32ms

Fix 1: give width and height

<Image src="/hero.png" alt="Hero" width={1200} height={600} />

These are the image's real pixel size, or at least its aspect ratio. They don't set the size on screen; CSS does. Add style={{ width: "100%", height: "auto" }} or a class to make it responsive, and sizes if it isn't full width.

Fix 2: import the image

import Image from "next/image";
import hero from "../public/hero.png";

<Image src={hero} alt="Hero" />

With a static import, Next.js reads the file at build time. The HTML came out with width="1200" height="600" without me writing either. This is the easiest fix for images that live in the repo.

Fix 3: fill, with a positioned parent

When you don't know the size (CMS images, user uploads) or the image should cover a box, use fill. The image becomes position: absolute and fills its parent, so the parent needs a position and a size:

<div style={{ position: "relative", width: "100%", aspectRatio: "2 / 1" }}>
  <Image src={post.coverUrl} alt={post.title} fill sizes="100vw" style={{ objectFit: "cover" }} />
</div>

Without position on the parent, the build passed and next dev only printed a console warning: "Image with src "/hero.png" has "fill" and parent element with invalid "position". Provided "static" should be one of absolute,fixed,relative." In the browser the image measured 1710×848 at the top of the page, the size of my whole window, covering the heading. Set sizes too, to the width the image actually displays at; without it next/image assumes 100vw and may send a larger file than needed.

Remote images need the host in next.config

A remote URL needs width and height (or fill) like any other src, and its host must be allowed. With width and height set but no config, next dev returned a 500 with "hostname "cdn.shopify.com" is not configured under images in your next.config.js". Production again rendered the page with 200, but the optimiser refused the image with 400 "url" parameter is not allowed, so visitors saw a broken image.

// next.config.ts
import type { NextConfig } from "next";

const config: NextConfig = {
  images: {
    remotePatterns: [new URL("https://cdn.shopify.com/s/files/**")],
  },
};

export default config;

After that change and a dev server restart, the page returned 200. Keep the pattern as narrow as you can: an open pattern lets anyone use your server to resize their images.

Checklist

  • Images in the repo: import them, and the size comes for free.
  • Known size: width and height, with CSS for the display size.
  • Unknown size or cover images: fill, a parent with position: relative and a size, and sizes.
  • Remote images: add the host to images.remotePatterns and restart next dev.
  • Open every page in next dev before shipping: production won't tell you about any of these.

Related

Sources