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)