I have a page that has a nav bar with a "Quarters" link. Under the Quarters link, when the user is on the /quarters
route, a list of quarters will be shown, like 2019Q2 etc. The url will be /quarters/2019q2
.
I want to make a component that show shows a hyperlink that will have the selected
class if the current url matches the href of the link. Here's the closest I can get:
<script>
import { afterUpdate } from 'svelte';
export let segment;
export let text = 'text here';
export let link;
let isCurrentPath = false;
console.log(segment, link, text);
afterUpdate(() => {
if (window.location.pathname.includes(link)) {
isCurrentPath = true;
debugger;
}
console.log('HL afterUpdate ', window.location);
});
</script>
<style>
/* omitted */
</style>
<a class:selected={segment && isCurrentPath} href={link}>{text}</a>
That works fine for the first load, but when the user navigates to a different data page the selection is not updated. How do I get some code to only run on the client-side? If I access the window
object outside of afterUpdate
I will get an null ref error from the server-side code.
ETA: Tried this too:
let isCurrentPath = false;
let path = typeof window === 'undefined' ? '' : window.location.pathname;
$: if (path) isCurrentPath = window.location.pathname.includes(link);
That code doesn't fire when the user clicks one of the data links. Tried onMount
as well with no positive result.
The trick is to create a reactive statement based on a value in the page store.
<!--
This is used to have a link on the page that will show highlighted if the url meets the criteria.
You might want to adjust the logic on line 19.
usage:
<HighlightedLink bind:segment highlight="faq" rel="prefetch" link="/faq" text="FAQ" />
-->
<script>
import { stores } from '@sapper/app';
const { page } = stores();
export let highlight;
export let segment;
export let text = 'text here';
export let link;
export let target;
let highlightPath = false;
$: highlightPath =
$page.path && highlight && ($page.path.includes(highlight) || $page.path.includes(link));
</script>
<style>
.selected {
position: relative;
display: inline-block;
}
.selected::after {
position: absolute;
content: '';
width: calc(100% - 1em);
height: 2px;
background-color: rgb(255, 62, 0);
display: block;
bottom: -1px;
}
a {
padding-left: 10px;
}
</style>
<a class:selected={highlightPath} href={link}>{text}</a>