07. Immagini, font, SEO, performance e deploy
← 06 - Rendering on-demand - adapter, middleware, actions · Indice · successivo → 08 - Reference rapida, errori comuni e migrazione
7.1 Immagini
---
import { Image, Picture } from 'astro:assets';
import foto from '../assets/foto.jpg';
---
<Image src={foto} alt="Descrizione della foto" />
<Picture src={foto} formats={['avif', 'webp']} alt="Descrizione" />Cosa fa <Image /> che un <img> non fa: converte nel formato migliore,
ridimensiona, aggiunge width/height (quindi niente layout shift), genera
srcset quando serve, e mette in cache i risultati tra una build e l’altra.
alt è obbligatorio: senza, la build fallisce. È una scelta di design del
framework, e giusta.
Immagini responsive: stabili dalla 5.10:
export default defineConfig({
image: {
layout: 'constrained', // 'constrained' | 'fixed' | 'full-width'
responsiveStyles: true, // default false: senza, non sono responsive
},
});
responsiveStylesèfalsedi defaultImposti
layoute ti aspetti immagini fluide; non succede niente. Ti serve ancheresponsiveStyles: true(a meno che gli stili te li scriva tu). Con Tailwind 4 invece lascialofalse: i layer di Tailwind hanno specificità più bassa e verrebbero sovrascritti.
Immagini remote: per ottimizzarle devi autorizzarne l’origine, altrimenti vengono servite così come sono.
image: {
domains: ['immagini.example.com'],
remotePatterns: [{ protocol: 'https' }],
}Nel Markdown la sintassi  funziona ed è ottimizzata per le
immagini locali. Nei file .mdx puoi anche usare <Image /> direttamente.
Nelle collections, l’helper image() nello schema ti dà un ImageMetadata
validato a partire da un path nel frontmatter (vedi 04 - Contenuti - Markdown, MDX e content collections).
Gli SVG importati diventano componenti Astro inline, con props width,
height, fill, stroke, comodo per le icone, senza sprite né librerie.
Le immagini in public/ non vengono mai ottimizzate. È il motivo per cui una
foto messa lì “perché era più veloce” pesa 4 MB in produzione.
📖 Images
7.2 Font
API integrata, stabile da Astro 6: scarica i font a build time, genera i fallback ottimizzati (riducono il layout shift) e gestisce il preload.
import { defineConfig, fontProviders } from 'astro/config';
export default defineConfig({
fonts: [{
provider: fontProviders.google(),
name: 'Inter',
cssVariable: '--font-inter',
weights: [400, 600],
subsets: ['latin'],
fallbacks: ['sans-serif'],
}],
});---
import { Font } from 'astro:assets'; // NON da 'astro:fonts'
---
<head>
<Font cssVariable="--font-inter" preload />
</head>
<style is:global>
body { font-family: var(--font-inter), sans-serif; }
</style>Provider disponibili: Google, Adobe, Bunny, Fontshare, Fontsource, Google Icons,
NPM e local (per i tuoi file .woff2). Il vantaggio rispetto al <link> verso
Google Fonts è che i file vengono serviti dal tuo dominio: meno round-trip, e
nessuna richiesta a terzi.
📖 Fonts
7.3 SEO
Sitemap: richiede site configurato:
npx astro add sitemapGenera sitemap-index.xml + sitemap-0.xml. Opzioni utili: filter (per
escludere rotte), changefreq, lastmod, i18n.
robots.txt dinamico, come endpoint:
// src/pages/robots.txt.ts
import type { APIRoute } from 'astro';
export const GET: APIRoute = ({ site }) => {
const sitemap = new URL('sitemap-index.xml', site);
return new Response(`User-agent: *\nAllow: /\nSitemap: ${sitemap.href}\n`);
};RSS:
// src/pages/rss.xml.js
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
export async function GET(context) {
const post = await getCollection('blog');
return rss({
title: 'Il mio sito',
description: 'Note e guide',
site: context.site,
items: post.map((p) => ({
title: p.data.title,
pubDate: p.data.pubDate,
description: p.data.descrizione,
link: `/blog/${p.id}/`,
})),
});
}Poi l’autodiscovery nel layout:
<link rel="alternate" type="application/rss+xml" href={new URL('rss.xml', Astro.site)} />URL canonico:
<link rel="canonical" href={new URL(Astro.url.pathname, Astro.site)} />Tutto questo dipende dal campo site in astro.config.mjs. Senza, Astro.site è
undefined e ti ritrovi con undefined/rss.xml in produzione.
7.4 Performance: cosa controllare davvero
Astro parte bene, ma non è immune. In ordine di impatto:
- Immagini: usa
<Image />, nonpublic/. È il primo posto dove si perdono secondi. - Direttive
client:*: ogniclient:loadè JavaScript nel percorso critico. Chiediti seclient:visiblebasta. Quasi sempre basta. - Font: usa la Fonts API con
preloadsul font del corpo testo, e nient’altro. - Script di terze parti: analytics, chat, embed. Sono spesso il 90% del
JavaScript di un sito Astro.
@astrojs/partytownli sposta in un web worker. - Prefetch:
prefetch: truein config, o automatico con<ClientRouter />. Fa sembrare la navigazione istantanea a costo quasi zero.
Verifica sempre sulla build, non in dev: astro build && astro preview, poi
Lighthouse. Il dev server ha caratteristiche di performance completamente diverse.
7.5 Build e deploy
astro build # → dist/
astro preview # serve dist/ localmenteSenza adapter: dist/ contiene HTML e asset, da caricare su qualunque hosting
statico (GitHub Pages, Netlify, Cloudflare Pages, un VPS con nginx, S3).
Con adapter: dist/client/ (asset pubblici) e dist/server/ (il codice server,
entry dist/server/entry.mjs).
Opzioni che tornano utili:
export default defineConfig({
site: 'https://esempio.it',
base: '/sottocartella', // per GitHub Pages su repo non-root
build: {
format: 'directory', // /pagina/index.html - default
assets: '_astro',
assetsPrefix: 'https://cdn.esempio.it', // se servi gli asset da CDN
},
});Comandi nuovi in Astro 7 utili in CI o in locale:
astro dev --background+astro dev status | stop | logs [--follow]astro dev --ignore-lock(7.1) per più dev server in paralleloastro preview --background(7.2)--jsonper log strutturatiastro build --forceper svuotare la cache del content layer
Astro documenta oltre 30 piattaforme di deploy con guide dedicate: 📖 Deploy your site
Checklist prima di pubblicare
-
siteimpostato inastro.config.mjs -
astro buildsenza warning -
astro checkpulito - 404 personalizzata presente e funzionante in
preview - sitemap e RSS raggiungibili
-
<title>e<meta name="description">diversi su ogni pagina - Lighthouse eseguito sulla build, non sul dev server
- test su mobile reale, non solo nel simulatore
Esercizi
- Sostituisci tutti gli
<img>di un tuo progetto con<Image />e confronta il peso totale della pagina prima e dopo. - Attiva la Fonts API con un font e verifica in Network che il
.woff2sia servito dal tuo dominio. - Aggiungi sitemap + RSS + canonical, poi apri i file generati in
dist/e leggili. - Fai girare Lighthouse su
astro previewe scrivi le prime tre cose da migliorare.