• Mutimedia Web la Web Agency Italiana. Contattateci per preventivi gratuiti e consulenze nello sviluppo del vostro sito web o app Ios e Android. Professinalità e assistenza garatite!
    Immagini dei quadri e opere di: Giuseppe Lattanzio

  • Social

    [easy-social-share buttons="facebook,twitter,pinterest,linkedin,digg,stumbleupon,vk,tumblr,print,mail,del,reddit,whatsapp" counters=0 hide_names="force" template="grey-blocks-retina"]
  • WEB AGENCY

  • Sede Principale

    Multimedia Web

    Blog Studio Web

    Studio Web

    Sede a Venezia

    Web Agency Venezia

    Sede a New York

    Nyc Web Design

    Sede International

    Web Designer International

    Sito Demo One Page

    Spaghetti Web

    Landing page

    Savinus

  • smartphone

    Trovaci sul tuo smartphone

  • web-designer-ancona
  • AGENZIA WEB ITALIA

Home / News / Un blog dinamico con Astro e htmx | JS

Un blog dinamico con Astro e htmx | JS


Quando gli articoli del blog cominciano ad essere numerosi, generare tutti gli elementi della collezione al momento della generazione della pagina potrebbe non essere la soluzione ottimale in termini di prestazioni.

Per ottimizzare le prestazioni del blog, dobbiamo adottare un approccio dinamico, generando il contenuto solo al momento della richiesta dell’utente. Dobbiamo passare dal rendering statico (SSG) al rendering dinamico (SSR).

Rendering on-demand in un blog dinamico con Astro e htmx

Di default, un sito Astro è statico. Ciò vuol dire che il rendering avviene al momento della build. Quando il client dell’utente invia una richiesta al server esso fornirà pagine statiche. Questo permette di ottenere siti dalle prestazioni notevoli. Non vi sono infatti database da interrogare o task server side da eseguire.

Tuttavia, quando è necessario eseguire operazioni lato server, come ad esempio il recupero di dati da un database, oppure una nuova interrogazione di una collezione di contenuti, è necessario passare ad una modalità di rendering Server-Side. Ciò in modo che le pagine vengano generate dinamicamente al momento della richiesta dell’utente.

La modalità SSR (Server-Side Rendering) richiede un server Node.js in esecuzione in produzione per generare le pagine dinamicamente alla richiesta dell’utente (rendering on-demand). Questo a differenza della modalità SSG (Static Site Generator) che produce file statici distribuibili su qualsiasi hosting statico.

È necessario anche aggiungere un adattatore che abiliti il rendering on-demand nel nostro progetto Astro. Qui utilizzeremo l’adattatore di Node.js, ma Astro supporta anche adattatori, come Cloudflare, Vercel e Netlify. Per maggiori informazioni, si veda la documentazione online.

Interrompiamo l’esecuzione del server di sviluppo, se è in funzione, e digitiamo nel terminale dei comandi quanto segue:

npx astro add node

Il rendering on-demand delle pagine

Questo ci permette di abilitare il rendering on-demand per singola pagina o per l’intero sito. Al termine dell’operazione, apriamo il file astro.config.mjs e verifichiamo che contenga il seguente codice:

import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
	adapter: node({
		mode: 'standalone',
	}),
	vite: {
		plugins: [tailwindcss()]
	}
});
  • import node from '@astrojs/node' importa l’adattatore di node per il Server-Side Rendering;
  • adapter: node(...) fa sì che il sito non sia statico ma dinamico, generato on-demand. La modalità standalone crea un pacchetto server completo di tutte le dipendenze e autonomo, in modo che possa essere eseguito su qualsiasi macchina su cui sia installato Node.js.

Verificato che il file contenga le istruzioni descritte, l’ultimo step per rendere dinamiche le pagine del progetto è aggiungere la seguente istruzione ad ogni singola pagina o endpoint che vogliamo rendere on-demand:

export const prerender = false;

Questa istruzione abilita il rendering dinamico (SSR) per una specifica pagina o endpoint. Le pagine senza questa istruzione rimarranno statiche. Questo permette di adottare un approccio ibrido con siti parzialmente dinamici. Più avanti vedremo in quali pagine del nostro progetto inserire questo codice.

Una pagina di archivio dinamica

Creiamo una nuova sezione del sito che rispecchi il blog creato nelle lezioni precedenti. Se il primo blog era statico, creato con l’integrazione di Alpine.js, questa nuova sezione, che chiameremo Archive, è generata dinamicamente con l’integrazione di htmx.

Creiamo, quindi, la cartella /src/pages/archive. All’interno di questa cartella aggiungiamo poi due file:

  • index.astro
  • load-more.astro

Il primo file conterrà il codice che genera l’HTML da fornire all’utente quando accede alla pagina di archivio.

Apriamo il file index.astro e aggiungiamo il seguente frontmatter:

---
import { getCollection, type CollectionEntry } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
import ArticleCard from '../../components/ArticleCard.astro';
const POSTS_PER_PAGE = 3;
const sortedPosts = (await getCollection('blog')).sort(
	(a: CollectionEntry<'blog'>, b: CollectionEntry<'blog'>) =>
		b.data.pubDate.getTime() - a.data.pubDate.getTime()
);
const initialPosts: CollectionEntry<'blog'>[] = sortedPosts.slice(0, POSTS_PER_PAGE);
const hasMore: boolean = sortedPosts.length > POSTS_PER_PAGE;
---
  • Le prime tre istruzioni importano le dipendenze necessarie;
  • POSTS_PER_PAGE stabilisce il numero di articoli da visualizzare per pagina;
  • sortedPosts è un array di oggetti CollectionEntry<'blog'> ordinati per data di pubblicazione;
  • initialPosts è un array degli articoli iniziali da mostrare nella pagina di archivio, dall’indice 0 a POSTS_PER_PAGE;
  • hasMore è un booleano impostato a true se sortedPosts.length > POSTS_PER_PAGE, ossia se il numero totale di post è maggiore del numero di post per pagina.

Nel successivo markup, utilizziamo i dati generati nel frontmatter per generare la struttura HTML della pagina. Come già detto, si tratta dei primi contenuti visibili al momento del caricamento.

<Layout title="Archivio Articoli" description="Caricamento progressivo con HTMX.">
	<h1 class="text-4xl font-extrabold text-gray-900 mb-8">Archivio</h1>
	<div id="posts-container" class="grid gap-10">
		{initialPosts.map(post => (
			<ArticleCard post={post} />
		))}
		<div id="load-more-row" class="mt-12 text-center">
			<!-- Mostra il pulsante solo se ci sono altri post -->
			{hasMore && (
			<button
				type="button"
				hx-get="/archive/load-more"
				hx-vals='{"page": 2}'
				hx-target="#load-more-row"
				hx-swap="outerHTML"
				class="bg-blue-600 text-white py-3 px-6 rounded-lg hover:bg-blue-700"
			>
				Carica Altri Articoli
			</button>
			)}
		</div>
	</div>
</Layout>

Analisi del codice

Vediamo gli elementi principali di questo blocco di codice:

  • Tutto il contenuto della pagina è racchiuso nel componente Layout. Quindi, l’header, il footer e i meta tag saranno gli stessi del blog. Gli attributi title e description sono le proprietà che vengono passate verso l’alto al componente.
  • La div#post-container è il contenitore di tutti gli articoli.
  • initialPosts.map itera tra gli elementi dell’array initialPosts che in questo esempio contiene tre articoli.
  • <ArticleCard post={post} /> renderizza il componente ArticleCard, passando ad ogni istanza la proprietà post.
  • La successiva div#load-more-row è il contenitore del pulsante “Carica Altri Articoli”.
  • Se hasMore è true, viene generato il pulsante “Carica Altri Articoli” con gli attributi htmx:
  • hx-get invia una richiesta GET all’URL specificato.
  • hx-vals aggiunge i parametri da trasmettere con l’URL. {"page": 2} specifica la pagina iniziale da caricare. Avremmo potuto fare la stessa cosa aggiungendo una variabile alla querystring (/archive/load-more?page=2).
  • hx-target specifica l’elemento del DOM che riceverà il codice della risposta. Nel nostro esempio è lo stesso contenitore del pulsante.
  • hx-swap stabilisce come aggiornare l’elemento target. In questo caso, outerHTML fa sì che venga sostituito l’intero elemento target, incluso l’elemento stesso.

Ora possiamo aggiungere un nuovo link al menu di navigazione nel layout generale del sito. Apriamo il file /src/layouts/Layout.astro e modifichiamo il menu come segue:

<nav class="max-w-4xl mx-auto px-6 py-4 flex justify-between items-center">
	<a href="https://www.html.it/" class="text-xl font-bold text-purple-700">{title}</a>
	<div class="flex items-center gap-x-6">
		<a href="https://www.html.it/" class="text-gray-600 hover:text-purple-700 mr-4">Home</a>
		<a href="http://www.html.it/blog" class="text-gray-600 hover:text-purple-700">Blog</a>
		<a href="http://www.html.it/archive" class="text-gray-600 hover:text-purple-700">Archive</a>
	</div>
</nav>
Archivio di articoli pronto per il rendering on-demand

Archivio di articoli pronto per il rendering on-demand

Dopo questo approfondimento dedicato alla creazione di un blog dinamico con Astro e htmx, nella prossima lezione, creeremo l’endpoint /archive/load-more.astro per gestire il caricamento dinamico dei post successivi, integrando htmx con Astro SSR per generare una paginazione dinamica e scalabile.

Se vuoi aggiornamenti su Un blog dinamico con Astro e htmx inserisci la tua email nel box qui sotto:



Source link