Build your first Astro island
本頁內容尚未翻譯。
Use a Preact component to greet your visitors with a randomly-selected welcome message!
準備好……
- Add Preact to your Astro project
- Include Astro islands (Preact
.jsxcomponents) on your home page - Use
client:directives to make islands interactive
Add Preact to your Astro project
If it’s running, quit the dev server to have access to the terminal (keyboard shortcut: Ctrl + C).
Add the ability to use Preact components in your Astro project with a single command:
npx astro add preactpnpm astro add preactyarn astro add preactFollow the command line instructions to confirm adding Preact to your project.
Include a Preact greeting banner
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.
Create a new file in
src/components/namedGreeting.jsxNote the
.jsxfile extension. This file will be written in Preact, not Astro.Add the following code to
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> ); }Import and use this component on your Home page
index.astro.--- 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!
Add a second
<Greeting />component with theclient:loaddirective.--- 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>Revisit your page and compare the two components. The second button works because the
client:loaddirective 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>
Analyze the Pattern
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?
In what way(s) will the two
<PreactBanner />components be the same? In what way(s) will they be different?Assume the
SvelteCountercomponent 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 usedclient:visible?
Test your knowledge
For each of the following components, identify what will be sent to the browser:
<ReactCounter client:load /><SvelteCard />