I am trying to create a navigation bar with sveltekit. So far, I have all the links (hash routes) working to be styled when clicked. However, after clicking the "Home" route several times, it stops causing the page to load, which causes my $page
subscription to not update and thus style the link correctly.
My subscription that logs the current hash route:
$: console.log($page.url.hash);
My test for styling the link:
class:active={$page.url.hash === x.path.slice(1)
Even after the Home link stops being styled, all the other links will still be styled when clicked. I do get an empty string in the console on the first page load, and again after clicking away from Home and back on it. The second time clicking the Home link does not produce anything in the console.
The route changes in the address bar each time I click any link.
<script lang="ts">
import { page } from '$app/stores';
const navItems = [
{
label: 'home',
path: '/'
},
{
label: 'how it works',
path: '/#how-it-works'
},
{
label: 'pricing',
path: '/#pricing'
},
{
label: 'partners',
path: '/#partners'
},
{
label: 'contact',
path: '/#contact-us'
}
];
$: console.log($page.url);
</script>
<nav>
{#each navItems as x}
<a
href={x.path}
class="capitalize"
class:active={$page.url.hash === x.path.slice(1)}
>
{x.label}
</a>
{/each}
</nav>
<style>
.active {
font-weight: bold;
position: relative;
}
.active::after {
content: '';
width: 100%;
height: 3px;
position: absolute;
left: 0;
bottom: -8px;
background-color: #17a398;
border-radius: 999px;
}
</style>
I honestly think there might be a bug here, and you should definitely report it.
However, there is a workaround, you can use the goto
function to navigate. This does seem to work.
Add the following import:
import { goto } from '$app/navigation';
Then in your navs update the code to this:
<nav>
{#each navItems as x}
<a
on:click|preventDefault={() => goto(x.path)}
href={x.path}
class="capitalize"
class:active={$page.url.hash === x.path.slice(1)}
>
{x.label}
</a>
{/each}
</nav>
Here, we prevent the default action of clicking the link, and instead we run the goto
function (which is the programmatic equivalent of clicking a link).
In the brief testing I've done, the styles are updated correctly and the logs are shown as expected.