white c letter with a black background

constt

Custom Sidebar

How to make a sidebar using svelte

Tags:

svelte

sidebar

design

First we need to create a new component in the lib folder.

To use this code you need to install a npm packages using this command

npm i lucide-svelte

When done you can use this code to have a sidebar

sidebar.svelte

<script lang="ts">
	import { page } from '$app/state';
	import ListTodo from 'lucide-svelte/icons/list-todo';
	import Settings from 'lucide-svelte/icons/settings';
	import PanelLeft from 'lucide-svelte/icons/panel-left';
	import { slide } from 'svelte/transition';
	import { innerWidth, innerHeight } from 'svelte/reactivity/window';

	let currentUrl = $derived(page.url.pathname);


	$effect(() => {
		if (Number(innerWidth.current) < 640) {
			showSidebar = false;
		}
	});

	let showSidebar = $state(true);

	const menuItems = [
		{
			name: 'Todos',
			href: '/todos',
			icon: ListTodo
		},
		{
			name: 'Settings',
			href: '/settings',
			icon: Settings
		}
	];
</script>

<div class="flex">
	{#if showSidebar}
		<div
			transition:slide={{ axis: 'x', duration: 500 }}
			class="border-primary-50 bg-text-950 flex h-screen w-52 flex-col justify-between overflow-hidden whitespace-nowrap border-x p-2 lg:static"
		>
			<div class="">
				{#each menuItems as item}
					{@const Icon = item.icon}
					<div
						class="{currentUrl === item.href
							? 'border border-zinc-300 bg-zinc-100 drop-shadow-xs dark:border-zinc-700 dark:bg-zinc-800'
							: ''} mt-2 flex items-center gap-2 overflow-hidden rounded-lg p-1"
					>
						<Icon size="16" />
						<a href={item.href}>
							<span class="font-inter text-sm">{item.name}</span>
						</a>
					</div>
				{/each}
			</div>
			<div class="flex items-center gap-2">
				<img
					src="https://todo-list.db.constt.de/api/files/users/{page.data.user.id}/{page.data.user
						.avatar}"
					class="size-10 overflow-hidden rounded-md"
					alt={page.data.user.id}
				/>
				<p class="font-bold">{page.data.user.user}</p>
			</div>
		</div>
	{/if}
	<div>
		<button
			class="p-1"
			onclick={() => {
				showSidebar = !showSidebar;
			}}><PanelLeft /></button
		>
	</div>
</div>

To change what items are in the sidebar, you can change the menuItems array.

Now all thats left is to display the sidebar on every side add this code into your +layout.svelte

+layout.svelte


<script lang="ts">
    // You may need to change the path if you created the component somewhere else in the lib folder
    import sidebar from '$lib/sidebar.svelte';

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

<Sidebar />
{@render children?.()}