Quando abbiamo deciso di rifare il sito di Basi Software, la scelta più ovvia è stata Next.js. Lo utilizziamo costantemente nei progetti dei nostri clienti. Il team lo conosce alla perfezione.
Abbiamo scelto invece Astro. Ecco perché — e cosa abbiamo imparato.
L’imposta SPA
Le applicazioni a pagina singola hanno spostato il carico di rendering dal server al client. Per le app altamente interattive — dashboard, editor, strumenti collaborativi — si tratta del giusto compromesso. Per un sito di marketing con un modulo di contatto, invece, rappresenta un onere.
La “tassa SPA” viene indicata come:
- JavaScript caricato per interazioni che non avvengono mai — L’utente legge la descrizione del protagonista, scorre la pagina e se ne va. Non ha mai cliccato sul pulsante che attiva la finestra modale. Eppure hai comunque caricato il codice JavaScript della finestra modale.
- Cascate di idratazione — React reidrata l’intero albero prima che sia possibile qualsiasi interazione
- Modifica del layout — l’HTML renderizzato dal server viene sostituito dall’HTML renderizzato dal client, causando un CLS
# Lighthouse on our old Next.js site (production build)
Performance: 71
First Contentful Paint: 1.8s
Total Blocking Time: 340ms
JavaScript bundle: ~280kb (gzipped)
# After migrating to Astro
Performance: 98
First Contentful Paint: 0.6s
Total Blocking Time: 0ms
JavaScript bundle: ~6kb (only the Nav and ContactForm islands)
Cosa significa in realtà l’architettura insulare di Astro
Il termine “isole” è stato coniato da Katie Sylor-Miller di Etsy. L’idea è questa: una pagina altrimenti statica presenta delle “isole” isolate di interattività. Ogni isola si aggiorna in modo indipendente. Tutto il resto viene caricato come HTML senza JavaScript.
---
// Layout.astro — the shell is pure HTML
import Nav from '../components/Nav.astro'; // Static shell + small script
import ContactForm from './ContactForm'; // React island
import HeroSection from './HeroSection.astro'; // Zero JS — static HTML
---
<body>
<!-- Astro component — no framework runtime required -->
<Nav />
<main>
<!-- Static Astro component — ships as HTML, zero runtime cost -->
<HeroSection />
</main>
</body>
Il modulo di contatto è l’unico “framework island” presente qui. La navigazione mantiene il suo comportamento interattivo grazie a un piccolo script del browser, quindi non comporta l’inclusione di React in ogni pagina.
Le direttive che contano
Astro illustra cinque linee guida sull’idratazione. Scegliere quella giusta ha un impatto tangibile:
| Direttiva | Quando idrata | Utilizzo per |
|---|---|---|
client:load | Immediatamente | Navigazione interattiva nella parte superiore della pagina |
client:idle | Quando il browser è inattivo | Componenti sotto la piega |
client:visible | Quando l’elemento entra nel viewport | Componenti lazy |
client:media | Quando la media query corrisponde | Widget solo per dispositivi mobili |
client:only | Solo lato client, nessun SSR | Componenti dipendenti dall’API del browser |
Per la maggior parte dei siti di marketing, client:visible è l’impostazione predefinita corretta per tutto ciò che si trova sotto la piega.
Visualizza le transizioni senza un framework
Uno dei motivi per cui i team scelgono Next.js è il router integrato con le transizioni tra le pagine. Anche Astro dispone di questa funzionalità, tramite il <ClientRouter /> componente e l’API delle transizioni di visualizzazione.
---
import { ClientRouter } from 'astro:transitions';
---
<head>
<ClientRouter />
</head>
/* Custom transition — runs on every page navigation */
::view-transition-old(root) {
animation: fade-out 0.3s ease-in forwards;
}
::view-transition-new(root) {
animation: slide-up 0.4s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
Il transition:persist L’attributo sul Nav fa sì che non venga ricaricato tra una pagina e l’altra: l’isola React rimane attiva, conservando la posizione di scorrimento e lo stato aperto/chiuso.
Raccolte di contenuti per contenuti con sicurezza di tipo
Questo stesso blog è basato sulle raccolte di contenuti Astro — un livello di contenuti validato da Zod e sviluppato principalmente in TypeScript:
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
category: z.string(),
tags: z.array(z.string()).default([]),
}),
});
export const collections = { blog };
Ogni file MDX presente in src/content/blog/ ora è completamente tipizzato. Se in un post manca un campo obbligatorio, la compilazione fallisce — non si tratta di un errore di esecuzione in produzione.
Quando è ancora opportuno scegliere Next.js
Astro non è la risposta a tutto:
- App altamente interattive — se la maggior parte della pagina deve essere reattiva, usa React. Un sito Astro con
client:loadsu ogni componente è peggiore rispetto a Next.js. - Funzionalità in tempo reale — I dashboard in tempo reale, la modifica collaborativa e le interfacce utente che fanno ampio uso di WebSocket trovano la loro collocazione ideale in una vera e propria SPA
- App di grandi dimensioni autenticate — flussi di autenticazione, routing dinamico basato sui dati dell’utente, stato complesso lato client — Next.js ha la meglio in questo ambito
L’euristica: se la maggior parte delle tue pagine è principalmente leggi piuttosto che ha interagito con, Astro è il punto di partenza migliore.
Conclusione
Il ritorno all’architettura multipagina non rappresenta un passo indietro. È piuttosto il riconoscimento del fatto che il modello nativo del web — documenti collegati tramite collegamenti ipertestuali — rimane l’architettura più performante, accessibile e resiliente per i siti incentrati sui contenuti.
Astro rende semplicemente piacevole lavorare in questo modo nel 2026.
Comments
Loading comments…