Astro
This guide will help create a basic Skeleton project using Astro, including adding components using Astro's island architecture.
Global Stylesheet
Let's start by creating a global stylesheet in /src/styles/global.css
. Then add the following styles.
html, body { @apply h-full overflow-hidden; }
Layout Setup
We'll create a new Astro Layout
in /src/layouts/LayoutRoot.astro
. Our layout needs a bit of structure, so let's make use of the Skeleton
App Shell component.
---
import '@skeletonlabs/skeleton/themes/theme-skeleton.css';
import '@skeletonlabs/skeleton/styles/all.css';
import '../styles/global.css';
import { AppShell, AppBar } from '@skeletonlabs/skeleton';
---
<!-- NOTE: we have set the .dark class to enable Dark Mode -->
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<!-- NOTE: customize your app title -->
<title>Skeleton</title>
</head>
<body>
<AppShell>
<!-- Header -->
<svelte:fragment slot="header">(header)</svelte:fragment>
<!-- Sidebar -->
<svelte:fragment slot="sidebarLeft">(sidebar)</svelte:fragment>
<!-- Page Content Slot -->
<slot />
</AppShell>
</body>
</html>
Add the App Bar
Next, let's add a header element using Skeleton's App Bar component. Replace "Skeleton" with your application name and customize the GitHub link as desired.
<svelte:fragment slot="header">
<!-- Insert the App Bar: -->
<AppBar>
<svelte:fragment slot="lead">
<h1>Skeleton</h1>
</svelte:fragment>
<svelte:fragment slot="trail">
<a class="btn btn-sm" href="https://github.com/" target="_blank" rel="noreferrer">GitHub</a>
</svelte:fragment>
</AppBar>
<!-- --- -->
</svelte:fragment>
Add Sidebar Navigation
Let's customize our App Shell's sidebar slot to make it stand out a bit more. Add the following Tailwind utility classes to the slotSidebarLeft
prop.
<AppShell slotSidebarLeft="bg-surface-500/5 w-56 p-4">
After that, let's implement a Tailwind Elements navigation list within the App Shell's left sidebar slot.
<svelte:fragment slot="sidebarLeft">
<!-- Insert the list: -->
<nav class="list-nav">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<!-- --- -->
</svelte:fragment>
Page Setup
Now that our layout is setup, let's implement it in our homepage in /src/pages/index.astro
. Replace the file contents
with the following. Be aware that we'll make use of the Gradient Heading import in a following step below.
---
import LayoutRoot from './layouts/LayoutRoot.astro';
import { GradientHeading } from '@skeletonlabs/skeleton';
---
<LayoutRoot>
<h1>Hello Skeleton</h1>
</LayoutRoot>
Now let's add some basic content to our homepage. Open /src/pages/index.astro
and replace the contents within the
LayoutRoot
tags with the following. This will provide multiple "Tailwind Elements" styled by the all.css
stylesheets.
<LayoutRoot>
<div class="container mx-auto p-8 space-y-8">
<h1>Hello Skeleton</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<hr />
<section class="card card-body">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
</section>
<hr />
<section class="flex space-x-2">
<a class="btn btn-filled-primary" href="https://kit.svelte.dev/" target="_blank" rel="noreferrer">SvelteKit</a>
<a class="btn btn-filled-accent" href="https://tailwindcss.com/" target="_blank" rel="noreferrer">Tailwind</a>
<a class="btn btn-filled-tertiary" href="https://github.com/" target="_blank" rel="noreferrer">GitHub</a>
</section>
</div>
</LayoutRoot>
These elements are styled automatically due to our use of all.css
and the included Tailwind Elements stylesheets.
Add a Component
Let's implement Skeleton's Gradient Heading component. Replace the H1 heading on the page with the following. Feel free to adjust the settings and text as you wish.
<GradientHeading tag="h1" direction="bg-gradient-to-br" from="from-primary-500" to="to-accent-500">
Homepage
</GradientHeading>
Island Architecture
Astro allows for partial component hydration via the Astro Island Architecture. Let's learn how to utilize this for Skeleton features.
Static Islands
Simple Svelte Components and Tailwind Elements require no Javascript functionality. This means they can be imported and used directly within your Astro page components with no hydration required.
---
import { Breadcrumb, Crumb } from '@skeletonlabs/skeleton';
---
<Breadcrumb>
<Crumb href='/'>Home</Crumb>
<Crumb>About</Crumb>
</Breadcrumb>
<a class="btn btn-filled-primary" href="/">Home</a>
Dynamic Islands
For more complex Svelte features--such as event handlers, Svelte Actions, using Svelte writable stores, and similar--we'll need to
create Svelte "wrapper" component. Let's create one now in
/src/components/WrapperExample.svelte
, and insert a button which uses a Svelte on:click
event handler.
<script lang="ts">
function triggerMessage(): void { console.log('Hello, Skeleton'); }
</script>
<button class="btn btn-filled-primary" on:click={() => { triggerMessage() }}>Trigger</button>
We can then import our new wrapper component within an Astro page component, such as our homepage in /src/pages/index.astro
.
---
import LayoutRoot from '../layouts/LayoutRoot.astro';
// ...
import WrapperExample from '../components/WrapperExample.svelte';
---
<LayoutRoot>
<!-- ... --->
<WrapperExample client:visible></WrapperExample>
</LayoutRoot>
Component Hydration
Please note that dynamic components MUST be hydrated using
Astro's Client Directives. In the example above, we opted for the
client:visible
directive, which loads and hydrates the component Javascript only when it becomes visible the userβs
viewport. Had we not hydrated our component, the
triggerMessage()
method would not work as expected.