Great question! You're describing two slightly different patterns, and it's worth clarifying what each one does before picking the right tool.
What Server Islands Do
Server islands (server:defer) are designed to defer rendering of a component at page load time — they render in the background while the rest of the page loads immediately. They are not triggered by user interaction (like a click). They load automatically when the page is requested, just independently from the main page render. [server islands guide]
So server islands alone won't solve your "fetch on click" use case.
What You Actually Want: Page Partials + HTMX
For your use case — render a component only when a user clicks a card — the right Astro feature is Page Partials, which pair well with htmx. [page partials]
Here's how it works:
- Create a partial
.astro page that fetches your CMS data and renders the panel content.
- Use htmx on your card to request that partial on click and inject it into a panel.
Example
src/pages/partials/card-detail.astro — fetches from your CMS on demand:
---
export const partial = true;
// This only runs when the partial is requested (i.e., on click)
const response = await fetch('<https://your-cms.com/api/item/123'>);
const data = await response.json();
---
<div>
<h2>{data.title}</h2>
<p>{data.description}</p>
</div>
src/pages/index.astro — triggers the fetch on click: