Svelte – menus and changing urls
We set up the menu in Svelte, highlight the current page and create url to links in the address bar.
I’ve already built the menu on ready-made solutions like svelte-tabs. Here I will show you how to make it with your own efforts. Plus, let’s add transitions from the browser line to specific Svelte pages.
The idea with url transitions is taken from here:
github.com/bluwy/svelte-url
This is a small url.js file that you need to put in your place.
Index.svelte
Entrance page Index.svelte… In it we load our menu. It is always unchanged and will not reload when you click on links. Then we add processing of url requests to the same page (which is also the main one). Specifies the transition page depending on the link. The same pages are indicated in the menu Nav.svelte…
import url from ‘./assets/js/url’
import Nav from “./Nav.svelte”;
import Main from ‘./pages/Main.svelte’;
import Page1 from ‘./pages/Page1.svelte’;
import Page2 from ‘./pages/Page2.svelte’;
script>
<Nav/>
Go from URL to pages ->
{#if $ url.hash === ” || $ url.hash === ‘# /’}
<Main/>
{:else if $ url.hash === ‘# / Page1’}
<Page1/>
{:else if $ url.hash === ‘# / Page2’}
<Page2/>
{:else}
<h1>404h1>
{/if}
Nav.svelte
A page with a menu and highlighting the current link to Svelte.
We collect our menu from the pages we need:
import url from ‘./assets/js/url’
let menu = 0;
let links = [
{
‘page’: ‘#/Main’,
‘name’: ‘Главная’
},
{
‘page’: ‘#/Page1’,
‘name’: ‘Название ссылки страницы 1’
},
{
‘page’: ‘Page2’,
‘name’: ‘Название ссылки страницы 2’
},
]
// Selected page
let current = ”;
let selected;
script>
We display the menu on the site:
<ul class=“menu”>
{#each links as link, id}
<li>
{#if link.page === ‘Main’}
<a href=“/ #”
class:selected=“{$ url.hash === ”}”
on:click=“{() => current = id}”
on:click={() => menu = id}
>
{link.name}
a>
{:else}
<a href=“# / {link.page}”
class:selected=“{$ url.hash === link.page}”
on:click=“{() => current = id}”
on:click={() => menu = id}
>
{link.name}
a>
{/if}
li>
{/each}
ul>
Add scss styles to Svelte:
// @ import ‘assets / scss / app’;
…menu {
display: flex;
justify–content: space–evenly;
flex–wrap: wrap;
border–bottom: 1px solid #CCCCCC;
margin: 0;
padding: 0;
li {
list–style: none;
display: inline;
}
a {
padding: 0.5em 0.75em;
border–bottom: 2px solid transparent;
cursor: pointer;
list–style: none;
display: inline–block;
&…selected {
border–bottom: 2px solid # 4F81E5;
color: # 4F81E5;
}
&:hover {
text–decoration: none;
color: darkred;
}
}
}
style>
These sections are responsible for highlighting the current link (page):
let current = ”;
let selected;
class:selected=“{$ url.hash === ‘# /’ + link.page}”
on:click=“{() => current = id}”
on:click={() => menu = id}
Nav.svelte with icons
Slightly modified version for icons.
JS:
import url from ‘./assets/js/url’
let menu = 0;
let links = [
{
// ‘name’: ‘Графики’,
‘link’: ‘#/Charts’,
‘hash’: ‘#/Charts’,
‘class’: ‘icon-chart’,
},
{
// ‘name’: ‘Главная’,
‘link’: ‘/#’,
‘hash’: ”,
‘class’: ‘icon-add’,
},
{
// ‘name’: ‘Админка’,
‘link’: ‘/admin/’,
‘class’: ‘icon-settings’
}
]
// Selected page
let current = ”;
let selected;
script>
Main code:
<ul class=“menu”>
{#each links as item, id}
<li class=“menu-container js-menu-container”>
<a href=“{item.link}”
class:selected=“{$ url.hash === item.hash}”
on:click=“{() => current = id}”
on:click={() => menu = id}>
<div class=“icon-menu {item.class}”> div>
a>
li>
{/each}
ul>
Styles:
// @ import ‘assets / scss / app’;
.menu {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
position: fixed;
z-index: 99;
width: 100%;
margin: 0;
left: 0;
bottom: 0;
background-color: # cdd5e2;
align-items: baseline;
overflow: hidden;
padding: 0;
li {
list-style: none;
display: inline;
}
a {
border-bottom: 2px solid transparent;
cursor: pointer;
list-style: none;
display: inline-block;
padding: 0.5em 0.75em;
color: # 000;
&.selected {
border-bottom: 2px solid # 4F81E5;
color: # 4F81E5;
}
&:hover {
text-decoration: none;
color: darkred;
}
}
.icon-menu {
height: 30px;
width: 30px;
padding: 5px;
cursor: pointer;
}
.icon-chart {
background-color: black;
mask-image: url(“”);
&:hover {
background-color: red;
}
}
.icon-add {
background-color: black;
mask-image: url(“”);
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
&:hover {
background-color: red;
}
}
.icon-settings {
background-color: black;
mask-image: url(“”);
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
&:hover {
background-color: red;
}
}
}
style>