Di SvelteKit, file +layout.svelte dipakai untuk membungkus halaman-halaman di dalam suatu segmen route. Konsep ini penting karena banyak aplikasi web memiliki elemen antarmuka yang berulang, seperti navbar, sidebar, footer, atau pembungkus konten dengan gaya tertentu. Daripada menyalin markup yang sama ke setiap halaman, kita bisa menaruhnya di layout agar lebih rapi, mudah dirawat, dan konsisten.

Artikel ini fokus pada praktik langsung membuat layout global untuk seluruh aplikasi dan nested layout untuk area blog. Contoh yang dipakai sederhana tetapi realistis: ada navbar, footer, slot konten, dan pemisahan tampilan khusus untuk route /blog. Semua contoh bisa langsung dicoba di proyek SvelteKit.

Memahami peran +layout.svelte di SvelteKit

Secara umum, +layout.svelte akan membungkus semua halaman di folder yang sama dan semua turunannya. Artinya, bila Anda membuat file src/routes/+layout.svelte, maka layout tersebut berlaku global untuk hampir seluruh route aplikasi. Jika Anda membuat file src/routes/blog/+layout.svelte, layout itu hanya berlaku untuk route di bawah /blog.

Dengan pola ini, SvelteKit memudahkan Anda memisahkan tampilan berdasarkan area aplikasi. Contohnya:

  • Layout global untuk header, footer, tema dasar, dan container utama.
  • Nested layout untuk bagian tertentu seperti blog, dashboard, admin, atau akun pengguna.

Kapan memakainya?

  • Gunakan layout global saat elemen UI muncul di hampir semua halaman.
  • Gunakan nested layout saat hanya sebagian route yang butuh struktur atau tampilan khusus.

Catatan: Di SvelteKit modern, konten halaman anak biasanya dirender melalui properti children dengan tag {@render children()}. Jika Anda menemukan dokumentasi lama yang memakai <slot />, pahami bahwa itu berasal dari pola versi sebelumnya.

Struktur folder yang akan digunakan

Berikut struktur folder sederhana untuk contoh artikel ini:

src/
├── lib/
│   └── components/
│       ├── Navbar.svelte
│       └── Footer.svelte
└── routes/
    ├── +layout.svelte
    ├── +page.svelte
    ├── about/
    │   └── +page.svelte
    └── blog/
        ├── +layout.svelte
        ├── +page.svelte
        └── [slug]/
            └── +page.svelte

Penjelasannya:

  • src/routes/+layout.svelte adalah layout global.
  • src/routes/+page.svelte adalah halaman beranda.
  • src/routes/about/+page.svelte adalah halaman biasa yang tetap memakai layout global.
  • src/routes/blog/+layout.svelte adalah nested layout khusus area blog.
  • src/routes/blog/+page.svelte adalah halaman indeks blog.
  • src/routes/blog/[slug]/+page.svelte adalah detail artikel blog.

Membuat komponen Navbar dan Footer

Supaya layout global lebih bersih, sebaiknya navbar dan footer dipisah menjadi komponen. Simpan komponen berikut di src/lib/components.

Komponen Navbar

<!-- src/lib/components/Navbar.svelte -->
<nav class="navbar">
  <div class="container">
    <a href="/" class="brand">MySvelteApp</a>

    <div class="links">
      <a href="/">Home</a>
      <a href="/about">About</a>
      <a href="/blog">Blog</a>
    </div>
  </div>
</nav>

<style>
  .navbar {
    background: #1e293b;
    color: white;
    padding: 1rem 0;
  }

  .container {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .brand {
    color: white;
    text-decoration: none;
    font-weight: 700;
  }

  .links {
    display: flex;
    gap: 1rem;
  }

  .links a {
    color: white;
    text-decoration: none;
  }
</style>

Komponen Footer

<!-- src/lib/components/Footer.svelte -->
<footer class="footer">
  <div class="container">
    <p>© 2026 MySvelteApp. Dibangun dengan SvelteKit.</p>
  </div>
</footer>

<style>
  .footer {
    background: #0f172a;
    color: #cbd5e1;
    padding: 1.5rem 0;
    margin-top: 2rem;
  }

  .container {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 1rem;
  }
</style>

Pemisahan seperti ini membantu karena layout tidak penuh dengan detail markup. Selain itu, Navbar dan Footer bisa dipakai ulang jika nanti Anda memerlukan variasi layout lain.

Membuat layout global dengan +layout.svelte

Sekarang buat file src/routes/+layout.svelte. Layout ini akan menjadi pembungkus utama seluruh halaman.

<!-- src/routes/+layout.svelte -->
<script>
  import Navbar from '$lib/components/Navbar.svelte';
  import Footer from '$lib/components/Footer.svelte';

  let { children } = $props();
</script>

<Navbar />

<main class="page-container">
  {@render children()}
</main>

<Footer />

<style>
  .page-container {
    max-width: 960px;
    margin: 0 auto;
    padding: 2rem 1rem;
    min-height: 70vh;
  }
</style>

Ada beberapa hal penting di sini:

  • Navbar akan selalu tampil di bagian atas.
  • Footer akan selalu tampil di bawah.
  • {@render children()} adalah tempat halaman anak dirender.
  • main.page-container menjadi pembungkus konten agar lebar halaman konsisten.

Inilah inti layout di SvelteKit: Anda membuat kerangka halaman sekali, lalu isi tiap route akan dimasukkan ke area children.

Contoh halaman yang memakai layout global

Buat halaman beranda:

<!-- src/routes/+page.svelte -->
<svelte:head>
  <title>Home</title>
</svelte:head>

<h1>Selamat datang</h1>
<p>Ini adalah halaman utama yang menggunakan layout global.</p>

Dan halaman about:

<!-- src/routes/about/+page.svelte -->
<svelte:head>
  <title>About</title>
</svelte:head>

<h1>About</h1>
<p>Halaman ini juga otomatis dibungkus oleh navbar dan footer dari layout global.</p>

Sampai tahap ini, route / dan /about sudah memiliki struktur UI yang sama tanpa duplikasi kode.

Membuat nested layout untuk area blog

Misalnya Anda ingin area blog punya header tambahan, sidebar sederhana, atau warna latar berbeda. Alih-alih membuat semua itu di tiap halaman blog, Anda cukup menambahkan src/routes/blog/+layout.svelte.

<!-- src/routes/blog/+layout.svelte -->
<script>
  let { children } = $props();
</script>

<section class="blog-layout">
  <header class="blog-header">
    <h2>Blog</h2>
    <p>Kumpulan artikel dan catatan teknis.</p>
  </header>

  <div class="blog-content">
    <aside class="blog-sidebar">
      <h3>Navigasi Blog</h3>
      <ul>
        <li><a href="/blog">Semua Artikel</a></li>
        <li><a href="/blog/sveltekit-layout">Contoh Artikel</a></li>
      </ul>
    </aside>

    <div class="blog-main">
      {@render children()}
    </div>
  </div>
</section>

<style>
  .blog-layout {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
  }

  .blog-header {
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    padding: 1rem;
    border-radius: 8px;
  }

  .blog-content {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 1.5rem;
  }

  .blog-sidebar {
    border: 1px solid #e2e8f0;
    padding: 1rem;
    border-radius: 8px;
    background: white;
  }

  .blog-main {
    border: 1px solid #e2e8f0;
    padding: 1rem;
    border-radius: 8px;
    background: white;
  }

  @media (max-width: 768px) {
    .blog-content {
      grid-template-columns: 1fr;
    }
  }
</style>

Nested layout ini tidak menggantikan layout global, melainkan berada di dalamnya. Jadi urutannya menjadi:

  1. Layout global menampilkan navbar dan footer.
  2. Di dalam area konten global, nested layout blog menampilkan header blog dan sidebar.
  3. Di dalam nested layout blog, halaman blog dirender.

Ini sangat berguna untuk menjaga struktur aplikasi tetap modular.

Halaman indeks blog

<!-- src/routes/blog/+page.svelte -->
<svelte:head>
  <title>Blog</title>
</svelte:head>

<h1>Daftar Artikel</h1>
<ul>
  <li><a href="/blog/sveltekit-layout">Membuat Layout Dasar di SvelteKit</a></li>
  <li><a href="/blog/routing-dasar">Memahami Routing Dasar</a></li>
</ul>

Halaman detail blog

<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
  let { params } = $props();
</script>

<svelte:head>
  <title>Detail Blog</title>
</svelte:head>

<article>
  <h1>Artikel: {params.slug}</h1>
  <p>Ini contoh halaman detail artikel berdasarkan slug URL.</p>
</article>

Saat Anda membuka /blog atau /blog/sveltekit-layout, halaman tersebut akan dibungkus oleh dua layer layout: global dan blog.

Kenapa pendekatan ini efektif

Menggunakan +layout.svelte membuat struktur UI lebih mudah dipelihara. Beberapa manfaat praktisnya:

  • Mengurangi duplikasi: navbar dan footer tidak perlu diulang di setiap halaman.
  • Konsistensi tampilan: container, spasi, dan struktur halaman lebih seragam.
  • Pemisahan tanggung jawab: layout global untuk kerangka umum, nested layout untuk area khusus.
  • Lebih mudah dikembangkan: saat area blog butuh sidebar atau breadcrumb, Anda cukup mengubah satu file layout.

Untuk aplikasi kecil, layout global mungkin sudah cukup. Namun ketika aplikasi mulai punya beberapa area dengan kebutuhan UI berbeda, nested layout menjadi jauh lebih berguna.

Kesalahan umum dan tips debugging

1. Menaruh file di folder route yang salah

Jika nested layout tidak terpakai, periksa lokasi file. Layout blog harus ada di src/routes/blog/+layout.svelte, bukan di folder lain.

2. Lupa merender children

Jika halaman kosong padahal route ada, sering kali penyebabnya adalah layout tidak memanggil {@render children()}. Tanpa itu, halaman anak tidak akan tampil.

3. Mengira nested layout menggantikan layout global

Secara default, nested layout akan ditumpuk di atas layout induknya. Jadi kalau Anda melihat navbar global masih muncul di area blog, itu memang perilaku yang diharapkan.

4. Styling bertabrakan

Kalau style layout global dan nested layout saling memengaruhi, periksa nama class yang terlalu umum seperti .container atau .content. Gunakan nama class yang lebih spesifik agar tidak membingungkan.

5. Link navigasi tidak sesuai route

Pastikan tautan seperti /blog/sveltekit-layout benar-benar punya halaman yang sesuai, misalnya route dinamis [slug]. Jika hasilnya 404, cek struktur folder dan penamaan file.

Penutup

+layout.svelte adalah fondasi penting dalam membangun UI yang terstruktur di SvelteKit. Dengan layout global, Anda bisa membungkus seluruh aplikasi dengan navbar, footer, dan container utama. Dengan nested layout, Anda bisa memberi area tertentu seperti blog tampilan dan struktur sendiri tanpa mengganggu halaman lain.

Untuk implementasi nyata, mulailah dari layout global yang sederhana, lalu tambahkan nested layout hanya ketika memang ada kebutuhan pemisahan antarmuka. Pendekatan ini membuat kode lebih mudah dipahami, lebih sedikit duplikasi, dan lebih aman saat aplikasi berkembang.

Jika Anda ingin melanjutkan setelah artikel ini, langkah berikutnya yang relevan adalah menambahkan +layout.ts atau +layout.server.ts untuk memasok data bersama ke layout, misalnya data menu, informasi pengguna login, atau konfigurasi tema.