DEV Community

Cover image for Astro loading spinners
Alex Nguyen
Alex Nguyen

Posted on Edited on Originally published at alexnguyen.co.nz

Astro loading spinners

Loading spinners with framework components

If you use a framework component with a client directive of client:only, you may see a flash of no content until the component renders.

In this case, it may be useful to show a loading state like a spinner or skeleton until the component loads - especially if it will take longer than a second.

One way to do this is to use a separate loading element alongside your framework component, and hide or remove that element once the component mounts.

React example

<!-- some sort of indicator or spinner --> 
<svg
  class="spinner"
  ...
  >
</svg>
<ReactComponent client:only="react" />
Enter fullscreen mode Exit fullscreen mode
/* ReactComponent.tsx */
import { useEffect } from "react";

export function ReactComponent() {
  useEffect(() => {
    const spinner = document.querySelector(".spinner");
    if (spinner) spinner.remove();
  }, []);

  return <div>React content</div>;
}

Enter fullscreen mode Exit fullscreen mode

Vue example

<VueComponent client:only="vue" />
Enter fullscreen mode Exit fullscreen mode
<!-- VueComponent.vue -->
<script setup lang="ts">
  import { onMounted } from "vue";

  onMounted(() => {
    const spinner = document.querySelector(".spinner");
    if (spinner) spinner.remove();
  });
</script>

<template>
  <div>Vue content</div>
</template>
Enter fullscreen mode Exit fullscreen mode

Svelte example

<SvelteComponent client:only="svelte" />
Enter fullscreen mode Exit fullscreen mode
<!-- SvelteComponent.svelte -->
<script lang="ts">
  import { onMount } from 'svelte';

  onMount(() => {
    const spinner = document.querySelector(".spinner");
    if (spinner) spinner.remove();
  });
</script>

<div>Svelte content</div>
Enter fullscreen mode Exit fullscreen mode

Alternative

If you're using another directive like client:load or client:visible, your component's initial view (before it hydrates) may render right away.

In this case, you probably don't need to do anything. But if you still need to show a loading state, then you can handle this within the component itself. For example, you could add a loading spinner within the component, and then conditionally render the final view once it's ready (with state).

Feel free to follow me or check out my blog.

Top comments (0)