Learn how to optimize images effortlessly in your Nuxt app using the NuxtImg component. Discover how to transform, cache, and resize images dynamically, improving performance with just a few lines of code.
Get notified when we release new tutorials, lessons, and other expert Nuxt content.
One of the best performance improvements you can do in your web app is dealing with images properly.
The (almost) built-in NuxtImg
component makes this really easy — transforming, compressing, caching, resizing, and more, with a few lines of code.
It will only take a few minutes to fill you in.
The NuxtImg
component is a drop-in replacement for all your img
tags, just like NuxtLink
replaces your a
tags.
It makes it super easy to resize images dynamically, cache them on your Nuxt server, and use images from other providers like Cloudinary, Directus, Fastly or anywhere else you’re storing them.
You can use the component just as you would a regular img
tag — it supports everything that the native image tag does:
<template>
<div class="p-2 md:-mx-8 lg:-mx-16">
<NuxtImg
class="rounded-xl shadow-lg w-full"
:src="src"
:alt="alt"
@click.stop="() => (showLightbox = !showLightbox)"
width="800"
/>
</div>
</template>
Nuxt will even download the package and install it automatically for you. The first time you use it, you’ll see a prompt in your CLI asking you to install the NuxtImg
package.
Using it like this, you won’t get most of the benefits of the component.
It will cache the images on your Nuxt server though.
Instead of fetching directly from the src
URL, your Nuxt server will fetch the image and cache it. If you inspect the devtools when using this component, you’ll see the actual src
used by the underlying img
tag is transformed to something like /_ipx/w_800/<https://source.unsplash.com/blue-volkswagen-beetle-on-grass-field-7HNftpNvqho/6000x4000
>.
The URL contains _ipx/
because Nuxt uses an unpackage tool called IPX to do all the image transformation. This fetched image and the transformed image are then cached.
This is fantastic, because it means you can use super high quality images in your app, but don’t have to rely on the provider being fast. Your server will cache the high-resolution image, along with any other versions of that image.
However, to get this to work, you have to do some configuration. But it’s very simple:
// nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@nuxt/image',
],
// Configure IPX here
image: {
domains: ['picsum.photos', 'www.google.com'],
provider: 'ipx',
},
});
You need to set the default provider
to ipx
in your nuxt.config.ts
. Otherwise, you’ll have to set the provider
prop on every usage of NuxtImg
. You’ll also need to include any domains you want to have transformed and cached in the domains
array.
Now, let’s move on to resizing and other things we can do with IPX!
As soon as we provide a width
or height
attribute on our NuxtImg
component, our image will be resized with IPX
:
<template>
<div class="p-2 md:-mx-8 lg:-mx-16">
<NuxtImg
class="rounded-xl shadow-lg w-full"
:src="src"
:alt="alt"
@click.stop="() => (showLightbox = !showLightbox)"
width="800"
/>
</div>
</template>
Beyond just resizing, IPX
and most other providers have a ton of other transformations we can apply. Here’s a list of what IPX can do. It’s powered by Sharp, so it supports most of what Sharp can do.
For example, we can get a grayscale version by applying the grayscale
modifier:
<template>
<div class="p-2 md:-mx-8 lg:-mx-16">
<NuxtImg
class="rounded-xl shadow-lg w-full"
:src="src"
:alt="alt"
@click.stop="() => (showLightbox = !showLightbox)"
width="800"
:modifiers="{ grayscale: true }"
/>
</div>
</template>
One of the best features is how easy it is to make responsive images — each user gets a different version based on their device’s screen size.
To make this work, we need to use the sizes
attribute. It’s a list of breakpoints and image sizes, using a format similar to TailwindCSS:
<NuxtImg
:src="src"
:alt="alt"
width="6000"
sizes="sm:600px md:800px lg:1600px xl:6000px"
/>
Here, we set four different sizes. The NuxtImg
component will then fetch the correct size based on the size of the client’s screen.
And because it’s all powered by IPX, all these versions are cached on your Nuxt server.
We can also use the densities
attribute to support different screen densities, like a Retina screen on a Macbook:
<NuxtImg
:src="src"
:alt="alt"
width="6000"
sizes="sm:600px md:800px lg:1600px xl:6000px"
densities="x1 x2"
/>
Using the NuxtImg
component into your web app unlocks powerful image optimizations with minimal effort.
From caching to resizing and responsive loading, this tool streamlines image management while improving performance. With just a few lines of configuration, you can deliver high-quality, fast-loading images tailored to each user’s device.