Tutorial Laravel 12 API Next JS 15 dan Tailwind CSS #5 Konfigurasi Sidebar

Belajar membangun aplikasi fullstack modern dengan backend Laravel 12 RESTful API, frontend Next.js, dan desain menggunakan Tailwind CSS. Tutorial ini membahas step-by-step mulai dari setup environment, pembuatan API, konsumsi API di Next.js, hingga integrasi UI responsif.

✅ Telah dilihat 293 kali

Rating: 5.00 ⭐

... 13 August 2025, 20:33

Konfigurasi Sidebar

Sekarang kita masuk ke bagian pengaturan sidebar. Kalau teman-teman perhatikan, tampilan dashboard yang kita install sebelumnya sudah memiliki beberapa menu bawaan. Nah, semua daftar menu itu sebenarnya diatur di sebuah file bernama app-sidebar.tsx yang ada di dalam folder components.

Di sinilah “pintu gerbang” untuk mengatur nama-nama menu yang muncul di sidebar. Karena dalam studi kasus kita hanya fokus pada pembelajaran API Laravel, khususnya untuk membuat CRUD produk, maka kita tidak butuh semua menu default tersebut.

Kita cukup membuat dua menu saja, yaitu Dashboard dan Products. Silakan buka file app-sidebar.tsx, lalu ubah isi menunya menjadi seperti berikut:

"use client"

import * as React from "react"
import Link from "next/link"
import { usePathname } from "next/navigation"
import {
  IconChartBar,
  IconDashboard,
  IconHelp,
  IconInnerShadowTop,
  IconSearch,
  IconSettings,
} from "@tabler/icons-react"

import {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuButton,
  SidebarMenuItem,
} from "@/components/ui/sidebar"

import { NavUser } from "@/components/nav-user"

const data = {
  user: {
    name: "shadcn",
    email: "[email protected]",
    avatar: "/avatars/shadcn.jpg",
  },
  navMain: [
    {
      title: "Dashboard",
      url: "/dashboard",
      icon: IconDashboard,
    },
    {
      title: "Products",
      url: "/products",
      icon: IconChartBar,
    },
  ],
  navSecondary: [
    {
      title: "Settings",
      url: "/settings",
      icon: IconSettings,
    },
    {
      title: "Get Help",
      url: "/help",
      icon: IconHelp,
    },
    {
      title: "Search",
      url: "/search",
      icon: IconSearch,
    },
  ],
}

// ================= NavMain =================
interface NavItemProps {
  title: string
  url: string
  icon: React.ElementType
}

function NavMain({ items }: { items: NavItemProps[] }) {
  const pathname = usePathname()
  return (
    <div className="space-y-1">
      {items.map((item) => {
        const Icon = item.icon
        const isActive = pathname === item.url
        return (
          <Link
            key={item.title}
            href={item.url}
            className={`flex items-center gap-2 px-3 py-2 rounded hover:bg-gray-100 ${
              isActive ? "bg-gray-200 font-semibold" : ""
            }`}
          >
            <Icon className="!size-5" />
            <span className="text-sm">{item.title}</span>
          </Link>
        )
      })}
    </div>
  )
}

// ================= NavSecondary =================
function NavSecondary({ items }: { items: NavItemProps[] }) {
  const pathname = usePathname()
  return (
    <div className="space-y-1 mt-auto">
      {items.map((item) => {
        const Icon = item.icon
        const isActive = pathname === item.url
        return (
          <Link
            key={item.title}
            href={item.url}
            className={`flex items-center gap-2 px-3 py-2 rounded hover:bg-gray-100 ${
              isActive ? "bg-gray-200 font-semibold" : ""
            }`}
          >
            <Icon className="!size-5" />
            <span className="text-sm">{item.title}</span>
          </Link>
        )
      })}
    </div>
  )
}

// ================= AppSidebar =================
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
  return (
    <Sidebar collapsible="offcanvas" {...props}>
      <SidebarHeader>
        <SidebarMenu>
          <SidebarMenuItem>
            <SidebarMenuButton
              asChild
              className="data-[slot=sidebar-menu-button]:!p-1.5"
            >
              <Link href="/">
                <IconInnerShadowTop className="!size-5" />
                <span className="text-base font-semibold">Laravel Next.JS</span>
              </Link>
            </SidebarMenuButton>
          </SidebarMenuItem>
        </SidebarMenu>
      </SidebarHeader>

      <SidebarContent>
        <NavMain items={data.navMain} />
        <NavSecondary items={data.navSecondary} />
      </SidebarContent>

      <SidebarFooter>
        <NavUser user={data.user} />
      </SidebarFooter>
    </Sidebar>
  )
}

Pada kode berikut, ada beberapa penyesuaian:

  1. Menambahkan import Link dari "next/link" Ini diperlukan karena kita ingin semua item menu bisa berfungsi sebagai tautan yang diarahkan ke halaman tertentu.
  2. Menentukan data menu di data.navMain dan data.navSecondary
    • navMain berisi menu inti (Dashboard dan Products).
    • navSecondary berisi menu tambahan (Settings, Get Help, Search).
  3. Memisahkan komponen menu utama (NavMain) dan menu sekunder (NavSecondary) Dengan cara ini, kode menjadi rapi dan mudah diperluas kalau nanti kita ingin menambahkan logika khusus untuk setiap bagian menu.

Preview

Jika kita akses dashboard, maka akan terlihat seperti berikut ini:

Kalau di sidebar kita sudah menambahkan menu Products dengan URL /products, maka saat link itu diklik, Next.js akan mencari file halaman di folder app/products/page.tsx.

Karena file itu belum ada, Next.js otomatis akan menampilkan pesan:

404 — This page could not be found

Itu artinya:

  • Sidebar kita sudah mengarahkan ke rute /products.
  • Tapi halaman /products belum dibuat.

Pada tahap berikutnya kita akan melangkah ke inti dari studi kasus kita: menyiapkan konfigurasi endpoint API Laravel. Tujuannya adalah supaya halaman di Next.js bisa berkomunikasi dengan backend Laravel dengan lancar, aman, dan terstruktur.

🔥 Flash Sale


📜 Table Of Contents


📌 Daftar Episode


Daftar eBook