Busque em todas as páginas da documentação
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Use o componente next/image para otimizar automaticamente imagens com lazy loading, dimensionamento responsivo e formatos modernos (WebP/AVIF). Configure padrões remotos para fontes de imagem externas.
// app/components/optimized-image.tsx
import Image from "next/image";
// Imagem local (importação estática habilita o placeholder de blur automático)
import heroPhoto from "@/public/images/hero.jpg";
export function HeroImage() {
return (
<Image
src={heroPhoto}
alt="Uma paisagem de montanha cênica"
placeholder="blur"
priority
className="rounded-lg"
/>
);
}// Imagem remota com dimensões explícitas
export function RemoteImage() {
return (
<Image
src="https://images.unsplash.com/photo-example"
alt="Foto do Unsplash"
width={800}
height={600}
className="rounded-lg"
/>
);
}// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "images.unsplash.com",
},
{
protocol: "https",
hostname: "cdn.pixabay.com",
},
],
},
};
export default nextConfig;Uma galeria de imagens responsiva com placeholders de blur e um layout pronto para lightbox:
// app/components/image-gallery.tsx
import Image from "next/image";
interface GalleryImage {
src: string;
alt: string;
blurDataURL: string;
width: number;
height: number;
}
const images: GalleryImage[] = [
{
src: "https://images.unsplash.com/photo-1506744038136-46273834b3fb",
alt: "Lago na montanha ao amanhecer",
blurDataURL: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCA...",
width: 1200,
height: 800,
},
{
src: "https://images.unsplash.com/photo-1469474968028-56623f02e42e",
alt: "Caminho na floresta no outono",
blurDataURL: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCA...",
width: 1200,
height: 800,
},
{
src: "https://images.unsplash.com/photo-1447752875215-b2761acb3c5d",
alt: "Cordilheira nebulosa",
blurDataURL: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCA...",
width: 1200,
height: 800,
},
];
export function ImageGallery() {
return (
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
{images.map((image, index) => (
<div key={image.src} className="relative aspect-[3/2] overflow-hidden rounded-xl">
<Image
src={image.src}
alt={image.alt}
fill
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
placeholder="blur"
blurDataURL={image.blurDataURL}
priority={index === 0}
className="object-cover transition-transform duration-300 hover:scale-105"
/>
</div>
))}
</div>
);
}// app/gallery/page.tsx
import { ImageGallery } from "@/app/components/image-gallery";
export default function GalleryPage() {
return (
<main className="mx-auto max-w-6xl px-4 py-8">
<h1 className="mb-6 text-3xl font-bold">Galeria de Fotos</h1>
<ImageGallery />
</main>
);
}next/image serve automaticamente imagens em formatos modernos (WebP, AVIF) com base no suporte do navegador através da API de Otimização de Imagens integrada.priority desabilita o lazy loading e pré-carrega a imagem, tornando-a ideal para imagens LCP (Largest Contentful Paint) acima da dobra.fill faz a imagem preencher seu contêiner pai. O pai deve ter position: relative (ou absolute ou fixed) e dimensões definidas.sizes informa ao navegador qual largura de imagem solicitar em cada ponto de interrupção da viewport. Sem ela, o Next.js serve a imagem em tamanho completo para todos os dispositivos.import hero from "@/public/hero.jpg") fornecem automaticamente width, height e blurDataURL.width e height (ou fill) porque o Next.js não pode inspecioná-las no momento da compilação.Modo fill com contêiner de proporção:
<div className="relative aspect-video w-full">
<Image
src="/images/banner.jpg"
alt="Banner"
fill
sizes="100vw"
className="object-cover"
/>
</div>Tamanhos responsivos para diferentes layouts:
// Herói em tela cheia
<Image src={src} alt={alt} fill sizes="100vw" />
// Grade de duas colunas
<Image src={src} alt={alt} fill sizes="(max-width: 768px) 100vw, 50vw" />
// Três colunas com barra lateral
<Image src={src} alt={alt} fill sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" />Loader personalizado para CDN externa:
import Image from "next/image";
const cloudinaryLoader = ({ src, width, quality }: { src: string; width: number; quality?: number }) => {
return `https://res.cloudinary.com/demo/image/upload/w_${width},q_${quality || 75}/${src}`;
};
export function CloudinaryImage() {
return (
<Image
loader={cloudinaryLoader}
src="sample.jpg"
alt="Imagem do Cloudinary"
width={800}
height={600}
/>
);
}next/image exporta os tipos ImageProps e StaticImageData.StaticImageData com as propriedades src, width, height e blurDataURL.loader é tipada como ImageLoader de next/image.import type { ImageProps, StaticImageData } from "next/image";
interface HeroProps {
image: StaticImageData;
alt: string;
priority?: boolean;
}fill sem sizes força o navegador a baixar a maior variante da imagem. Sempre combine fill com uma prop sizes apropriada.fill deve ter position: relative (ou absolute ou fixed) e dimensões definidas. Sem isso, a imagem colapsa para altura zero.placeholder="blur" com imagens remotas requer uma prop blurDataURL. Apenas importações estáticas geram isso automaticamente.priority deve ser usada apenas em imagens acima da dobra (tipicamente uma ou duas por página). O uso excessivo anula os benefícios do lazy loading.remotePatterns em next.config requer uma reinicialização do servidor para ter efeito. As alterações não são capturadas pelo hot reload.width e height não corta ou redimensiona o elemento de imagem no DOM. Esses valores definem a proporção e o tamanho da solicitação. Use CSS para dimensionamento visual.remotePatterns falharão com um erro 400 em tempo de execução, não em tempo de compilação.| Abordagem | Prós | Contras |
|---|---|---|
| next/image | Otimização integrada, lazy loading, conversão de formato | Props complexas, dependência do lado do servidor |
| Tag img nativa | Simples, sem configuração | Sem otimização, sem lazy loading por padrão |
| Cloudinary ou Imgix | Transformações avançadas, entrega via CDN | Serviço externo, custo adicional |
| @unpic/react | Agnóstico de framework, funciona com múltiplas CDNs | Sem servidor de otimização integrado |
Accept do navegador.priority apenas em imagens LCP (Largest Contentful Paint) acima da dobra.fill com uma prop sizes apropriada para servir imagens de tamanho correto por breakpoint.position: relative (ou absolute ou fixed).width, height e blurDataURL.width e height (ou fill), pois o Next.js não pode inspecioná-las no momento da compilação.placeholder="blur" funciona automaticamente com importações estáticas, mas precisa de um blurDataURL manual para imagens remotas.// next.config.ts
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{ protocol: "https", hostname: "images.unsplash.com" },
],
},
};Uma reinicialização do servidor é necessária após as alterações.
const cloudinaryLoader = ({ src, width, quality }: { src: string; width: number; quality?: number }) => {
return `https://res.cloudinary.com/demo/image/upload/w_${width},q_${quality || 75}/${src}`;
};
<Image loader={cloudinaryLoader} src="sample.jpg" alt="Foto" width={800} height={600} />import type { ImageProps, StaticImageData } from "next/image";StaticImageData é o tipo de retorno de importações estáticas, com src, width, height e blurDataURL.ImageLoader tipa a função loader personalizada.sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"Isso informa ao navegador para solicitar imagens de largura total no mobile, metade no tablet e um terço no desktop.
remotePatterns em next.config.ts e reinicie o servidor.Revisado por Chris St. John·Última atualização: 7 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥