2026 Community Survey results are here! See how the Craft CMS community works. results are live!

UI Framework Components in Astro

How to use Svelte in Astro as an "Astro Island"

As I men­tioned at the begin­ning of the course, Astro makes it easy to add in your favorite com­po­nent frame­work, whether it’s Vue, React, Svelte, or some­thing like AlpineJS. 

Each com­po­nent used on a page can exist as a stand-alone set of dynam­ic func­tion­al­i­ty. These dynam­ic blobs in an oth­er­wise sta­t­ic page built by Astro are called Astro Islands (or some­times called Com­po­nent Islands”).

Remem­ber, the default in Astro is that it strips all JavaScript and ren­ders a com­plete­ly sta­t­ic set of HTML doc­u­ments for your site. How­ev­er, there are times when we need to have some dynam­ic and inter­ac­tive UI components. 

To han­dle that, Astro has this con­cept of Islands where Astro hydrates a por­tion of a page using just the Javascript need­ed, and it keeps it iso­lat­ed to just that com­po­nent. We tell Astro how to han­dle each com­po­nent or island using spe­cial client direc­tives. We’ll cov­er that more in a few min­utes when we build a Svelte com­po­nent for our project.

Let’s start work­ing with code and learn more about Astro Islands and using a UI frame­work with Astro.

Installing the Svelte Integration

For this course, we’ll use Svelte. The frame­work you choose doesn’t mat­ter but I would stick with the offi­cial inte­gra­tions, which cov­ers all of the major players. 

npx astro add svelte

Fol­low the wiz­ard, and Astro will add the depen­den­cies that will enable sup­port for Svelte com­po­nents right inside your Astro project.

As part of the process, Astro will cre­ate a Svelte con­fig file and update the Astro con­fig file to load the Svelte integration.

To show how Astro Islands/​UI frame­works work inside of Astro, we will build a sim­ple Svelte com­po­nent that cre­ates a dis­miss­able ban­ner at the top of the page.

Let’s start by cre­at­ing a new Svelte com­po­nent called BannerNotify.svelte in the components direc­to­ry of the project. We can mix up our com­po­nents from dif­fer­ent frame­works in the sin­gle components direc­to­ry if we want. Of course, we can also give each frame­work or com­po­nent type its own direc­to­ry. It’s real­ly up to you, or me, or us. 

We’ll use the fol­low­ing code so we have a very sim­ple yet func­tion­al Svelte com­po­nent. Cov­er­ing the ins and outs of Svelte is out of the scope of this course, so fol­low along as we get the com­po­nent set up and work­ing. 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">&rarr;</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 com­po­nent code cre­ates a sim­ple ban­ner pop­u­lat­ed with con­tent from the hard-code javascript object. The default state is that the ban­ner is dis­played. It is removed when a user clicks the X” to dis­miss the banner. 

It could be a more sophis­ti­cat­ed ban­ner, but it will get the job done for this project!

Now we need to use the com­po­nent some­where in our Astro code. Let’s put it on the home­page via the pages/index.astro component.

import BannerNotify from '../components/BannerNotify.svelte'

And then, we place the com­po­nent ele­ment wher­ev­er we want that com­po­nent 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 com­po­nent an Astro Island, we’ll tell Astro to ren­der 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" />
Craft Version
Craft 4
Instructor
Ryan Irelan
Level
Beginner
Date Published
May 02, 2023
Ryan Irelan

I am the creator of CraftQuest, a web developer, and former software team manager. I spend most of my time improving CraftQuest with code and courses. When I'm not in front of the computer, I spend my time with my family, and running on the roads and trails of Austin, TX.