
Pernah gak kamu buka sebuah website, dan dalam 3 detik langsung tutup tab-nya karena tampilannya meh banget? Nah, hal kayak gitu tuh bisa berdampak besar buat bisnis online. Di dunia digital sekarang, kesan pertama pengguna ditentukan bukan dari kata-kata, tapi dari tampilan visual yang mereka lihat di layar.
Bayangin kamu punya produk bagus, layanan keren, bahkan diskon besar-besaran⦠tapi desain websitenya berantakan, loading-nya lama, gambar-gambar pecah, dan warna-warnanya bikin mata sakit. Udah pasti banyak pengunjung yang bakal langsung kabur, bukan karena produkmu jelek, tapi karena first impression-nya gagal total.
Tampilan website yang cantik itu bukan soal gaya-gayaan. Ini soal membangun kepercayaan, meningkatkan waktu kunjungan, dan yang paling penting: mendorong konversi. Orang yang merasa nyaman di sebuah halaman, kemungkinan besar akan lebih lama mengeksplor, membaca lebih lanjut, bahkan akhirnya klik tombol beli sekarang atau hubungi kami.
Dan jangan salah, tampilan yang menarik bukan hanya urusan desainer aja. Frontend developer juga punya peran penting buat mewujudkan desain jadi pengalaman nyata. Gambar yang dimuat, cara loading-nya, responsif-nya, semuanya berpengaruh ke persepsi pengguna.
Makanya, sebelum mikirin fitur canggih atau sistem login yang kompleks, pastikan dulu tampilannya enak dipandang. Karena di dunia online, mata adalah gerbang ke dompet πΈ
Kita Akan Belajar Soal Gambar di Next.js
Nah, masuk ke topik utama. Di artikel ini, kita bakal bahas pentingnya penggunaan image yang baik dalam framework Next.js. Terutama buat kamu yang masih baru banget mulai belajar Next.js, ini adalah salah satu fondasi penting yang sering dianggap remeh.
Gambar itu bukan cuma pemanis tampilan, tapi juga bisa memengaruhi kecepatan website, SEO, dan kenyamanan pengguna. Salah satu keunggulan Next.js adalah dia punya sistem optimasi gambar bawaan yang canggih, dan yes, ini sangat direkomendasikan buat pemula karena bisa langsung dapet benefit besar tanpa ribet.
Kita gak langsung masuk ke coding dulu ya. Di bagian awal ini, tujuannya supaya kamu ngerti dulu kenapa hal ini penting banget. Setelah kamu paham konteks dan alasannya, barulah nanti kita pelajari gimana cara implementasinya di proyek nyata.
Jadi, siapkan diri kamu. Karena kita akan eksplor fitur image di Next.js yang bisa bikin website kamu bukan cuma tampil cantik, tapi juga cepat dan efisien π
Gambar di Next.js Gak Sama Kayak <img>
, Tapi Bisa Gantikan dengan Cara Lebih Pintar
Kalau kamu udah biasa pakai tag HTML <img>
, kamu mungkin bakal mikir:
βLah, kenapa sih harus repot-repot ganti ke komponen <Image />
dari Next.js?β
Jawabannya simpel: <Image />
itu versi modern dan smart dari <img>
.
Dia bawa fitur bawaan seperti lazy loading otomatis, optimasi ukuran gambar, dan format gambar modern (seperti WebP) β semua ini bisa ngebantu banget buat performa website kamu tanpa perlu setting manual.
Tapi perlu diingat ya, <Image />
ini bukan 100% drop-in replacement dari <img>
. Ada aturan mainnya. Kalau kamu asal copy-paste <img>
terus ganti jadi <Image>
, kemungkinan besar error. Yuk kita lihat perbedaannya.
Contoh <img>
biasa:
<img src="/assets/images/hero.png" alt="Hero Banner" />
Kalau kamu pakai komponen <Image />
dari Next.js, kamu harus import dulu dan struktur penggunaannya beda:
import Image from 'next/image'
export default function HeroSection() {
return (
<div>
<Image
src="/assets/images/hero.png"
alt="Hero Banner"
width={600}
height={400}
/>
</div>
)
}
Perlu diperhatikan, kamu gak bisa pakai path dari luar (URL full dari domain lain) secara langsung tanpa setting tambahan. Dan kamu gak boleh asal nulis <Image src="..." />
tanpa kasih tahu ukuran gambar.
Jadi intinya: <Image />
itu memang gantinya <img>
, tapi kamu harus ngerti cara pakainya supaya gak error dan justru bikin frustrasi.
Harus Pakai width
dan height
, Kecuali Kamu Pakai Layout Khusus
Satu hal yang bikin developer baru sering bingung waktu pakai <Image />
adalah: kenapa harus banget ada width
dan height
?
Kalau pakai <img>
kan tinggal tempel, langsung jalan. Tapi di Next.js, kamu bakal kena error kalau gak spesifik kasih ukuran.
Ini bukan Next.js iseng, tapi justru demi kebaikan performa website kamu. Dengan ukuran yang jelas, browser bisa langsung hitung layout halaman sebelum gambar benar-benar muncul β hasilnya: gak ada layout shift yang ganggu UX.
Contoh penggunaannya:
import Image from 'next/image'
export default function ProfileCard() {
return (
<div className="w-[300px] p-4 border rounded-lg">
<Image
src="/assets/images/avatar.png"
alt="User Avatar"
width={100}
height={100}
className="rounded-full"
/>
<h3 className="mt-4 font-semibold text-lg">Andi Prasetyo</h3>
<p className="text-gray-500">Fullstack Developer</p>
</div>
)
}
Tapi gimana kalau kamu gak tahu ukurannya, atau kamu pengen gambar ini responsif?
Tenang, Next.js kasih opsi lain: kamu bisa pakai prop fill
atau layout="fill"
(di versi lama). Tapi ini perlu container yang punya posisi relatif dan ukuran yang ditentukan.
Contoh penggunaan fill
:
import Image from 'next/image'
export default function FullCover() {
return (
<div className="relative w-full h-[400px]">
<Image
src="/assets/images/banner.jpg"
alt="Cover Image"
fill
style={{ objectFit: 'cover' }}
/>
</div>
)
}
Yang penting kamu ingat: kalau gak pakai width
dan height
, maka kamu harus pakai pendekatan khusus seperti fill
, dan pastikan container-nya punya ukuran yang jelas.
Kalau dua-duanya gak ada? Yaβ¦ bakal error. Jadi jangan lupa aturan main ini biar pengalaman coding kamu lebih lancar π
Semua Gambar Di-Load Secara Lazy Otomatis β Tanpa Perlu Kamu Atur
Kalau kamu pernah ngoding manual dan pakai <img loading="lazy" />
biar gambar gak langsung dimuat semua pas user buka halaman, kamu pasti tahu pentingnya lazy loading. Ini bikin halaman lebih ringan dan cepat tampil, terutama kalau ada banyak gambar.
Nah, enaknya pakai <Image />
dari Next.js itu kamu gak perlu nulis loading="lazy"
lagi. Soalnya Next.js udah otomatis menerapkan lazy loading untuk semua gambar yang pakai komponen ini. Artinya, gambar hanya akan dimuat ketika sudah hampir masuk ke viewport (layar user).
Contohnya kayak gini:
import Image from 'next/image'
export default function BlogThumbnail() {
return (
<div className="p-6 border rounded-lg w-full max-w-md">
<Image
src="/assets/images/article-cover.jpg"
alt="Cover Artikel"
width={600}
height={350}
/>
<h2 className="text-xl font-bold mt-4">Tips Belajar Next.js untuk Pemula</h2>
<p className="text-gray-600 mt-2">Pelajari cara kerja komponen image yang powerful ini...</p>
</div>
)
}
Gak ada keterangan lazy loading di kode? Betul. Tapi saat kamu cek DevTools atau scroll pelan-pelan, kamu akan lihat bahwa gambar baru dimuat saat mendekati layar. Ini karena sistemnya udah smart banget.
Jadi kamu tinggal fokus ke desain dan strukturnya aja, sisanya Next.js bantuin optimasinya dari belakang layar π οΈ
Format Gambar Diubah Otomatis ke WebP atau yang Lebih Ringan
Pernah dengar format gambar WebP? Itu loh, format gambar yang lebih ringan dari JPEG atau PNG tapi kualitasnya tetap bagus. Format ini bisa bikin loading website lebih cepat β terutama di koneksi yang lambat atau di device mobile.
Nah, satu lagi fitur keren dari <Image />
di Next.js adalah: kamu gak perlu konversi gambar ke WebP secara manual.
Next.js secara otomatis akan memilih format gambar paling optimal berdasarkan browser yang digunakan user.
Misalnya kamu upload gambar PNG, lalu user buka website dari Chrome yang support WebP β maka Next.js akan otomatis kasih versi WebP ke browser tersebut. Kalau browsernya gak support WebP, ya gak masalah β fallback ke format asli. Jadi aman buat semua pengguna.
Coba lihat contoh ini:
import Image from 'next/image'
export default function ProductCard() {
return (
<div className="border p-4 rounded-md w-[300px]">
<Image
src="/assets/images/shoes.png"
alt="Sepatu Keren"
width={280}
height={200}
className="rounded-md"
/>
<h4 className="font-semibold text-lg mt-3">Sepatu Lari Pro</h4>
<p className="text-sm text-gray-500 mt-1">Ringan, stylish, dan nyaman dipakai seharian</p>
</div>
)
}
Kamu upload-nya shoes.png
, tapi user bisa aja nerima shoes.webp
karena Next.js bantuin konversi di server saat build atau runtime.
Ini yang bikin kecepatan website kamu bisa meningkat tanpa perlu kamu convert manual satu per satu.
Kesimpulannya: pakai <Image />
itu kayak punya asisten pribadi yang ngurusin performa gambar buat kamu, tinggal pakai dan santai π
Gambar Lokal Lebih Disukai Kalau Disimpan di Folder public/
Next.js punya cara tersendiri dalam menangani gambar. Secara default, dia lebih suka gambar-gambar yang kamu simpan di folder public/
. Kenapa? Karena gambar yang disimpan di folder public/
itu bisa langsung diakses sebagai URL statis, tanpa perlu di-import atau dibundle ke dalam JavaScript.
Contohnya gini, kamu punya gambar hero.jpg
yang kamu simpan di:
/public/assets/images/hero.jpg
Nah, kamu tinggal panggil gambar itu dengan path /assets/images/hero.jpg
di komponen <Image />
.
Contoh penggunaannya:
import Image from 'next/image'
export default function LandingHero() {
return (
<div className="w-full h-[500px] relative">
<Image
src="/assets/images/hero.jpg"
alt="Gambar Hero Section"
fill
style={{ objectFit: 'cover' }}
/>
<div className="absolute bottom-10 left-10 text-white">
<h1 className="text-4xl font-bold">Bangun Bisnis Online dengan Website</h1>
</div>
</div>
)
}
Kamu gak perlu import
gambar tersebut seperti file JS atau asset lainnya, cukup tulis path-nya dari folder public/
.
Oh ya, yang perlu diingat: path-nya gak boleh diawali dengan ./
atau ../
, cukup langsung mulai dari root URL, misalnya /images/foto.jpg
.
Mau Pakai Gambar dari Luar? Bisa Banget, Tapi Harus Diatur Dulu
Kalau kamu ambil gambar dari domain luar, misalnya dari CDN atau website lain (kayak https://images.unsplash.com/...
), Next.js bakal blokir secara default. Ini demi alasan keamanan dan performa β supaya server gak sembarangan fetch gambar dari mana aja.
Tapi tenang, kamu masih bisa pakai gambar eksternal asal kamu daftarin dulu domain-nya di file next.config.js
.
Contoh konfigurasinya:
// next.config.js
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com',
},
],
},
}
module.exports = nextConfig
Setelah itu, kamu bisa pakai gambar dari URL eksternal seperti ini:
import Image from 'next/image'
export default function ExternalImageExample() {
return (
<div className="w-full max-w-[500px] mx-auto p-4">
<Image
src="<https://images.unsplash.com/photo-1603791440384-56cd371ee9a7>"
alt="Ilustrasi Startup"
width={500}
height={300}
className="rounded-lg"
/>
<h3 className="mt-4 font-semibold text-lg">Inspirasi Kantor Startup</h3>
</div>
)
}
Tanpa setting remotePatterns tadi, kode di atas bakal error pas build atau runtime. Jadi kalau kamu tahu bakal ambil gambar dari luar, pastikan domainnya udah dikonfigurasi dulu.
Intinya, Next.js kasih kamu fleksibilitas β mau pakai gambar dari dalam public/
atau dari luar, semua bisaβ¦ asal kamu tahu cara mainnya π
Bikin Gambar Responsif? Bisa Banget Pakai sizes
dan Tailwind CSS
Salah satu fitur canggih di Next.js <Image />
adalah responsive image β yaitu gambar yang menyesuaikan ukurannya tergantung ukuran layar pengguna.
Tapi⦠ini bukan cuma soal width: 100%
. Next.js juga bantuin kita nge-load gambar yang ukurannya paling efisien buat ukuran layar tersebut.
Supaya fitur ini bekerja maksimal, kamu bisa kombinasikan properti sizes
di Next.js dengan Tailwind CSS.
sizes
itu kayak βpetunjukβ ke browser, bilang:
βkalau layarnya segini, ambil gambar ukuran sekian ya.β
Contoh penggunaannya:
import Image from 'next/image'
export default function ResponsiveCard() {
return (
<div className="w-full md:w-1/2 lg:w-1/3 p-4">
<Image
src="/assets/images/responsive.jpg"
alt="Gambar Responsif"
width={800}
height={600}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="rounded-xl w-full h-auto"
/>
<h3 className="text-lg font-bold mt-3">Desain Fleksibel untuk Semua Layar</h3>
</div>
)
}
Dengan kode ini, saat layarnya kecil (mobile), gambar akan gunakan 100% lebar viewport, tapi kalau makin lebar, dia akan turun jadi 50% atau 33% tergantung ukuran layar.
Browser akan pilih gambar ukuran terbaik, jadi gak boros bandwidth dan tetap tajam tampilannya.
Pakai layout="fill"
atau fill
Kalau Kamu Mau Gambar Penuh dan Bebas Atur Pakai CSS
Kadang kamu pengen gambar jadi background penuh dari sebuah elemen β contohnya kayak header, banner, atau hero section yang besar.
Dalam kasus seperti ini, kamu bisa pakai properti fill
(versi modern dari layout="fill"
di Next.js versi lama). Tapi inget ya, harus dibungkus dengan elemen yang punya posisi relatif dan ukuran yang jelas.
Tujuannya? Supaya Next.js tahu seberapa besar ruang yang harus diisi gambarnya.
Contoh penggunaan:
import Image from 'next/image'
export default function FullWidthBanner() {
return (
<div className="relative w-full h-[500px]">
<Image
src="/assets/images/full-banner.jpg"
alt="Banner Penuh"
fill
style={{ objectFit: 'cover' }}
priority
/>
<div className="absolute bottom-10 left-10 text-white">
<h1 className="text-4xl font-bold">Selamat Datang di Website Kami</h1>
<p className="mt-2 text-lg">Solusi modern untuk bisnis digital kamu</p>
</div>
</div>
)
}
Di atas, div wrapper punya className="relative w-full h-[500px]"
, dan itu penting banget supaya <Image fill />
bisa menyesuaikan 100% lebar dan tinggi elemen tersebut.
Ditambah dengan objectFit: 'cover'
, hasilnya gambar akan memenuhi seluruh ruang dengan crop otomatis kalau perlu, mirip banget kayak background-image: cover
.
Jadi, kalau kamu butuh kontrol penuh pakai Tailwind atau CSS untuk bikin hero section yang estetik dan powerful, opsi fill
ini wajib banget kamu kuasai πͺ
Bantu SEO an Percepat LCP (Largest Contentful Paint)
Salah satu alasan kenapa komponen <Image />
dari Next.js itu powerful banget adalah karena dia gak cuma bantu tampilan website jadi kece, tapi juga berdampak langsung ke performa β terutama dalam skor SEO dan Core Web Vitals.
Salah satu metrik penting di sana adalah LCP (Largest Contentful Paint), yaitu waktu yang dibutuhkan sampai konten terbesar (biasanya gambar hero atau judul utama) muncul di layar.
Kalau kamu pakai gambar biasa yang belum dioptimasi, bisa bikin loading lama. Tapi kalau pakai <Image />
, gambar bakal:
- Di-lazy load kalau bukan bagian utama
- Di-preload kalau jadi prioritas
- Di-resize ke ukuran paling efisien
Semua itu bantu browser nampilin konten utama lebih cepat, yang akhirnya ningkatin skor SEO dan pengalaman pengguna.
Contoh implementasi yang bagus buat LCP:
import Image from 'next/image'
export default function HeroSEO() {
return (
<section className="relative w-full h-[600px]">
<Image
src="/assets/images/lcp-hero.jpg"
alt="Gambar Utama LCP"
fill
priority
style={{ objectFit: 'cover' }}
/>
<div className="absolute bottom-10 left-10 text-white">
<h1 className="text-5xl font-bold">Bangun Masa Depan Digital Kamu</h1>
<p className="mt-3 text-xl">Website cepat = peluang lebih besar β¨</p>
</div>
</section>
)
}
Dengan properti priority
, gambar ini akan dimuat lebih awal, karena kita kasih tahu ke Next.js bahwa ini konten penting di halaman.
Hasilnya? Waktu LCP jadi jauh lebih cepat, dan Google pun akan lebih senang saat ngecek performa websitemu lewat Lighthouse.
Masih Bisa Lewatin Optimasi Kalau Emang Perlu
Walaupun optimasi gambar itu sangat berguna, kadang ada kasus di mana kamu gak pengen Next.js optimize gambar yang kamu pakai.
Misalnya:
- Kamu udah punya gambar yang sangat teroptimasi sendiri (WebP atau SVG)
- Kamu butuh kontrol penuh atas cara gambar di-load
- Kamu pengen pakai
<img>
biasa tanpa sistem dynamic image loader dari Next.js
Caranya? Kamu tinggal set prop unoptimized
di komponen <Image />
. Ini akan kasih tahu Next.js: βudah, gak usah diapa-apain ya gambar ini.β
Contoh penggunaannya:
import Image from 'next/image'
export default function CustomImageExample() {
return (
<div className="w-full p-6">
<Image
src="/assets/images/custom.svg"
alt="Custom Gambar"
width={300}
height={300}
unoptimized
className="mx-auto"
/>
<p className="text-center mt-4 text-gray-600">Gambar ini tidak dioptimasi otomatis</p>
</div>
)
}
Perlu dicatat, saat kamu pakai unoptimized
, artinya kamu bertanggung jawab sendiri terhadap performa gambar tersebut.
Ini bukan opsi default, dan hanya digunakan kalau kamu tahu betul apa yang kamu lakukan.
Tapi enaknya, Next.js tetap fleksibel: kalau kamu butuh performa β dia bantuin. Kalau kamu butuh kontrol penuh β dia izinkan. Kombinasi yang mantap buat developer modern πΌ
Penutup: Kamu Sudah Kuasai 10 Hal Penting Tentang Gambar di Next.js
Kita udah belajar bareng 10 poin penting tentang penggunaan gambar di Next.js β mulai dari kenapa <Image />
lebih baik dari <img>
, gimana caranya bikin gambar lebih responsif, cara kerja lazy loading otomatis, optimasi format seperti WebP, hingga konfigurasi untuk gambar eksternal. Bahkan, kita juga bahas bagaimana optimasi ini bisa bantu skor SEO dan performa LCP-mu jadi lebih baik.
Intinya, <Image />
bukan cuma soal estetika. Dia adalah alat penting buat bikin website kamu lebih cepat, lebih ramah SEO, dan lebih nyaman diakses dari semua device.
Tapi ini baru permulaan.
Kalau kamu pengen next level dalam belajar Next.js β bukan cuma tahu dasar-dasarnya, tapi juga bisa bikin project yang siap masuk portofolio kerja remote β kamu bisa belajar langsung dari mentor expert di BuildWithAngga.
Dengan belajar di BuildWithAngga, kamu bisa dapat banyak benefit seperti:
β Akses kelas selamanya
β Materi langsung dari praktisi industri
β Forum diskusi dan feedback bareng mentor
β Project real-world yang bisa jadi portofolio
β Peluang persiapan kerja remote, freelance, atau startup
Jadi tunggu apa lagi? Yuk lanjutkan belajar bareng mentor di BuildWithAngga, karena masa depan digital dimulai dari langkah kecil hari ini π