How to use Svelte in Astro as an "Astro Island"
As I mentioned at the beginning of the course, Astro makes it easy to add in your favorite component framework, whether it’s Vue, React, Svelte, or something like AlpineJS.
Each component used on a page can exist as a stand-alone set of dynamic functionality. These dynamic blobs in an otherwise static page built by Astro are called Astro Islands (or sometimes called “Component Islands”).
Remember, the default in Astro is that it strips all JavaScript and renders a completely static set of HTML documents for your site. However, there are times when we need to have some dynamic and interactive UI components.
To handle that, Astro has this concept of Islands where Astro hydrates a portion of a page using just the Javascript needed, and it keeps it isolated to just that component. We tell Astro how to handle each component or island using special client directives. We’ll cover that more in a few minutes when we build a Svelte component for our project.
Let’s start working with code and learn more about Astro Islands and using a UI framework with Astro.
For this course, we’ll use Svelte. The framework you choose doesn’t matter but I would stick with the official integrations, which covers all of the major players.
npx astro add svelte
Follow the wizard, and Astro will add the dependencies that will enable support for Svelte components right inside your Astro project.
As part of the process, Astro will create a Svelte config file and update the Astro config file to load the Svelte integration.
To show how Astro Islands/UI frameworks work inside of Astro, we will build a simple Svelte component that creates a dismissable banner at the top of the page.
Let’s start by creating a new Svelte component called BannerNotify.svelte
in the components
directory of the project. We can mix up our components from different frameworks in the single components
directory if we want. Of course, we can also give each framework or component type its own directory. It’s really up to you, or me, or us.
We’ll use the following code so we have a very simple yet functional Svelte component. Covering the ins and outs of Svelte is out of the scope of this course, so follow along as we get the component set up and working. It should work just fine if you copy the component’s code.
<script>
let showBanner = true;
const banner = {
title: 'Monthly Market Livestream',
description: 'Join me on July 2, 2023 at 10 AM PT',
link: 'https://google.com',
dismissText: 'Dismiss',
dismissIcon: 'M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z',
}
function dismissBanner() {
showBanner = false;
}
</script>
{#if showBanner}
<div class="flex items-center gap-x-6 bg-gray-900 px-6 py-2.5 sm:px-3.5 sm:before:flex-1">
<p class="text-sm leading-6 text-white">
<a href="{banner.link}">
<strong class="font-semibold">{banner.title}</strong><svg viewBox="0 0 2 2" class="mx-2 inline h-0.5 w-0.5 fill-current" aria-hidden="true"><circle cx="1" cy="1" r="1" /></svg>{banner.description}<span aria-hidden="true">→</span>
</a>
</p>
<div class="flex flex-1 justify-end">
<button on:click={dismissBanner} type="button" class="-m-3 p-3 focus-visible:outline-offset-[-4px]">
<span class="sr-only">{banner.dismissText}</span>
<svg class="h-5 w-5 text-white" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path d="{banner.dismissIcon}" />
</svg>
</button>
</div>
</div>
{/if}
This component code creates a simple banner populated with content from the hard-code javascript object. The default state is that the banner is displayed. It is removed when a user clicks the “X” to dismiss the banner.
It could be a more sophisticated banner, but it will get the job done for this project!
Now we need to use the component somewhere in our Astro code. Let’s put it on the homepage via the pages/index.astro
component.
import BannerNotify from '../components/BannerNotify.svelte'
And then, we place the component element wherever we want that component to appear. We’ll place it just inside the Layout
element:
<Layout title="Welcome to Home Quest" description="In a competitive market, Olivia is the experienced real estate agent you want on your side.">
<BannerNotify />
To make the component an Astro Island, we’ll tell Astro to render it only on the client as a Svelte component:
<Layout title="Welcome to Home Quest" description="In a competitive market, Olivia is the experienced real estate agent you want on your side.">
<BannerNotify client:only="svelte" />
Astro Quick-Start Guide is made up of the following videos: