src/content/docs/en/tutorial/6-islands/1.mdx
import Box from '/components/tutorial/Box.astro';
import Checklist from '/components/Checklist.astro';
import Spoiler from '/components/Spoiler.astro';
import MultipleChoice from '/components/tutorial/MultipleChoice.astro';
import Option from '/components/tutorial/Option.astro';
import PreCheck from '/components/tutorial/PreCheck.astro';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import { Steps } from '@astrojs/starlight/components';
Use a Preact component to greet your visitors with a randomly-selected welcome message!
<PreCheck> - Add Preact to your Astro project - Include Astro islands (Preact `.jsx` components) on your home page - Use `client:` directives to make islands interactive </PreCheck>Add the ability to use Preact components in your Astro project with a single command:
<PackageManagerTabs> <Fragment slot="npm"> ```sh npx astro add preact ``` </Fragment> <Fragment slot="pnpm"> ```sh pnpm astro add preact ``` </Fragment> <Fragment slot="yarn"> ```sh yarn astro add preact ``` </Fragment> </PackageManagerTabs>Follow the command line instructions to confirm adding Preact to your project.
</Steps>This component will take an array of greeting messages as a prop and randomly select one of them to show as a welcome message. The user can click a button to get a new random message.
<Steps> 1. Create a new file in `src/components/` named `Greeting.jsx`Note the `.jsx` file extension. This file will be written in Preact, not Astro.
2. Add the following code to Greeting.jsx:
```jsx title="src/components/Greeting.jsx"
import { useState } from 'preact/hooks';
export default function Greeting({messages}) {
const randomMessage = () => messages[(Math.floor(Math.random() * messages.length))];
const [greeting, setGreeting] = useState(messages[0]);
return (
<div>
<h3>{greeting}! Thank you for visiting!</h3>
<button onClick={() => setGreeting(randomMessage())}>
New Greeting
</button>
</div>
);
}
```
3. Import and use this component on your Home page index.astro.
```astro title="src/pages/index.astro" ins={3,8}
---
import BaseLayout from '../layouts/BaseLayout.astro';
import Greeting from '../components/Greeting';
const pageTitle = "Home Page";
---
<BaseLayout pageTitle={pageTitle}>
<h2>My awesome blog subtitle</h2>
<Greeting messages={["Hi", "Hello", "Howdy", "Hey there"]} />
</BaseLayout>
```
Check the preview in your browser: you should see a random greeting, but the button won't work!
4. Add a second <Greeting /> component with the client:load directive.
```astro title="src/pages/index.astro" ins={9} "client:load"
---
import BaseLayout from '../layouts/BaseLayout.astro';
import Greeting from '../components/Greeting';
const pageTitle = "Home Page";
---
<BaseLayout pageTitle={pageTitle}>
<h2>My awesome blog subtitle</h2>
<Greeting messages={["Hi", "Hello", "Howdy", "Hey there"]} />
<Greeting client:load messages={["Hej", "Hallo", "Hola", "Habari"]} />
</BaseLayout>
```
5. Revisit your page and compare the two components. The second button works because the client:load directive tells Astro to send and rerun its JavaScript on the client when the page loads, making the component interactive. This is called a hydrated component.
Once the difference is clear, remove the non-hydrated Greeting component.
---
import BaseLayout from '../layouts/BaseLayout.astro';
import Greeting from '../components/Greeting';
const pageTitle = "Home Page";
---
<BaseLayout pageTitle={pageTitle}>
<h2>My awesome blog subtitle</h2>
<Greeting messages={["Hi", "Hello", "Howdy", "Hey there"]} />
<Greeting client:load messages={["Hej", "Hallo", "Hola", "Habari"]} />
</BaseLayout>
There are other client: directives to explore. Each sends the JavaScript to the client at a different time. client:visible, for example, will only send the component's JavaScript when it is visible on the page.
Consider an Astro component with the following code:
---
import BaseLayout from '../layouts/BaseLayout.astro';
import AstroBanner from '../components/AstroBanner.astro';
import PreactBanner from '../components/PreactBanner';
import SvelteCounter from '../components/SvelteCounter.svelte';
---
<BaseLayout>
<AstroBanner />
<PreactBanner />
<PreactBanner client:load />
<SvelteCounter />
<SvelteCounter client:visible />
</BaseLayout>
Which of the five components will be hydrated islands, sending JavaScript to the client?
<p> <Spoiler>`<PreactBanner client:load />` and `<SvelteCounter client:visible />` will be hydrated islands.</Spoiler> </p>In what way(s) will the two <PreactBanner /> components be the same? In what way(s) will they be different?
Assume the SvelteCounter component shows a number and has a button to increase it. If you couldn't see your website's code, only the live published page, how would you tell which of the two <SvelteCounter /> components used client:visible?
For each of the following components, identify what will be sent to the browser:
<ReactCounter client:load />
<SvelteCard />