ngodingdulu
Web & DatabaseTutorialPemula

JavaScript Modern untuk Pemula: dari Dasar ke DOM

Dasar-dasar JavaScript yang benar-benar dipakai hari ini, langsung dipraktikkan untuk membuat halaman dengan pencarian dan keranjang belanja.

Oleh Afa Hernandes15 menit baca

Daftar isi

HTML menentukan isi halaman dan CSS menentukan tampilannya, tapi halaman yang hanya berisi keduanya tidak bisa merespons apa pun. Tombol yang menambah pesanan, kolom pencarian yang langsung menyaring hasil, atau data yang dimuat tanpa memuat ulang halaman, semuanya dikerjakan oleh JavaScript.

Di tutorial ini kamu akan mempelajari dasar JavaScript modern yang benar-benar dipakai hari ini, lalu langsung memakainya untuk membuat halaman menu Kopi Senja dengan pencarian dan keranjang belanja. Datanya dimuat dari file JSON, seperti aplikasi sungguhan yang mengambil data dari server.

Sebelum mulai

  • Paham dasar logika: variabel, percabangan, perulangan, dan function. Contoh di jalur Mulai Ngoding memakai Python, tapi konsepnya sama.
  • Sudah membaca Flexbox dan Grid. Halaman di tutorial ini memakai tampilan yang mirip.
  • Node.js versi LTS dari nodejs.org. Node dipakai untuk menjalankan contoh kode di terminal dan menyalakan server lokal.
  • Diuji dengan Node 24 dan Chrome.

Cek instalasi Node di terminal:

Terminal
node -v

Kalau muncul nomor versi (misalnya v24.22.0), Node siap dipakai.

Dua tempat menjalankan JavaScript

JavaScript bisa berjalan di dua tempat:

  • Browser. Tekan F12 di Chrome, buka tab Console, lalu ketik 1 + 2 dan tekan Enter. Di sini juga semua pesan error halamanmu muncul, jadi biasakan membukanya.
  • Node.js. Simpan kode di file .js, lalu jalankan dengan node nama-file.js di terminal. Cara ini yang dipakai untuk contoh-contoh dasar di bawah.

Variabel: const dan let

dasar.js
const namaKedai = "Kopi Senja";
let jumlahPesanan = 0;
jumlahPesanan = jumlahPesanan + 1;
console.log(`${namaKedai}: ${jumlahPesanan} pesanan`);
Output
Kopi Senja: 1 pesanan
  • const untuk nilai yang tidak akan diganti. Pakai ini sebagai pilihan pertama.
  • let untuk nilai yang memang akan berubah, seperti penghitung.
  • console.log() mencetak nilai, sama seperti print() di Python.

Kalau kamu mencoba mengganti nilai const, JavaScript langsung menolak:

const.js
const pajak = 0.11;
pajak = 0.12;
Output
TypeError: Assignment to constant variable.

Di tutorial lama kamu akan menemukan var. Hindari: var punya aturan cakupan (scope) yang membingungkan dan sudah digantikan oleh const dan let.

Baris terakhir di dasar.js memakai template literal: teks yang diapit tanda backtick (`), bukan kutip biasa. Nilai variabel disisipkan dengan ${…}, mirip f-string di Python.

Function dan arrow function

fungsi.js
function formatRupiah(nilai) {
return "Rp" + nilai.toLocaleString("id-ID");
}
const tambahPajak = (harga) => Math.round(harga * 1.11);
console.log(formatRupiah(18000));
console.log(formatRupiah(tambahPajak(18000)));
Output
Rp18.000
Rp19.980

tambahPajak ditulis sebagai arrow function: parameter, tanda =>, lalu hasilnya. Kalau isinya hanya satu ekspresi, kata return dan kurung kurawal boleh dihilangkan. Bentuk ini sangat sering dipakai sebagai function kecil yang dioper ke function lain, seperti di bagian berikutnya.

toLocaleString("id-ID") memformat angka sesuai aturan Indonesia, dengan titik sebagai pemisah ribuan.

Array dan method yang paling sering dipakai

Data di aplikasi web hampir selalu berbentuk array berisi object: daftar produk, daftar pesanan, daftar pengguna.

array.js
const menu = [
{ id: 1, nama: "Kopi susu", harga: 18000, kategori: "kopi" },
{ id: 2, nama: "Americano", harga: 15000, kategori: "kopi" },
{ id: 3, nama: "Matcha latte", harga: 22000, kategori: "non-kopi" },
{ id: 4, nama: "Croissant", harga: 25000, kategori: "makanan" },
];
const namaSaja = menu.map((item) => item.nama);
const kopi = menu.filter((item) => item.kategori === "kopi");
const croissant = menu.find((item) => item.id === 4);
const totalSemua = menu.reduce((total, item) => total + item.harga, 0);
console.log(namaSaja);
console.log(kopi.length, "menu kopi");
console.log(croissant.nama);
console.log(totalSemua);
Output
[ 'Kopi susu', 'Americano', 'Matcha latte', 'Croissant' ]
2 menu kopi
Croissant
80000
Method Fungsinya Hasilnya
map mengubah setiap item array baru, jumlahnya sama
filter menyaring item yang memenuhi syarat array baru, bisa lebih sedikit
find mencari item pertama yang cocok satu item, atau undefined kalau tidak ada
reduce menggabungkan semua item jadi satu nilai satu nilai, misalnya total

Keempatnya menerima function sebagai argumen, dan di situlah arrow function dipakai. Perhatikan juga ===: di JavaScript, selalu pakai tiga tanda sama dengan untuk membandingkan. == (dua tanda) diam-diam mengubah tipe data, sehingga "1" == 1 dianggap benar.

Object: destructuring, spread, dan nilai kosong

objek.js
const produk = { nama: "Kopi susu", harga: 18000, stok: 0 };
const { nama, harga } = produk;
console.log(nama, harga);
const produkDiskon = { ...produk, harga: 15000 };
console.log(produkDiskon);
console.log(produk.harga);
const pelanggan = { nama: "Sari" };
console.log(pelanggan.alamat?.kota);
console.log(pelanggan.alamat?.kota ?? "Alamat belum diisi");
console.log(produk.stok || "Stok tidak diketahui");
console.log(produk.stok ?? "Stok tidak diketahui");
Output
Kopi susu 18000
{ nama: 'Kopi susu', harga: 15000, stok: 0 }
18000
undefined
Alamat belum diisi
Stok tidak diketahui
0
  • Destructuring (const { nama, harga } = produk) mengambil beberapa properti sekaligus ke variabel dengan nama yang sama.
  • Spread ({ ...produk, harga: 15000 }) menyalin semua properti ke object baru, lalu menimpa yang perlu diubah. Object aslinya tidak berubah, terlihat dari produk.harga yang tetap 18000.
  • Optional chaining (?.) mencegah error saat properti di tengahnya tidak ada. Tanpa ?., pelanggan.alamat.kota langsung error karena alamat tidak ada.
  • Nullish coalescing (??) memberi nilai cadangan hanya kalau nilainya null atau undefined.

Dua baris terakhir menunjukkan bedanya dengan ||. Stok 0 adalah data yang sah (barangnya habis), tapi || menganggap 0 sama dengan “kosong” lalu menggantinya. ?? tidak melakukan itu, jadi lebih aman untuk angka.

Sekarang saatnya memakai semua ini di halaman sungguhan.

Langkah 1: Siapkan halaman

Buat folder menu-kopi berisi empat file. Pertama, HTML-nya:

menu-kopi/index.html
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Menu Kopi Senja</title>
<link rel="stylesheet" href="style.css">
<script type="module" src="app.js"></script>
</head>
<body>
<main class="menu">
<h1>Menu Kopi Senja</h1>
<label class="search">
Cari menu
<input id="cari" type="search" placeholder="mis. latte" autocomplete="off">
</label>
<p id="status" class="status">Memuat menu…</p>
<div id="daftar-menu" class="card-grid"></div>
<aside class="keranjang">
<h2>Pesananmu</h2>
<ul id="isi-keranjang"></ul>
<p class="total">Total: <strong id="total">Rp0</strong></p>
</aside>
</main>
</body>
</html>

Daftar menunya sengaja kosong (<div id="daftar-menu">). Isinya nanti dibuat oleh JavaScript dari data.

<script type="module"> memuat app.js sebagai module. Module JavaScript otomatis dijalankan setelah seluruh HTML selesai dibaca, jadi kodenya aman mencari elemen di halaman. Module juga bisa memakai import dan export untuk memecah kode ke beberapa file.

Lalu datanya, dalam format JSON (JavaScript Object Notation), format yang juga dipakai hampir semua API:

menu-kopi/menu.json
[
{ "id": 1, "nama": "Kopi susu", "harga": 18000, "kategori": "kopi" },
{ "id": 2, "nama": "Americano", "harga": 15000, "kategori": "kopi" },
{ "id": 3, "nama": "Matcha latte", "harga": 22000, "kategori": "non-kopi" },
{ "id": 4, "nama": "Croissant", "harga": 25000, "kategori": "makanan" }
]

Dan tampilannya. Tekniknya sama dengan di tutorial Flexbox dan Grid:

menu-kopi/style.css
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.6;
color: #1f2328;
background: #fbf9f6;
}
.menu {
max-width: 1100px;
margin: 0 auto;
padding: 2rem 1.5rem 4rem;
}
.search {
display: flex;
flex-direction: column;
gap: 0.25rem;
max-width: 360px;
margin-bottom: 1rem;
font-weight: 600;
}
.search input {
padding: 0.6rem 0.8rem;
border: 1px solid #d0c4b8;
border-radius: 10px;
font: inherit;
font-weight: 400;
}
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
.card {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1.25rem;
border: 1px solid #e7dfd6;
border-radius: 16px;
background: #fff;
}
.card h3,
.card p {
margin: 0;
}
.card .price {
font-weight: 700;
color: #b45309;
}
.card button {
margin-top: auto;
padding: 0.5rem;
border: 0;
border-radius: 999px;
background: #b45309;
color: #fff;
font: inherit;
font-weight: 600;
cursor: pointer;
}
.keranjang {
margin-top: 2rem;
padding: 1.25rem;
border-radius: 16px;
background: #3b2a20;
color: #f3e3d3;
}
.keranjang h2 {
margin-top: 0;
}
.status:empty {
display: none;
}

Grid di sini memakai auto-fill, bukan auto-fit. Hasil pencarian bisa tinggal satu kartu, dan auto-fill menjaga kartu itu tetap selebar satu kolom, tidak melebar selebar layar.

File keempat, app.js, kita tulis bertahap di langkah berikutnya.

Langkah 2: Ambil elemen dari halaman

Browser menyediakan DOM (Document Object Model): representasi halaman HTML sebagai object yang bisa dibaca dan diubah oleh JavaScript. Langkah pertama hampir selalu sama, yaitu mengambil elemen yang dibutuhkan:

menu-kopi/app.js
const daftarMenu = document.querySelector("#daftar-menu");
const inputCari = document.querySelector("#cari");
const status = document.querySelector("#status");
const isiKeranjang = document.querySelector("#isi-keranjang");
const totalEl = document.querySelector("#total");
let menu = [];
const keranjang = [];
const formatRupiah = (nilai) => "Rp" + nilai.toLocaleString("id-ID");

document.querySelector() menerima selektor CSS, sama persis dengan yang kamu tulis di file CSS: #cari untuk id, .card untuk class. Hasilnya elemen pertama yang cocok, atau null kalau tidak ada.

menu memakai let karena isinya nanti diganti dengan data dari JSON. keranjang memakai const karena array-nya tetap sama. Yang berubah hanya isinya, dan const membolehkan itu.

Langkah 3: Tampilkan kartu menu

menu-kopi/app.js
function buatKartu(item) {
const kartu = document.createElement("article");
kartu.className = "card";
const judul = document.createElement("h3");
judul.textContent = item.nama;
const harga = document.createElement("p");
harga.className = "price";
harga.textContent = formatRupiah(item.harga);
const tombol = document.createElement("button");
tombol.type = "button";
tombol.textContent = "Tambah";
tombol.addEventListener("click", () => tambahKeKeranjang(item));
kartu.append(judul, harga, tombol);
return kartu;
}
function tampilkanMenu(daftar) {
daftarMenu.replaceChildren(...daftar.map(buatKartu));
status.textContent = daftar.length === 0 ? "Menu tidak ditemukan." : "";
}
  • document.createElement() membuat elemen baru, dan append() memasukkannya ke elemen lain.
  • addEventListener("click", …) mendaftarkan function yang dijalankan setiap kali tombol diklik. Inilah cara halaman merespons pengguna.
  • daftar.map(buatKartu) mengubah array data menjadi array elemen, lalu replaceChildren() mengganti seluruh isi daftarMenu dengan elemen-elemen itu. Tanda ... (spread) membuka array-nya menjadi argumen satu per satu.
  • Baris status memakai operator ternary (syarat ? kalauBenar : kalauSalah), bentuk singkat if/else untuk memilih satu dari dua nilai.

Kenapa tidak menulis HTML sebagai teks lewat innerHTML? Karena textContent selalu memperlakukan isinya sebagai teks biasa. Kalau suatu saat nama menu berasal dari input pengguna dan isinya <img src=x onerror="…">, textContent menampilkannya apa adanya sebagai tulisan, sedangkan innerHTML mengubahnya menjadi elemen sungguhan dan menjalankan kode di dalam onerror. Celah ini disebut XSS, dan dibahas lengkap di XSS dan CSRF. Biasakan textContent sejak awal.

Langkah 4: Keranjang belanja

menu-kopi/app.js
function tambahKeKeranjang(item) {
const sudahAda = keranjang.find((baris) => baris.id === item.id);
if (sudahAda) {
sudahAda.jumlah += 1;
} else {
keranjang.push({ ...item, jumlah: 1 });
}
tampilkanKeranjang();
}
function tampilkanKeranjang() {
const baris = keranjang.map((item) => {
const li = document.createElement("li");
li.textContent = `${item.jumlah}x ${item.nama}: ${formatRupiah(item.harga * item.jumlah)}`;
return li;
});
isiKeranjang.replaceChildren(...baris);
const total = keranjang.reduce((jumlah, item) => jumlah + item.harga * item.jumlah, 0);
totalEl.textContent = formatRupiah(total);
}

Semua yang kamu pelajari di bagian dasar dipakai di sini: find mencari apakah menu itu sudah ada di keranjang, spread ({ ...item, jumlah: 1 }) membuat salinan data menu dengan tambahan jumlah, map mengubah isi keranjang jadi baris daftar, dan reduce menghitung totalnya.

Polanya juga patut diingat: ubah datanya dulu, lalu tampilkan ulang dari data. Function tampilkanKeranjang() selalu menggambar ulang keranjang dari array keranjang, sehingga tampilan tidak pernah berbeda dengan datanya. Framework seperti React dan Svelte dibangun di atas ide yang sama.

Langkah 5: Pencarian langsung

menu-kopi/app.js
inputCari.addEventListener("input", () => {
const kata = inputCari.value.trim().toLowerCase();
const hasil = menu.filter((item) => item.nama.toLowerCase().includes(kata));
tampilkanMenu(hasil);
});

Event input terpicu setiap kali isi kolom berubah, jadi hasilnya tersaring sambil kamu mengetik. trim() membuang spasi di awal dan akhir, dan toLowerCase() membuat pencarian tidak membedakan huruf besar-kecil, sehingga mengetik MATCHA tetap menemukan “Matcha latte”.

Langkah 6: Muat data dengan fetch

menu-kopi/app.js
async function muatMenu() {
try {
const respons = await fetch("menu.json");
if (!respons.ok) {
throw new Error(`HTTP ${respons.status}`);
}
menu = await respons.json();
tampilkanMenu(menu);
} catch (error) {
status.textContent = "Menu gagal dimuat. Coba muat ulang halaman.";
console.error(error);
}
}
muatMenu();

fetch() meminta file atau data dari server. Permintaan lewat jaringan butuh waktu, jadi hasilnya tidak langsung ada:

  • async menandai function yang berisi pekerjaan yang perlu ditunggu.
  • await menunggu sampai hasilnya datang, lalu lanjut ke baris berikutnya. Kodenya tetap terbaca dari atas ke bawah.
  • respons.ok bernilai false kalau server menjawab dengan error seperti 404. fetch tidak otomatis gagal untuk status seperti itu, jadi kamu harus memeriksanya sendiri.
  • try/catch menangkap semua kegagalan, baik koneksi putus maupun status error, lalu menampilkan pesan yang jelas untuk pengguna. Detail teknisnya tetap dicatat di Console lewat console.error().

Ganti menu.json dengan alamat API sungguhan, dan kodenya tetap sama. Begitulah aplikasi web mengambil data dari server.

Langkah 7: Jalankan lewat server lokal

Kalau index.html dibuka dengan klik dua kali, menunya tidak akan pernah muncul. Browser memblokir module dan fetch dari alamat file:// demi keamanan. Kamu perlu server lokal. Dari folder menu-kopi, jalankan:

Terminal
npx serve .

npx mengunduh dan menjalankan paket serve tanpa perlu menginstalnya permanen. Saat pertama kali, kamu mungkin diminta konfirmasi (Ok to proceed? (y)); ketik y. Buka alamat yang ditampilkan di terminal, biasanya http://localhost:3000. Hentikan server dengan Ctrl+C.

Kalau kamu memakai VS Code, ekstensi seperti Live Server juga bisa dipakai. Yang penting, alamatnya diawali http://, bukan file://.

Hasil

Klik Tambah di kopi susu dua kali dan di croissant sekali. Keranjang dan totalnya langsung diperbarui:

Halaman Menu Kopi Senja dengan empat kartu menu bertombol Tambah dan kotak Pesananmu berisi 2x Kopi susu Rp36.000, 1x Croissant Rp25.000, total Rp61.000

Ketik latte di kolom pencarian. Hanya Matcha latte yang tersisa, dan isi keranjang tidak hilang:

Hasil pencarian latte: hanya kartu Matcha latte yang tampil selebar satu kolom, keranjang tetap berisi pesanan sebelumnya

Kalau menu.json tidak ditemukan, halaman menampilkan “Menu gagal dimuat. Coba muat ulang halaman.” dan Console mencatat Error: HTTP 404. Semua perilaku ini sudah diuji di Chrome.

Kode JavaScript lengkap

menu-kopi/app.js
const daftarMenu = document.querySelector("#daftar-menu");
const inputCari = document.querySelector("#cari");
const status = document.querySelector("#status");
const isiKeranjang = document.querySelector("#isi-keranjang");
const totalEl = document.querySelector("#total");
let menu = [];
const keranjang = [];
const formatRupiah = (nilai) => "Rp" + nilai.toLocaleString("id-ID");
function buatKartu(item) {
const kartu = document.createElement("article");
kartu.className = "card";
const judul = document.createElement("h3");
judul.textContent = item.nama;
const harga = document.createElement("p");
harga.className = "price";
harga.textContent = formatRupiah(item.harga);
const tombol = document.createElement("button");
tombol.type = "button";
tombol.textContent = "Tambah";
tombol.addEventListener("click", () => tambahKeKeranjang(item));
kartu.append(judul, harga, tombol);
return kartu;
}
function tampilkanMenu(daftar) {
daftarMenu.replaceChildren(...daftar.map(buatKartu));
status.textContent = daftar.length === 0 ? "Menu tidak ditemukan." : "";
}
function tambahKeKeranjang(item) {
const sudahAda = keranjang.find((baris) => baris.id === item.id);
if (sudahAda) {
sudahAda.jumlah += 1;
} else {
keranjang.push({ ...item, jumlah: 1 });
}
tampilkanKeranjang();
}
function tampilkanKeranjang() {
const baris = keranjang.map((item) => {
const li = document.createElement("li");
li.textContent = `${item.jumlah}x ${item.nama}: ${formatRupiah(item.harga * item.jumlah)}`;
return li;
});
isiKeranjang.replaceChildren(...baris);
const total = keranjang.reduce((jumlah, item) => jumlah + item.harga * item.jumlah, 0);
totalEl.textContent = formatRupiah(total);
}
inputCari.addEventListener("input", () => {
const kata = inputCari.value.trim().toLowerCase();
const hasil = menu.filter((item) => item.nama.toLowerCase().includes(kata));
tampilkanMenu(hasil);
});
async function muatMenu() {
try {
const respons = await fetch("menu.json");
if (!respons.ok) {
throw new Error(`HTTP ${respons.status}`);
}
menu = await respons.json();
tampilkanMenu(menu);
} catch (error) {
status.textContent = "Menu gagal dimuat. Coba muat ulang halaman.";
console.error(error);
}
}
muatMenu();

Error yang sering muncul

Semua pesan di bawah muncul di tab Console DevTools (F12).

Access to script at ‘file:///…/app.js’ from origin ‘null’ has been blocked by CORS policy

Halaman dibuka langsung dari file (alamatnya diawali file://). Browser tidak mengizinkan module dimuat dari sana. Jalankan lewat server lokal seperti di Langkah 7.

TypeError: Cannot read properties of null (reading ‘addEventListener’)

querySelector() tidak menemukan elemennya, sehingga hasilnya null. Periksa apakah selektornya sama persis dengan id di HTML (#cari untuk id="cari", termasuk huruf besar-kecilnya). Kalau kamu memakai <script> biasa tanpa type="module" di dalam <head>, skripnya berjalan sebelum elemennya ada. Tambahkan type="module" atau defer.

TypeError: Assignment to constant variable.

Kamu mengganti nilai variabel yang dibuat dengan const. Kalau nilainya memang perlu berubah, ganti dengan let.

Error: HTTP 404

Pesan dari kode kita sendiri: fetch tidak menemukan menu.json. Pastikan nama file dan letaknya benar, satu folder dengan index.html.

Total menjadi NaN atau angkanya menyambung, misalnya 1800018000.

Harganya terbaca sebagai teks, bukan angka. Ini sering terjadi pada nilai dari <input>, yang selalu berupa teks. Ubah dulu dengan Number(nilai) sebelum dihitung. Kesalahan seperti ini bisa ditangkap otomatis oleh TypeScript.

Langkah berikutnya: rilis dan amankan

Halaman ini tetap statis: hanya file HTML, CSS, JavaScript, dan JSON, tanpa backend. Artinya bisa langsung online gratis lewat deploy pertama ke Cloudflare Pages. Unggah folder menu-kopi, lalu fitur pencarian dan keranjangnya berjalan sama seperti di laptop.

Dua hal keamanan yang perlu diingat sejak sekarang:

  • Semua kode JavaScript di browser bisa dibaca siapa saja lewat DevTools. Jangan pernah menaruh API key, password, atau data rahasia di dalamnya. Caranya ada di environment variable dan secrets.
  • Pengguna bisa mengubah apa pun yang terjadi di browser, termasuk harga di keranjang. Di aplikasi sungguhan, total belanja harus dihitung ulang di server, bukan dipercaya dari browser.

Pertanyaan yang sering diajukan

JavaScript dan Java itu sama?

Tidak. Keduanya bahasa yang berbeda, dengan cara kerja dan kegunaan yang berbeda. Kemiripan namanya hanya urusan sejarah pemasaran.

Perlu belajar jQuery?

Tidak untuk proyek baru. Banyak fitur yang dulu menjadi alasan memakai jQuery, seperti memilih elemen dan mengambil data, sekarang sudah ada langsung di browser lewat querySelector dan fetch. Kamu cukup bisa membacanya kalau menemukannya di proyek lama.

Titik koma di akhir baris wajib?

Secara teknis JavaScript bisa menambahkannya sendiri, tapi ada beberapa kasus yang hasilnya mengejutkan. Pilih satu gaya dan pakai konsisten. Kode di tutorial ini selalu memakai titik koma.

Kapan saya mulai belajar framework seperti React?

Setelah kamu nyaman dengan semua yang ada di tutorial ini: array method, DOM, event, dan fetch. Framework mengotomatiskan pola “ubah data, lalu tampilkan ulang” dari Langkah 4, dan jauh lebih mudah dipahami kalau kamu sudah pernah melakukannya secara manual.

Kesimpulan

JavaScript modern cukup dikuasai dari beberapa hal: const dan let, arrow function, map/filter/find/reduce, object dengan spread dan ??, DOM dan event, serta fetch dengan async/await. Dengan itu kamu sudah membuat halaman yang memuat data, merespons klik, dan menyaring hasil secara langsung.

Kamu mungkin sudah merasakan satu kelemahannya: JavaScript baru memberi tahu kesalahan saat program dijalankan. Langkah berikutnya di jalur Web Developer Modern, TypeScript, menangkap banyak kesalahan itu sebelum kode dijalankan.

Bagikan:WhatsAppTelegramXFacebook
Ilustrasi jendela browser berisi tiga tahap belajar web: fondasi, komponen dan framework, lalu full-stack, diakhiri bendera online
WebRoadmap

Roadmap Web Developer 2026 untuk Pemula

Tiga level berurutan, dari halaman HTML pertama sampai aplikasi full-stack yang online. Lengkap dengan urutan belajar dan tanda kapan kamu siap naik level.

23 Oktober 20266 mnt

Ilustrasi dua kartu bersebelahan: kartu kiri berisi daftar alat lama seperti XAMPP, mysql_query, jQuery, dan FTP, kartu kanan berisi padanan modernnya seperti PHP 8, prepared statement, fetch, dan git push
WebKonsep

Apa yang Berubah di Dunia Web Sejak Era XAMPP

Kalau terakhir ngoding web dengan XAMPP, PHP native, jQuery, dan FTP, ini peta yang berubah, yang tetap sama, dan urutan mengejarnya tanpa membuang pengalamanmu.

6 November 202610 mnt

Enter bukaEsc tutupHalaman pencarian