Sveltekit Loading Spinner

Sveltekit Loading Indicator shows that a page is currently being loaded or it is in the process of navigation.

svelte logo

Want to build a Svelte/SvelteKit site? Hire Me.

Sveltekit Loading Spinner

Why Sveltekit site needs a Loading Indicator?

Many a times - usually, at the beginning of the page load - the layout, or all the components may not be ready to be displayed.

An image might still be loading, the font might not be applied yet.

A loding indicator improves user experience.

How to show a Loading Indicator on Sveltekit site

We have to target the top level layout for showing a loading spinner. That would be /src/routes/+layout.svelte.

/routes/+layout.svelte

<script>
    let hasPageLoaded = false;

    onMount(() => {
        hasPageLoaded = true;
    });
</script>

{#if !hasPageLoaded}
    <Loader /> <!-- A component that shows loading indicator (fullscreen) -->
{/if}
<slot />

Loader.svelte

<div class="loading-container">
	<svg width="50" height="50" viewBox="0 0 24 24">
        <path
        fill="currentColor"
        d="M12 2A10 10 0 1 0 22 12A10 10 0 0 0 12 2Zm0 18a8 8 0 1 1 8-8A8 8 0 0 1 12 20Z"
        opacity=".5"/><path fill="currentColor" d="M20 12h2A10 10 0 0 0 12 2V4A8 8 0 0 1 20 12Z"
        ><animateTransform
            attributeName="transform"
            dur="1s"
            from="0 12 12"
            repeatCount="indefinite"
            to="360 12 12"
            type="rotate"
        /></path>
    </svg>
</div>

<style>
.loading-container {
    position: fixed;
    width: 100vw;
    height: 100vh;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    display: grid;
    place-items: center;
}
</style>

Do not use {:else} statement here. If you do so then server-side-rendering will not happen.

Now this will show the loading spinner when the page is in loading state but not when navigating.

Sveltekit Loading Indicator on navigation

We are going to use navigate store to show the loading spinner when the user is navigating from one page to another.

<script>
    import { navigating } from '$app/stores';

    let hasPageLoaded = false;

    onMount(() => {
        hasPageLoaded = true;
    });
</script>
{#if !hasPageLoaded || $navigating}
    <Loader />
{/if}
<slot />

Find related articles

Let's discuss on Twitter