10 Hal Perlu Dipelajari Pemula Framework NextJS 15

Zaman sekarang, punya bisnis online tuh gak cukup cuma punya produk bagus dan harga bersaing. Serius deh. Karena di era digital kayak sekarang, cara orang menilai bisnismu itu udah berubah. Orang bisa langsung ilfeel cuma karena websitemu lemot, tampilannya jadul, atau malah gak bisa dibuka di HP.

Kita hidup di masa di mana semua serba instan dan cepat. Customer itu nggak mau nunggu, gak mau ribet. Mereka pengen cari produk, klik, terus checkout tanpa banyak drama. Dan buat bisa nyampe ke titik itu, artinya kamu — sebagai pemilik bisnis atau developer yang bantu bangun bisnis orang lain — perlu ngerti pentingnya pengalaman pengguna (user experience) dan teknologi yang mendukungnya.

Website adalah pintu utama buat pelanggan baru. Kalau tampilannya gak meyakinkan atau loading-nya lambat, mereka bisa langsung keluar sebelum sempat lihat produkmu. Parahnya lagi, bisa jadi mereka langsung pindah ke kompetitor yang tampilannya lebih segar dan lebih responsif. Makanya, update teknologi itu wajib.

Bukan karena ikut-ikutan tren, tapi karena itulah cara terbaik buat menjangkau lebih banyak orang dan ningkatin kepercayaan dari calon pembeli.

Kenapa Next.js Jadi Pilihan Terbaik Buat Bikin Website Modern

Di antara banyaknya framework yang bisa dipakai buat bikin website, Next.js sekarang bisa dibilang jadi salah satu primadona. Bukan cuma di kalangan developer expert, tapi juga buat pemula yang baru belajar bikin website profesional. Kenapa? Karena Next.js ini ngebuka banyak pintu kemudahan tapi tetap powerful.

Pertama, performanya luar biasa. Dengan fitur-fitur seperti server-side rendering (SSR), static site generation (SSG), dan hybrid rendering, Next.js bisa bantu website kamu tampil lebih cepat. Buat customer, ini artinya loading halaman gak pake muter-muter lama. Dan buat SEO? Ini surga. Karena Google lebih suka website yang cepet dan bisa diakses dengan struktur yang jelas. Cocok banget buat kamu yang pengen websitenya nongol di halaman pertama hasil pencarian.

Kedua, Next.js itu gak ribet. Serius. Struktur project-nya clean dan mudah diatur. Bahkan buat pemula, begitu mulai ngerti cara kerja routing-nya, semuanya jadi terasa natural. Ditambah lagi, dukungan komunitasnya gede banget.

Kamu gak akan merasa sendirian saat belajar karena dokumentasinya lengkap dan banyak banget tutorial gratis di luar sana.

Dan yang paling penting nih, Next.js itu cocok banget buat bikin full stack website. Artinya kamu bisa handle frontend dan backend sekaligus dalam satu project. Mau ngatur API sendiri? Bisa. Mau konek ke database?

Bisa juga. Mau deploy ke Vercel? Tinggal klik. Gak ada lagi drama setup yang makan waktu berjam-jam cuma buat bisa mulai coding.

Di Artikel Ini, Kita Bakal Kupas 10 Hal Penting Buat Kamu yang Baru Mulai Belajar Next.js

Nah, setelah kita ngobrol soal pentingnya bisnis online punya website yang cepat dan responsif, serta kenapa Next.js itu layak banget dipelajari… sekarang kita masuk ke bagian yang gak kalah penting, yaitu apa aja sih yang perlu kamu pelajari sebagai pemula di dunia Next.js?

Jujur aja, banyak banget orang yang baru mulai belajar Next.js langsung ngerasa overwhelmed. Mulai dari struktur folder yang beda dari React biasa, sampai fitur-fitur kayak server-side rendering dan API routes yang kedengarannya teknis banget.

Tapi santai aja, karena sebenarnya kalau dipecah satu per satu, semuanya bisa dicerna dengan gampang kok. Yang penting adalah urutan belajarnya tepat dan gak buru-buru pengen jago instan.

Di artikel ini, kita bakal bahas 10 hal penting yang wajib kamu pahami di awal-awal perjalanan kamu bareng Next.js. Semua poin ini disusun berdasarkan pengalaman pribadi dan juga kebiasaan belajar dari para pemula yang pernah gue mentoring—jadi bukan teori doang, tapi udah terbukti bermanfaat buat banyak orang.

Tujuannya bukan supaya kamu langsung expert dalam semalam ya, tapi biar kamu punya fondasi yang kuat. Karena Next.js itu bisa dipakai untuk banyak jenis website—mulai dari company profile sederhana, toko online, sampai platform edukasi atau sosial media skala besar. Makanya, punya pemahaman dasar yang rapi itu penting banget supaya ke depannya kamu gak gampang bingung atau frustrasi di tengah jalan.

Pahami Struktur Folder Next.js Lewat Analogi dan Contoh Biar Gak Nyasar

Ketika kamu mulai bikin project pakai Next.js (terutama versi terbaru yang pakai App Router), kamu akan langsung nemuin struktur folder yang keliatannya cukup rapi. Tapi jujur aja, kalau kamu belum pernah ngulik Next.js sebelumnya, struktur ini bisa bikin mikir, “Lho, ini apaan aja sih?”

Sekarang bayangin kamu lagi pindahan ke rumah baru. Rumah ini udah lengkap banget—ada ruang tamu, dapur, kamar tidur, sampai ruang kerja. Tapi semuanya ditata rapi. Nah, tiap ruangan itu fungsinya jelas, dan kamu gak perlu mikir dua kali buat nyari barang. Itulah perasaan ideal saat kamu udah paham struktur folder di Next.js.

Biar gak cuma bayangan, coba kita lihat contoh struktur folder sederhana berikut:

my-nextjs-project/
│
├── app/
│   ├── page.tsx             <- Ini halaman utama, tampil di route "/"
│   ├── about/
│   │   ├── page.tsx         <- Ini halaman tentang, tampil di route "/about"
│   │   └── layout.tsx       <- Layout khusus buat halaman "/about"
│   ├── dashboard/
│   │   ├── page.tsx         <- Halaman dashboard, route "/dashboard"
│   │   └── layout.tsx       <- Layout dashboard (biasanya sidebar)
│   └── layout.tsx           <- Layout global (header/footer yang muncul di semua halaman)
│
├── public/
│   ├── images/
│   │   └── logo.png         <- Gambar yang bisa langsung diakses dari browser
│   └── favicon.ico          <- Icon website
│
├── styles/
│   └── globals.css          <- CSS global kamu, misalnya reset style atau tema dasar
│
├── next.config.js           <- Konfigurasi Next.js
├── tsconfig.json            <- Setting TypeScript (kalau pakai TS)
└── package.json             <- Info dependencies & script project kamu

Sekarang coba lihat pelan-pelan.

Folder app/ ini bisa kamu anggap sebagai jantung utama project Next.js kamu. Semua halaman, layout, dan komponen routing berbasis file bakal ada di sini. Misalnya kamu bikin folder about, otomatis itu jadi halaman /about tanpa perlu konfigurasi routing manual.

File page.tsx adalah isi utama halaman tersebut, sedangkan layout.tsx itu seperti “kerangka tetap” yang membungkus kontennya—misalnya kamu pengen ada sidebar khusus di dashboard aja, atau halaman tertentu punya layout yang beda dari global.

Terus, folder public/ ini seperti garasi atau laci rumah tempat kamu nyimpen barang-barang yang bisa diakses langsung. Mau taruh gambar, icon, atau file lainnya? Simpen aja di sini, terus panggil di HTML atau komponen tanpa harus diimport secara eksplisit.

Struktur ini kelihatannya banyak, tapi justru bikin project kamu lebih tertata dan gampang dikembangin jangka panjang. Gak ada lagi tuh file App.jsx isinya komponen campur aduk. Dengan Next.js, kamu belajar untuk lebih rapih dan disiplin dari awal—dan ini penting banget kalau suatu hari kamu kerja bareng tim.

Intinya, struktur folder di Next.js itu bukan untuk bikin pusing, tapi justru ngebantu kamu kerja lebih enak. Begitu kamu udah terbiasa, semua bagian ini bakal terasa logis dan bikin proses ngoding jadi lebih nikmat.

Gimana Sih Cara Kerja Routing di Next.js? Yuk Pahami Lewat Analogi Jalan dan Papan Petunjuk

Routing itu sebenernya konsep yang udah lama banget ada di dunia web development. Tapi di Next.js, routing jadi terasa lebih alami karena semuanya diatur langsung lewat struktur folder. Nah, biar kamu gampang ngebayanginnya, kita coba pake analogi jalanan dan papan petunjuk, ya.

Bayangin kamu lagi jalan-jalan di sebuah kota kecil. Di tiap sudut kota, ada papan penunjuk jalan yang ngarahin kamu ke lokasi tertentu. Misalnya, kalau kamu liat papan bertuliskan “/about”, kamu tahu itu jalan menuju halaman informasi. Atau kalau kamu belok ke “/contact”, itu jalan ke tempat buat ngirim pesan.

Nah, di Next.js, kamu tinggal bikin folder atau file sesuai nama jalannya, dan secara otomatis sistemnya akan ngerti, “Oh, ini route ke halaman ini.” Jadi kamu gak perlu atur routing manual kayak di React biasa yang harus pakai react-router-dom dan bikin config panjang-panjang.

Contohnya gini:

Misal kamu punya struktur folder kayak gini di dalam app/:

app/
├── page.tsx
├── about/
│   └── page.tsx
├── contact/
│   └── page.tsx

Artinya:

  • app/page.tsx itu otomatis jadi route /
  • app/about/page.tsx itu route /about
  • app/contact/page.tsx itu route /contact

Setiap file page.tsx itu adalah papan petunjuk yang ngarahin pengunjung ke konten halaman tersebut.

Contoh isi kodenya di masing-masing halaman bisa kayak gini:

app/page.tsx

export default function HomePage() {
  return (
    <main>
      <h1>Selamat datang di website kita!</h1>
      <p>Ini adalah halaman utama.</p>
    </main>
  );
}

app/about/page.tsx

export default function AboutPage() {
  return (
    <main>
      <h1>Tentang Kami</h1>
      <p>Website ini dibangun menggunakan Next.js.</p>
    </main>
  );
}

app/contact/page.tsx

export default function ContactPage() {
  return (
    <main>
      <h1>Hubungi Kami</h1>
      <p>Kirim pesan lewat email ke [email protected].</p>
    </main>
  );
}

Kamu gak perlu ngapalin sintaks aneh atau setup routing tambahan. Cukup bikin folder dan file, dan Next.js akan otomatis ngerti path-nya.

Analoginya kayak kamu bikin bangunan-bangunan baru di kota kecil itu. Selama kamu kasih nama jalan dan papan petunjuk yang jelas, semua orang bisa dengan mudah navigasi ke tempat yang mereka tuju.

Dan kalau nanti kamu pengen bikin dynamic route (misalnya halaman detail produk atau artikel), tinggal tambahin tanda kurung di nama folder atau file—tapi itu bakal kita bahas lebih dalam di bagian selanjutnya. Intinya, Next.js routing itu super simpel dan sangat powerful, tinggal kamu biasain aja mainan sama struktur foldernya.

Jadi, gak ada alasan buat bingung-bingung lagi soal routing. Mulai dari sini aja, bikin beberapa halaman dan coba akses lewat browser. Rasain sendiri gimana Next.js ngatur jalannya buat kamu tanpa ribet.

Client vs Server Components di Next.js — Bedanya Apa? Yuk Biar Gak Gagal Paham!

Kalau kamu baru belajar Next.js, mungkin kamu bakal bingung waktu lihat ada komponen yang berjalan di "client" dan ada yang berjalan di "server". Di Next.js versi App Router, ini penting banget buat dipahami karena bakal nentuin di mana dan bagaimana komponen kamu dijalankan.

Biar gak pusing, yuk kita pakai analogi yang gampang dulu.

Bayangin kamu lagi nongkrong di restoran all-you-can-eat. Ada dua jenis makanan yang bisa kamu nikmati:

Pertama, makanan yang langsung dimasakin dan disajikan dari dapur oleh chef. Kamu gak perlu ikut masak, tinggal duduk, dan makanan datang ke meja kamu. Proses masaknya gak kelihatan, tapi hasil akhirnya langsung bisa kamu nikmati. Nah, itu ibaratnya Server Component. Semua prosesnya terjadi di server, dan hasilnya langsung dikirim ke browser.

Kedua, ada makanan yang kamu masak sendiri di meja, kayak Korean BBQ. Bahan-bahannya udah disiapin, tapi kamu yang ngatur masaknya. Ini ibarat Client Component—prosesnya terjadi di sisi browser, kamu bisa interaksi langsung sama elemennya: klik tombol, isi form, buka modal, dan sebagainya.

Next.js kasih kamu fleksibilitas buat milih, komponen mana yang pengen dijalanin di server (biar ringan dan SEO-friendly), dan mana yang perlu dijalanin di client (karena butuh interaksi langsung).

Oke, sekarang kita lihat contoh coding-nya biar lebih jelas.


Contoh Server Component (default)

Semua file .tsx di folder app/ itu default-nya adalah Server Component. Kamu gak perlu nulis apa-apa untuk deklarasinya.

app/about/page.tsx

export default function AboutPage() {
  const currentTime = new Date().toLocaleString();

  return (
    <main>
      <h1>Halaman Tentang Kami</h1>
      <p>Waktu saat halaman dirender dari server: {currentTime}</p>
    </main>
  );
}

Komponen ini bakal dirender di server. Artinya, waktu currentTime bakal diset di server dan hasilnya langsung dikirim ke browser sebagai HTML statis. Bagus banget buat SEO dan kecepatan render awal.


Contoh Client Component (butuh interaksi)

Kalau kamu butuh fitur yang interaktif—misalnya tombol yang bisa diklik—kamu harus declare komponen itu sebagai client.

app/counter/page.tsx

'use client'

import { useState } from 'react';

export default function CounterPage() {
  const [count, setCount] = useState(0);

  return (
    <main>
      <h1>Hitung Klik</h1>
      <p>Jumlah klik: {count}</p>
      <button onClick={() => setCount(count + 1)}>Tambah</button>
    </main>
  );
}

Perhatikan bagian 'use client' di paling atas. Itu wajib ditulis supaya Next.js tahu bahwa komponen ini perlu dijalankan di browser karena pakai useState, useEffect, atau interaksi DOM lainnya.


Kapan harus pakai yang mana?

Kalau kamu cuma butuh nampilin data, format tanggal, atau ambil data dari API dan render-nya gak butuh interaksi dari user, pakai Server Component. Lebih cepat, lebih ringan, dan bagus buat SEO.

Tapi kalau kamu butuh sesuatu yang interaktif—misalnya klik tombol, buka modal, isi form—pakai Client Component.

Dengan paham perbedaan ini, kamu bisa bikin aplikasi yang performanya lebih mantap dan loading-nya ngebut, tanpa ngorbanin interaksi yang dibutuhin user.

Jadi inget ya, Server Component = masakan siap saji dari dapur, Client Component = masak sendiri di meja. Dua-duanya enak, tinggal sesuaikan aja dengan kebutuhan aplikasi kamu.

Layouts dan Templates di Next.js — Biar Halamanmu Gak Capek Ngulang-ngulang

Ketika kamu bikin website, kamu pasti bakal punya banyak halaman yang punya bagian yang mirip-mirip. Misalnya, semua halaman punya header yang sama, footer yang sama, atau sidebar yang gak berubah. Nah, daripada kamu ngulang-ngulang bagian itu di tiap file, Next.js kasih fitur keren banget yang namanya layout dan template.

Biar gampang bayanginnya, kita coba pakai analogi bangunan.

Bayangin kamu lagi bangun sebuah apartemen. Semua unit apartemennya punya kerangka dasar yang sama—ada kamar mandi, dapur, ruang tamu, dan kamar tidur. Tapi masing-masing unit boleh punya isi yang berbeda, kayak furnitur atau warna tembok. Nah, layout itu kayak kerangka bangunan apartemen. Semua unit pakai kerangka yang sama biar efisien dan seragam.

Sementara itu, template itu kayak dekorasi awal dari ruangan tertentu, biasanya lebih jarang berubah. Misalnya, ruang meeting yang selalu punya layout dan tema warna yang konsisten—jadi beda dengan layout umum.

Dengan layout dan template di Next.js, kamu bisa atur biar tiap halaman punya kerangka tampilan yang konsisten, tapi tetap bisa beda isi sesuai kebutuhan.

Sekarang kita lihat contoh koding biar makin jelas ya.


Contoh Layout Utama (app/layout.tsx)

Layout ini akan membungkus semua halaman yang ada di project kamu.

// app/layout.tsx
import './globals.css';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="id">
      <body>
        <header>
          <h1>My Website</h1>
          <nav>
            <a href="/">Home</a> | <a href="/about">About</a>
          </nav>
        </header>
        <main>{children}</main>
        <footer>
          <p>© 2025 My Company</p>
        </footer>
      </body>
    </html>
  );
}

Semua halaman di dalam folder app/ secara otomatis akan dibungkus oleh layout ini. Jadi kamu gak perlu lagi nulis ulang header, nav, atau footer di tiap halaman.


Contoh Halaman (app/about/page.tsx)

Halaman ini akan tetap tampil di dalam layout yang sudah kamu buat.

export default function AboutPage() {
  return (
    <section>
      <h2>Tentang Kami</h2>
      <p>Kami membangun website ini pakai Next.js yang kece banget!</p>
    </section>
  );
}

Ketika kamu buka halaman /about, tampilannya akan tetap ada header, footer, dan konten dari halaman ini.


Contoh Layout Khusus (app/dashboard/layout.tsx)

Misalnya kamu pengen halaman di /dashboard punya sidebar dan tampilan yang beda dari layout utama.

// app/dashboard/layout.tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div style={{ display: 'flex' }}>
      <aside style={{ width: '200px', background: '#f0f0f0' }}>
        <p><strong>Menu Dashboard</strong></p>
        <ul>
          <li><a href="/dashboard">Home</a></li>
          <li><a href="/dashboard/settings">Settings</a></li>
        </ul>
      </aside>
      <main style={{ flex: 1, padding: '20px' }}>{children}</main>
    </div>
  );
}

Dan kamu bisa bikin halaman kayak app/dashboard/page.tsx yang akan dibungkus dengan layout khusus ini.

export default function DashboardHome() {
  return (
    <div>
      <h2>Welcome to the Dashboard</h2>
      <p>Ini adalah halaman utama dashboard.</p>
    </div>
  );
}


Dengan sistem layout dan template ini, kamu bisa bikin website yang modular, rapih, dan gampang dikembangin. Gak perlu capek-capek ngulangin header, nav, atau sidebar di tiap file. Tinggal taruh di layout, dan semuanya udah ke-handle otomatis.

Jadi ingat: layout = kerangka bangunan apartemen, template = dekorasi standar dari ruangan tertentu. Semua jadi efisien dan konsisten, dan kamu bisa fokus ngembangin fitur-fitur lainnya tanpa mikir ulang struktur halaman dari awal.

Metadata & SEO di Next.js — Biar Website Kamu Gak Cuma Cakep, Tapi Juga Gampang Ditemuin

Pernah gak kamu bikin website yang tampilannya keren banget, cepet juga, tapi kok sepi banget pengunjungnya? Nah, bisa jadi kamu lupa satu hal penting: metadata dan SEO.

Sekarang kita pakai analogi biar lebih gampang paham ya.

Bayangin kamu lagi bikin sebuah toko keren di tengah kota. Desainnya cakep, produknya lengkap, pelayanannya ramah. Tapi… kamu gak pasang papan nama, gak masuk Google Maps, bahkan gak ada info sama sekali di depan toko. Gimana orang mau nemu?

Nah, metadata itu ibarat identitas toko kamu yang muncul di Google. SEO (Search Engine Optimization) adalah upaya biar toko kamu muncul di hasil pencarian teratas waktu orang cari sesuatu yang kamu jual. Jadi meskipun kamu udah bangun website paling kece sedunia, tanpa metadata yang bener dan SEO yang oke, website kamu bisa aja gak pernah keliatan orang.

Untungnya, Next.js udah nyediain cara super gampang buat atur metadata tiap halaman. Kamu tinggal nambahin konfigurasi metadata di setiap page.tsx atau bahkan secara global di layout.tsx.

Langsung aja kita lihat contohnya.


Metadata Global (app/layout.tsx)

Ini akan jadi metadata default untuk semua halaman yang gak punya metadata spesifik.

// app/layout.tsx
export const metadata = {
  title: 'My Awesome Website',
  description: 'Belajar Next.js biar jadi web developer keren!',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="id">
      <body>{children}</body>
    </html>
  );
}

Dengan ini, setiap halaman akan punya judul "My Awesome Website" dan deskripsi sesuai yang kamu tulis. Ini penting banget buat hasil pencarian Google dan juga waktu orang share link kamu ke media sosial.


Metadata Khusus Halaman (app/about/page.tsx)

Kalau kamu pengen halaman tertentu punya metadata yang beda, kamu bisa override langsung di file halaman itu.

// app/about/page.tsx
export const metadata = {
  title: 'Tentang Kami - My Awesome Website',
  description: 'Pelajari lebih lanjut tentang tim dan misi kami di halaman ini.',
};

export default function AboutPage() {
  return (
    <main>
      <h1>Tentang Kami</h1>
      <p>Kami percaya teknologi bisa bantu banyak orang berkembang.</p>
    </main>
  );
}

Dengan begitu, halaman /about akan punya title dan description yang spesifik. Ini bikin mesin pencari kayak Google bisa lebih paham konten halaman kamu dan ngasih ranking yang lebih baik.


Bonus: Metadata Tambahan (Open Graph, Twitter, dll)

Kalau kamu pengen halaman kamu tampil keren waktu di-share ke Twitter atau WhatsApp, kamu juga bisa tambahin metadata sosial seperti ini:

// app/page.tsx
export const metadata = {
  title: 'Beranda - My Awesome Website',
  description: 'Ini halaman utama dari website Next.js kamu.',
  openGraph: {
    title: 'Beranda - My Awesome Website',
    description: 'Gabung belajar bareng dan jadi developer masa depan.',
    images: [
      {
        url: '/images/cover-home.jpg',
        width: 1200,
        height: 630,
        alt: 'Cover Home Page',
      },
    ],
  },
  twitter: {
    card: 'summary_large_image',
    title: 'Beranda - My Awesome Website',
    description: 'Gabung belajar bareng dan jadi developer masa depan.',
    images: ['/images/cover-home.jpg'],
  },
};


Jadi intinya, metadata itu bukan hiasan doang. Dia adalah wajah dan kartu nama digital halaman kamu di dunia luar. Mesin pencari, media sosial, dan browser semuanya ngandelin metadata buat nunjukin konten kamu ke dunia.

Jangan sampai website kamu udah keren dan fungsional, tapi gak ada yang tahu karena gak dioptimasi dari sisi metadata dan SEO-nya. Di Next.js, semuanya udah disiapin tinggal kamu manfaatin.

Pentingnya Optimasi Gambar di Next.js — Biar Website Gak Berat Kayak Bawa Koper Isi Batu

Optimasi gambar itu hal yang sering diremehin sama pemula, padahal efeknya gede banget ke kecepatan website dan pengalaman pengguna. Nah, Next.js datang bawa solusi lewat fitur bawaan mereka: next/image. Tapi sebelum kita bahas teknisnya, kita pakai analogi dulu ya biar lebih kebayang.

Bayangin kamu lagi liburan ke luar kota dan harus bawa koper. Kamu punya dua pilihan: bawa semua baju, sepatu, dan perlengkapan tanpa disortir—pokoknya semua masuk koper, berat banget. Atau, kamu pilah-pilah, bawa yang penting aja, gulung baju biar hemat tempat, dan pakai koper ringan. Jelas yang kedua lebih nyaman, kan?

Nah, gambar di website juga gitu. Kalau kamu langsung taruh gambar ukuran besar (misalnya hasil export dari kamera atau Figma tanpa dikompres), browser bakal ‘nyeret koper berat’ setiap kali halaman dibuka. Ini bikin website jadi lambat, terutama di koneksi internet yang biasa-biasa aja.

Next.js punya fitur khusus buat bantu kamu otomatis bawa ‘koper ringan’. Namanya next/image. Dia bantu resize, compress, dan pilih format gambar terbaik otomatis, tergantung device dan koneksi pengguna. Jadi kamu bisa tetap pakai gambar berkualitas tinggi, tanpa bikin loading page jadi lelet.

Sekarang kita masuk ke contoh penggunaannya.


Tanpa Optimasi (pakai tag img biasa):

<img
  src="/images/banner.jpg"
  alt="Banner Website"
  width={1200}
  height={600}
/>

Kalau kamu pakai ini, browser akan langsung download gambar full-size tanpa optimasi apapun. Jadi walaupun user buka lewat HP kecil, tetap aja gambar 1200px itu bakal diload penuh. Boros banget.


Dengan Optimasi (pakai next/image):

import Image from 'next/image';

export default function HeroSection() {
  return (
    <section>
      <h1>Selamat Datang di Website Kami</h1>
      <Image
        src="/images/banner.jpg"
        alt="Banner Website"
        width={1200}
        height={600}
        priority
      />
    </section>
  );
}

Saat kamu pakai komponen Image dari Next.js:

  • Gambar akan otomatis dikompres dan disesuaikan dengan ukuran layar user.
  • Gambar hanya diload saat muncul di viewport (lazy loading otomatis).
  • Bisa pakai format gambar modern seperti WebP kalau browser mendukung.
  • Kecepatan website meningkat tanpa kamu harus pakai tool optimasi gambar terpisah.

Kamu juga bisa kasih style langsung ke gambarnya, dan bahkan atur layout atau fit-nya:

<Image
  src="/images/profile.jpg"
  alt="Foto Profil"
  width={200}
  height={200}
  style={{ borderRadius: '100%' }}
/>


Jadi intinya, gambar itu penting banget buat branding dan desain, tapi kalau gak dioptimasi, dia bisa jadi beban paling besar buat website kamu. Dengan next/image, kamu kayak punya asisten pribadi yang bantu packing gambar-gambar kamu biar tetap kece, tapi ringan buat dibawa ke mana-mana.

Mulai sekarang, coba deh ubah semua <img> biasa kamu jadi <Image> dari Next.js. Rasain bedanya waktu loading halaman. Website jadi lebih cepat, pengunjung pun lebih betah.

Ngomongin Data di Next.js: API Routes vs Data Fetching — Simpelnya Kayak Masak Sendiri atau Delivery

Waktu kamu bikin website pakai Next.js, kamu pasti butuh ngambil data dari suatu tempat. Bisa dari database, dari API lain, atau dari file lokal. Nah, gimana cara ngelola dan nampilin data ini tergantung kamu pakai sistem routing yang mana—Pages Router atau App Router.

Tapi sebelum nyemplung ke teknis, yuk kita pakai analogi yang gampang dulu.

Bayangin kamu lagi lapar. Kamu punya dua pilihan buat dapet makanan:

  • Pertama, kamu masak sendiri di dapur rumah. Kamu yang kontrol semua bahan, waktu masak, dan rasa. Ini mirip kayak bikin API Routes di Pages Router—kamu bikin sendiri endpoint-nya, kamu atur prosesnya, dan kamu bisa kasih data sesuai kebutuhan.
  • Kedua, kamu order makanan dari luar, tinggal buka aplikasi, pilih menu, dan tunggu makanan diantar. Ini mirip banget sama fitur Data Fetching di App Router. Kamu tinggal bilang “saya butuh data ini”, dan Next.js bantu ambilin dan siapin langsung sebelum halaman ditampilkan.

Kedua metode ini sama-sama valid, tinggal tergantung kebutuhan kamu dan sistem routing yang kamu pakai.


Kalau pakai Pages Router: kamu bikin API sendiri pakai API Routes

Contoh bikin endpoint /api/products yang return data produk:

// pages/api/products.ts

import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  const products = [
    { id: 1, name: 'T-Shirt', price: 150000 },
    { id: 2, name: 'Jacket', price: 300000 },
  ];

  res.status(200).json(products);
}

Endpoint ini bisa kamu akses lewat fetch:

// pages/products.tsx
import { useEffect, useState } from 'react';

export default function ProductPage() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    fetch('/api/products')
      .then((res) => res.json())
      .then((data) => setProducts(data));
  }, []);

  return (
    <main>
      <h1>Daftar Produk</h1>
      {products.map((item) => (
        <div key={item.id}>
          <p>{item.name} - Rp {item.price}</p>
        </div>
      ))}
    </main>
  );
}


Kalau pakai App Router: kamu langsung fetch data di server pakai async function

Misalnya kamu mau ambil data produk di halaman /products:

// app/products/page.tsx

async function getProducts() {
  const res = await fetch('<https://fakestoreapi.com/products>', {
    next: { revalidate: 60 }, // ini ISR biar bisa cache dan update tiap 60 detik
  });

  return res.json();
}

export default async function ProductPage() {
  const products = await getProducts();

  return (
    <main>
      <h1>Daftar Produk</h1>
      {products.map((item: any) => (
        <div key={item.id}>
          <p>{item.title}</p>
          <p>Rp {item.price}</p>
        </div>
      ))}
    </main>
  );
}

Di sini, semua data diambil sebelum halaman ditampilkan ke user, karena function page.tsx bersifat async dan bisa langsung fetch data saat render di server.


Jadi intinya, kamu bisa pilih:

  • Kalau kamu pakai Pages Router, kamu bisa bikin dapur sendiri (API Routes) dan fetch data manual dari client side.
  • Kalau kamu pakai App Router, kamu tinggal ambil data langsung di server (Data Fetching di page.tsx) kayak order makanan, udah siap saji.

Dua-duanya fleksibel dan bisa disesuaikan sesuai skenario. Yang penting kamu ngerti perbedaan mindset-nya: Pages Router lebih seperti kamu handle semuanya manual, sedangkan App Router kasih kamu tools biar proses ambil data terasa lebih “server-aware” dan efisien.

Static vs Dynamic Rendering di Next.js — Ibarat Masak Nasi Bungkus vs Nasi Goreng Dadakan

Ketika kamu bangun website dengan Next.js, kamu akan sering ketemu dua istilah penting ini: Static Rendering dan Dynamic Rendering. Kalau gak ngerti bedanya, bisa-bisa kamu bikin halaman yang lambat padahal harusnya bisa ngebut. Tapi jangan khawatir—kita bahas dengan cara santai biar gak bikin pusing.

Bayangin kamu lagi jualan makanan.

Static Rendering itu kayak kamu udah nyiapin nasi bungkus dari pagi. Semua lauk, nasi, sambel udah dikemas rapi di kotak, tinggal kamu kasih ke pelanggan yang datang. Cepat banget, gak ada proses masak ulang. Jadi cocok buat menu yang sama persis buat semua orang, dan gak perlu perubahan tergantung siapa yang beli. Nah, di Next.js, ini mirip banget sama Static Site Generation (SSG)—halaman udah diproses dan disimpan sebagai HTML siap pakai.

Sebaliknya, Dynamic Rendering itu kayak kamu masak nasi goreng dadakan. Pas pelanggan datang dan bilang "saya mau nasi goreng level 3 pedesnya", barulah kamu masak di tempat. Gak bisa disiapin dari awal, karena harus disesuaikan sama permintaan masing-masing. Nah, ini mirip dengan Server Side Rendering (SSR) di Next.js—halaman baru dirender di server saat ada request masuk, dan bisa menyesuaikan isinya sesuai data user, query, atau kondisi tertentu.


Contoh Static Rendering (dengan data tetap):

Misalnya kamu mau bikin halaman list artikel yang jarang berubah.

// app/blog/page.tsx

async function getArticles() {
  const res = await fetch('<https://example.com/api/articles>', {
    next: { revalidate: 3600 }, // revalidate tiap 1 jam
  });
  return res.json();
}

export default async function BlogPage() {
  const articles = await getArticles();

  return (
    <main>
      <h1>Artikel Terbaru</h1>
      {articles.map((item: any) => (
        <article key={item.id}>
          <h2>{item.title}</h2>
          <p>{item.summary}</p>
        </article>
      ))}
    </main>
  );
}

Halaman ini akan dirender sekali di server, lalu disimpan sebagai HTML statis. Selama satu jam ke depan, semua pengunjung akan dapat versi yang sama, dan baru akan diperbarui setelah masa revalidasi habis.


Contoh Dynamic Rendering (buat data real-time atau personalized):

Misalnya kamu bikin halaman profil user yang harus menampilkan nama berdasarkan login mereka.

// app/profile/page.tsx

import { cookies } from 'next/headers';

export default async function ProfilePage() {
  const cookieStore = cookies();
  const userId = cookieStore.get('user_id')?.value;

  const res = await fetch(`https://example.com/api/users/${userId}`, {
    cache: 'no-store', // jangan cache, selalu ambil fresh
  });
  const user = await res.json();

  return (
    <main>
      <h1>Halo, {user.name}!</h1>
      <p>Selamat datang kembali ke dashboard kamu.</p>
    </main>
  );
}

Karena kontennya tergantung siapa yang login, halaman ini dirender secara dinamis di server tiap kali ada request baru. Cocok buat data yang berubah terus atau yang sifatnya personal.


Jadi, kesimpulannya:

  • Static Rendering = nasi bungkus siap santap, cepat dan efisien, cocok untuk konten tetap.
  • Dynamic Rendering = masak dadakan di tempat, fleksibel dan personal, cocok buat konten yang berubah-ubah atau tergantung user.

Pilih yang paling sesuai sama kebutuhan halaman kamu. Jangan semua dipaksain dinamis, nanti performa jeblok. Tapi jangan juga semua diset statis, nanti data pentingnya malah gak update.

Dengan Next.js, kamu punya kuasa buat atur strategi render sesuai kebutuhan — dan itu salah satu kekuatan terbesarnya.

Ngerti Environment Variables di Next.js — Kayak Punya Catatan Rahasia di Saku Celana

Kalau kamu udah mulai serius ngoding project Next.js, pasti bakal nemu istilah Environment Variables atau sering disebut env. Biar gak bingung, kita bahas ini dulu dengan analogi santai.

Bayangin kamu lagi kerja di sebuah restoran. Nah, ada resep khusus yang cuma boleh diketahui oleh koki. Gak boleh ditulis di papan menu, gak boleh dikasih ke tamu. Tapi resep itu penting banget biar rasa makanannya konsisten, dan restoran tetap bisa jalan. Resep rahasia itu disimpan di saku celana koki, jadi cuma dia yang bisa lihat dan pakai pas masak.

Nah, environment variables itu kayak catatan rahasia di saku developer. Informasi yang penting banget, tapi gak boleh ditaruh langsung di dalam kode. Misalnya: API key, database password, base URL API, secret token, dan lain-lain.

Kenapa harus disembunyiin? Karena kalau kamu simpen langsung di file kode dan ternyata project-nya ke-push ke GitHub atau di-deploy ke server publik, orang lain bisa aja lihat informasi sensitif itu. Bahaya banget, bro.

Makanya Next.js punya cara khusus buat nyimpen dan akses environment variable lewat file .env.local.


Langkah pertama: bikin file .env.local di root project

NEXT_PUBLIC_API_URL=https://api.example.com
SECRET_TOKEN_SERVER=super-secret-token-123

Ada dua hal yang penting di sini:

  • Variabel yang diawali dengan NEXT_PUBLIC_ akan bisa diakses dari browser/client.
  • Variabel tanpa NEXT_PUBLIC_ hanya bisa diakses di server, jadi aman dari paparan publik.

Contoh penggunaan di client component:

'use client'

export default function ShowApiUrl() {
  return (
    <div>
      <p>Base URL API kamu: {process.env.NEXT_PUBLIC_API_URL}</p>
    </div>
  );
}

Hasilnya nanti akan tampil: Base URL API kamu: <https://api.example.com>

Karena variabel ini punya awalan NEXT_PUBLIC_, maka bisa digunakan langsung di komponen React yang berjalan di browser.


Contoh penggunaan di server (tanpa diekspose):

// app/api/hello/route.ts

export async function GET() {
  const token = process.env.SECRET_TOKEN_SERVER;

  return Response.json({
    message: 'Token berhasil digunakan di server',
    tokenUsed: token,
  });
}

Di sini, SECRET_TOKEN_SERVER tidak akan pernah muncul di client, tapi bisa kamu pakai untuk kirim request ke API yang butuh authentication, selama itu dilakukan di server.


Hal penting yang perlu kamu tahu juga:

  • File .env.local tidak akan pernah ikut ke-push ke GitHub kalau kamu pakai .gitignore dengan benar.
  • Kamu bisa punya beberapa file env berbeda, seperti .env.production atau .env.development, tergantung environment project kamu dijalankan.

Jadi kesimpulannya: Environment variables itu catatan rahasia penting yang disimpan di luar kode, tapi bisa kamu pakai kapan aja pas dibutuhin. Dengan ngatur ini dengan benar, project kamu jadi lebih aman, fleksibel, dan gampang dipindah-pindahin ke environment lain tanpa harus ubah banyak file.

Deployment ke Vercel — Ibarat Buka Toko di Mall yang Udah Disediain Semua Fasilitasnya

Setelah kamu selesai bikin website pakai Next.js, pertanyaan selanjutnya pasti: “Gimana caranya biar website-nya bisa diakses banyak orang dari mana aja?” Nah, inilah saatnya kamu masuk ke tahap deployment.

Biar gampang dipahami, kita pakai analogi yang relate banget.

Bayangin kamu baru selesai desain interior toko impian kamu. Udah rapi, produk siap, banner udah digantung. Tapi toko kamu masih di dalam garasi rumah—gak ada yang bisa lihat, gak ada yang lewat, gak ada pelanggan. Nah, deployment itu ibarat kamu mindahin toko dari garasi ke dalam mall besar. Di mall, ada pengunjung, sistem keamanan, listrik stabil, dan bahkan staff kebersihan.

Vercel itu mall-nya.

Kenapa Vercel jadi pilihan favorit buat deploy Next.js? Karena Vercel tuh dibuat langsung sama tim yang bikin Next.js, jadi udah sangat cocok dan seamless banget. Semua proses build dan hosting-nya udah diaturin. Kamu tinggal dorong project kamu dan... boom, website kamu langsung bisa diakses lewat internet dengan domain yang cantik.


Langkah deployment ke Vercel:

  1. Push project kamu ke GitHub (atau GitLab, atau Bitbucket).
  2. Buka https://vercel.com dan login (bisa pakai akun GitHub).
  3. Klik tombol “New Project”, terus pilih repo project Next.js kamu.
  4. Tinggal klik deploy. Dalam beberapa detik, Vercel akan otomatis:
    • install dependency
    • build project
    • host semua file
    • dan kasih kamu URL online

Contoh hasil build otomatis di Vercel (gak perlu ditulis sendiri):

Vercel akan membaca next.config.js, package.json, dan struktur folder kamu, lalu jalankan:

npm install
npm run build
npm start

Semua itu dikerjakan otomatis di server mereka.


Bonus: Tambahin file vercel.json kalau mau custom

{
  "rewrites": [
    {
      "source": "/old-route",
      "destination": "/new-route"
    }
  ]
}

Ini misalnya kamu mau redirect atau rewrite URL, tinggal atur aja lewat file vercel.json.


Apa yang kamu dapet setelah deploy ke Vercel?

  • Website kamu bisa langsung diakses dengan URL seperti https://nama-project.vercel.app
  • Setiap kali kamu update kode di GitHub, Vercel otomatis build dan deploy versi terbaru
  • Bisa custom domain, misalnya jadi www.websitemu.com
  • Gratis buat project skala kecil sampai menengah
  • Bisa pantau performa, log error, dan analitik langsung dari dashboard Vercel

Jadi kalau dibilang singkat: kamu cukup bikin project, dorong ke GitHub, terus klik deploy di Vercel. Tanpa setup ribet, tanpa mikirin server, tanpa harus ngerti networking.

Dengan Vercel, kamu tinggal fokus bikin konten dan fitur keren. Urusan buka tokonya? Udah disiapin sama mall premium-nya si Vercel.

Penutup: 10 Hal Penting Sudah Kamu Pelajari, Saatnya Naik Level Bareng Mentor Expert

Nah, sampai di sini kamu udah berhasil ngelewatin 10 hal penting yang wajib banget dipahami pemula saat belajar Next.js. Mulai dari cara kerja routing, bedain client dan server components, paham layout, optimasi gambar, sampai cara deploy ke Vercel — semua udah kamu lalui dengan analogi yang mudah dicerna dan contoh kode yang bisa langsung dipraktikkan.

Tapi jangan berhenti di sini ya. Belajar Next.js itu gak cukup cuma teori doang, apalagi kalau tujuan akhirnya pengen bikin website profesional, masuk ke dunia kerja, atau bahkan jadi freelance developer yang bisa dapetin klien dari luar negeri.

Kalau kamu pengen belajar lebih terarah, punya mentor yang bisa bantu review hasil kerja kamu, dan akses ke komunitas yang supportif banget — kamu bisa lanjut belajar bareng mentor expert di BuildWithAngga.

Di BuildWithAngga, kamu gak cuma dapat video pembelajaran, tapi juga:

  • Project real-world yang bisa kamu masukin ke portfolio
  • Sertifikat resmi buat nunjukin skill kamu ke HRD dan klien
  • Akses selamanya ke semua materi kelas
  • Forum diskusi langsung bareng mentor dan murid lainnya
  • Tips karier buat persiapan kerja remote, freelance, atau startup

Jadi daripada kamu belajar sendiri dan muter-muter gak jelas, mending langsung dapet arahan dari yang udah berpengalaman.

Next.js udah jadi langkah awal yang bagus. Sekarang waktunya kamu leveling up.

Belajar lebih dalam, bikin project lebih keren, dan raih karier impian bareng BuildWithAngga 🚀💼

Siap lanjut ke tahap selanjutnya? Yuk gabung sekarang!