Reputation: 75
I am new to svelte so I cannot figure this out how to solve this after many tries. Imagine I have a component Navbar.svelte
in the $lib/component
. As usual I will add this component to my +layout.svelte
file. What I am trying to do is make this Navbar dynamic so that the content of the Navbar changes according to my page.
The idea comes from Dynamic Island (Apple iPhone) and I want a navbar that is always stays on top and responsive like that.
(This is one of the reasons why I put my <Navbar/>
in +layout.svelte because I will be using page transitions and I don't want the navbar to be a part of the page transition, it will stay on top always visible) Here is an example taken from my project.
File: Navbar.svelte
<nav>
<slot>
<a href="/another-page"> Another Page </a>
<h1> This is navbar for home </h1>
</slot>
</nav
File: +layout.svelte
<script> // imports </script>
<Navbar/>
<slot/>
<Footer/>
File: +page.svelte
<h1> This is a Home page </h1>
How can I change the navbar when I click on the /another-page
link so that in /another-page my navbar will contain only these:
<a href="/"> Home </a>
<h1> This is navbar for Another Page </h1>
I tried named slots but it seems like +layout.svelte only accepts one slot.
Upvotes: 6
Views: 4028
Reputation: 2315
One way to do this is to use a Svelte store to pass around the constructor of the navbar component you want. You can see a live demo here.
We use <svelte:component>
in the routes/+layout.svelte
file and bind that component to a simple writable store named currentNavBar
.
We then create 2 navbar components: HomeNavBar
and AnotherPageNavBar
.
Then, in routes/+page.svelte
, we set the store value to be the constructor of HomeNavBar
. We also do the equivalent needful in routes/anotherpage/+page.svelte
.
This is routes/+layout.svelte
:
<script>
import './global.css';
import currentNavBar from '../stores/currentNavBar.js';
</script>
<!-- UPDATE 2024-07-04: Wrap with an IF block in case no navbar is needed. -->
{#if $currentNavBar}
<svelte:component this={$currentNavBar} />
{/if}
<slot />
This is stores/currentNavBar.js
:
import { writable } from 'svelte/store';
export default writable(undefined);
This is routes/+page.svelte
, the homepage, the script part:
<script>
import HomeNavBar from '$lib/NavBars/HomeNavBar.svelte';
import currentNavbar from '../stores/currentNavBar.js';
export let data;
$currentNavbar = HomeNavBar;
</script>
This is routes/anotherpage/+page.svelte
:
<script>
import AnotherPageNavBar from '$lib/NavBars/AnotherPageNavBar.svelte';
import currentNavBar from '../../stores/currentNavBar.js';
$currentNavBar = AnotherPageNavBar;
</script>
<h1>This is Another Page</h1>
Upvotes: 11