Ask
71
@mulch_mule ·

new to astro — do people really give every interactive bit its own island Islands

Coming from Next. Building a marketing site plus a small dashboard section in Astro 5.

I've got a nav with a mobile menu, a theme toggle, a newsletter form, a pricing calculator and an FAQ accordion. Right now each is a separate .svelte file with client:load on it, so the page mounts five separate components with five separate roots.

That feels wrong? In Next it'd be one tree. Is this genuinely how people build these, or have I misunderstood the model?

10 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @tomato_tobin · 6mo ago · 3 replies

    That is how it works, yes. But you've got the directives wrong and that's where the cost actually is.

    Five islands is fine — they're independent little apps and that's the point. Five client:load is not fine, because it hydrates everything before anyone interacts with anything.

    • mobile menu: client:media="(max-width: 768px)" — desktop never downloads it
    • theme toggle: this should be six lines of inline script, not a component. A framework island to toggle a class is silly, and you want it running before paint anyway to avoid the flash
    • newsletter form: client:visible, it's in the footer
    • FAQ accordion: <details> and <summary>, zero JS
    • pricing calculator: client:idle or client:visible depending on where it sits

    You'll go from around 140 KB of JS to under 30 and the page will feel identical.

    88
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @mulch_mule · 6mo ago

      The FAQ one is embarrassing. I have an entire Svelte component doing what <details> does natively.

      27
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @drainfield_dez · 6mo ago

      Everyone does that once. The Astro reflex is 'can the platform already do this', and the answer is yes far more often than a React habit expects.

      22
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @muslin_mira · 6mo ago · 2 replies

    The mental shift is that in Next you have one app that happens to emit some HTML, and in Astro you have HTML that happens to contain some apps. Once that clicks, five roots stops feeling wrong.

    The real constraint is that islands can't share reactive state through props, because they're separate roots. If the calculator needs to know the theme, that goes through something outside the framework — a nanostore, a custom event, a data attribute on <html>. And if you find yourself wanting a lot of cross-island state, that's the signal that section should be one bigger island.

    46
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @mulch_mule · 6mo ago

      That's the thing I was actually worried about and no docs page says it that plainly. Thanks.

      18
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @edge_runtime_bo · 6mo ago

    For the dashboard section, don't island it. Authenticated app pages with lots of interconnected state are exactly the case where you make the whole route one island — or just a client-rendered subtree — and stop fighting the model. Astro is quite happy to be a static marketing site and an app shell in the same project.

    29
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @flux_and_solder · 6mo ago

    Run astro build and look at what actually ships per page. That output tells you more than any advice in this thread — if a page you thought was static is pulling 60 KB, something on it has a directive you forgot about.

    12
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @cookie_domain_al · 6mo ago

    Small thing that will bite you: client:only exists and it is not the same as client:load. If a component touches window at module scope you'll get a build error under client:load, because Astro still server-renders it once. client:only="svelte" skips that render. Worth knowing before you lose an hour to "window is not defined".

    17
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @nightbus_nina · 6mo ago · 2 replies

    honestly if half your site is a dashboard you might just want next. islands are great until they aren't

    11
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @muslin_mira · 6mo ago

      Or run both — Astro for marketing and docs, a separate app for the dashboard, shared design tokens. Two deploys, but each half is built with the right thing. Plenty of people ship it that way.

      9
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report