# HTMX con ASP.NET Core Partials: Il Server-Side Rinascimento

<datetime class="hidden">2025-11-28T12:00</datetime>

<!--category-- HTMX, ASP.NET Core, Web Development, HTMX.NET -->
## Introduzione

Se hai costruito le tradizionali applicazioni ASP.NET Core MVC , si conosce il problema: che temuto " fare clic su flash " quando gli utenti navigano tra le pagine . Ricarica pagina completa , il browser cromata flickering , contenuti saltando in giro come la nuova pagina rende . Funziona , ma non *ensazione di* Moderno.

La tecnica di restituire frammenti HTML parziali dal server e di scambiarli nel DOM risolve questo - e non è nuova. Ho usato questo modello fin dai giorni jQuery, e anche prima con vaniglia JavaScript e `XMLHttpRequest`. Quello che è cambiato è come *elegante* E' diventato con l'HTMX.

HTMX ci offre un modo dichiarativo per fare quello che abbiamo sempre fatto: restituire HTML fornito dal server e scambiarlo nella pagina. Niente più scrittura JavaScript personalizzato per ogni interazione. Niente più scelta tra lo sviluppo "proprio" lato server e l'esperienza utente fluida. Con HTMX, otteniamo entrambi.

> **Articolo Companion:** Questo articolo si concentra sul lato ASP.NET Core integrazione. Per una profonda immersione in eventi HTMX, ciclo di vita, e estensioni personalizzate, vedere il mio articolo compagno: [A Whistle-stop Tour di estensioni HTMX e l'utilizzo di HTMX con ASP.NET Core](/blog/htmxandaspnetcore).

In questo articolo, vi mostrerò come HTMX si integra splendidamente con ASP.NET Core parziale, come il eccellente **HTMX.NET** biblioteca rende ancora meglio, e come il mio [per lo piùlucid.pagingtaghelper](https://github.com/scottgal/mostlylucid.pagingtaghelper) Il pacchetto NuGet utilizza HTMX fornisce una potente paginazione con una configurazione minima.

L'approccio è framework-agnostico troppo - Django ha aggiunto frammenti di template nella versione 6.0, Rails ha Turbo Frames, e l'ecosistema web più ampio sta abbracciando HTML-over-the-wire pattern. E 'un buon momento per essere la costruzione di applicazioni dotate di server.

[TOC]

## Che cos'è HTMX?

HTMX è una libreria che consente di accedere alle moderne funzionalità del browser direttamente da HTML, piuttosto che scrivere JavaScript. Si estende HTML con attributi che consentono di effettuare richieste AJAX, scambiare contenuti e creare interazioni ricche - il tutto senza lasciare il tuo markup.

Gli attributi chiave che userai più spesso:

- `hx-get`, `hx-post`, `hx-put`, `hx-delete` - Effettuare richieste HTTP
- `hx-target` - Specificare dove mettere la risposta
- `hx-swap` - Controllare come il contenuto viene scambiato (HTML interno, HTML esterno, ecc.)
- `hx-trigger` - Definire cosa innesca la richiesta (click, cambio, carico, ecc.)
- `hx-push-url` - Aggiornare l'URL del browser senza ricaricare l'intera pagina

Ecco la bellezza: stai ancora scrivendo codice server-side, restituendo server-rendered HTML. Nessuna API JSON, nessun modello client-side, nessun build pipeline. Solo un buon vecchio stile HTML sopra il filo.

## Un modello vecchio come AJAX se stesso

Prima di HTMX, abbiamo ottenuto lo stesso effetto con molta più cerimonia. Ecco come sono stati gli aggiornamenti parziali nell'era jQuery:

```javascript
// jQuery circa 2010
$('#load-more').click(function() {
    $.ajax({
        url: '/posts/page/' + currentPage,
        success: function(html) {
            $('#posts-container').append(html);
            currentPage++;
        }
    });
});
```

E anche prima, con vaniglia JavaScript:

```javascript
// Vanilla JS circa 2005
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        document.getElementById('content').innerHTML = xhr.responseText;
    }
};
xhr.open('GET', '/partial-content', true);
xhr.send();
```

Il modello lato server era identico - restituire frammenti HTML, scambiarli nel DOM. HTMX sposta solo questa logica da JavaScript in attributi HTML, rendendolo dichiarativo, scovabile, e molto meno error-prone. L'innovazione non è la tecnica; è l'interfaccia.

Gli sviluppatori di ASP.NET lo fanno da anni. AggiornarePanel in WebForms (2005), `PartialView()` in MVC dal primo giorno, `Html.RenderAction()` per i frammenti composabili - la capacità è sempre stata presente. Ciò che ci mancava era un modo elegante e standardizzato per collegarlo sul lato client. HTMX riempie perfettamente questo spazio.

Anche l'industria più ampia sta riscoprendo questi modelli. Termini come "SSR" (Server-Side Rendering), "hybrid rendering" e "ilands architecture" stanno essenzialmente descrivendo ciò che i framework sul lato server hanno sempre fatto, ma con occhi nuovi. È la validazione che le scale di approccio rese dal server, le prestazioni e - con gli strumenti giusti - forniscono un'eccellente esperienza utente.

## Impostazione di HTMX in ASP.NET Core

In primo luogo, includere HTMX nel vostro layout. È possibile utilizzare una CDN o servirla localmente:

```html
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
```

Niente build step, niente installazione di npm, niente configurazione di webpack.

## Alpine.js: il componente Client-Side

Per la reattività lato client (mostrare/nascondere elementi, stati di commutazione, stato UI locale), [Alpine.js](https://alpinejs.dev/) completa perfettamente HTMX. A soli 15KB gzipped, fornisce Vue/React-like reattività dichiarativa senza il bloat.

```html
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
```

Ecco come lavorano insieme:

```razor
<div x-data="{ open: false }">
    <button x-on:click="open = !open">Toggle</button>
    <div x-show="open" x-transition>
        <button hx-get="/api/data" hx-target="#results">Load Data</button>
    </div>
</div>
```

Alpine gestisce l'interfaccia utente locale (il toggle), HTMX gestisce le chiamate del server (il recupero dati). In questo articolo, vedrete questo modello - Alpine per la reattività del client, HTMX per le interazioni del server.

## La libreria HTMX.NET

[Khalid Abuhakmeh](https://khalidabuhakmeh.com/about)'s [HTMX.NET](https://github.com/khalidabuhakmeh/Htmx.Net) libreria fornisce l'integrazione core ASP.NET di prima classe. `Htmx` e `Htmx.TagHelpers` NuGet pacchetti, si sente nativo di .NET e rende lavorare con HTMX un piacere assoluto. Troverete più di Khalid eccellente lavoro open-source sul suo [GitHubCity name (optional, probably does not need a translation)](https://github.com/khalidabuhakmeh).

### Installazione

```bash
dotnet add package Htmx
dotnet add package Htmx.TagHelpers
```

Nella tua `_ViewImports.cshtml`:

```razor
@addTagHelper *, Htmx.TagHelpers
```

### Il metodo di estensione IsHtmx()

La caratteristica più utile è la `Request.IsHtmx()` metodo di estensione, che ti dice se la richiesta è arrivata da HTMX. Questo consente di restituire una vista completa o solo una parziale:

```csharp
[HttpGet]
public async Task<IActionResult> Index(int page = 1, int pageSize = 20)
{
    var posts = await blogViewService.GetPagedPosts(page, pageSize);

    if (Request.IsHtmx())
        return PartialView("_BlogSummaryList", posts);

    return View("Index", posts);
}
```

Questo modello è assolutamente brillante. Una singola azione del controller serve entrambi:

- Caricamento completo della pagina (quando gli utenti navigano direttamente o aggiornano)
- Aggiornamenti parziali (quando HTMX fa la richiesta)

Nessun endpoint API separato, nessuna logica duplicata, nessuna serializzazione JSON.

> **Un errore comune:** Molti sviluppatori ASP.NET pensano che è necessario il `_` prefisso (come `_BlogSummaryList.cshtml`) per ottenere il rendering parziale. `PartialView()` metodo stesso dice ASP.NET Core di saltare il layout - sta dicendo "dimentica il layout, basta renderizzare questo bit." È possibile utilizzare `return PartialView("SearchResults", model)` con un file di visualizzazione regolare e funziona perfettamente. La convenzione di sottolineatura è nata da pagine web ASP.NET (WebMatrix) dove ha impedito che i file fossero serviti direttamente tramite URL - ma MVC ha sempre protetto tutte le viste dall'accesso diretto comunque. E 'solo una convenzione di denominazione per aiutare a identificare le viste *destinati* come parziali.

### Helper per tag HTMX.NET

HTMX.NET fornisce aiutanti di tag che rendono lavorare con i controller più puliti. Invece di scrivere stringhe di route, è possibile utilizzare riferimenti fortemente digitati:

```razor
<button
    hx-controller="Comment"
    hx-action="GetCommentForm"
    hx-post
    hx-target="#commentform">
    Reply
</button>
```

Questo genera il percorso corretto usando il sistema di routing di ASP.NET Core. Se rinomini il controller o l'azione, il tuo IDE lo catturerà. Molto meglio delle stringhe magiche!

Ecco un vero esempio dal sistema di commento di questo blog:

```razor
<button
    class="btn btn-outline btn-sm mb-4"
    hx-action="Comment"
    hx-controller="Comment"
    hx-post
    hx-vals
    x-on:click.prevent="window.mostlylucid.comments.setValues($event)"
    hx-on="htmx:afterSwap: window.scrollTo({top: 0, behavior: 'smooth'})"
    hx-swap="outerHTML"
    hx-target="#commentform">
    Comment
</button>
```

Notare come HTMX gioca bene con Alpine.js (`x-on:click.prevent`) per quei bit occasionali di interattività client-side.

### Altri helper HTMX.NET

La biblioteca fornisce inoltre:

- `Request.IsHtmxNonBoosted()` - Controllare se si tratta di una richiesta HTMX ma non potenziato
- `Request.IsHtmxRefresh()` - Controlla se è una richiesta di ripristino della cronologia
- Helper di risposta per intestazioni HTMX (innesti, reindirizzamenti, ecc.)

## Esempio di Real-World: Cerca con Partials

Ecco il controllore di ricerca da questo blog, mostrando il modello di ritorno a tre livelli:

```csharp
[HttpGet]
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request", "pagerequest" })]
public async Task<IActionResult> Search(
    string? query,
    int page = 1,
    int pageSize = 10,
    [FromHeader] bool pagerequest = false)
{
    var searchModel = await BuildSearchModel(query, page, pageSize);

    if (pagerequest && Request.IsHtmx())
        return PartialView("_SearchResultsPartial", searchModel.SearchResults);

    if (Request.IsHtmx())
        return PartialView("SearchResults", searchModel);

    return View("SearchResults", searchModel);
}
```

Tre percorsi di ritorno per tre scenari:

1. Richieste di paginazione - parziale minimo (solo l'elenco dei risultati)
2. Modifiche del filtro - sezione parziale (risultati con filtri)
3. Navigazione diretta - pagina intera (layout + tutto)

La vista parziale (`_SearchResultsPartial.cshtml`) utilizza l'helper del tag paging:

```razor
@model Mostlylucid.Models.Blog.PostListViewModel
<div class="pt-2" id="content">
    @if (Model.Data?.Any() is true)
    {
        <div class="inline-flex w-full items-center justify-center pb-4">
            @if (Model.TotalItems > Model.PageSize)
            {
                <pager
                    x-ref="pager"
                    link-url="@Model.LinkUrl"
                    hx-boost="true"
                    hx-target="#content"
                    hx-swap="show:none"
                    page="@Model.Page"
                    page-size="@Model.PageSize"
                    total-items="@Model.TotalItems"
                    hx-headers='{"pagerequest": "true"}'>
                </pager>
            }
        </div>
        @foreach (var post in Model.Data)
        {
            <partial name="_ListPost" model="post"/>
        }
    }
</div>
```

Spezzare l'helper del tag del pager:

- `hx-boost="true"` - Intercetta collegamenti, converte in AJAX
- `hx-target="#content"` - Dove iniettare la risposta
- `hx-headers='{"pagerequest": "true"}'` - Intestazione personalizzata dice al controller che è paginazione
- Il controllore controlla `Request.IsHtmx() && pagerequest` per restituire solo il minimo parziale

## Il pacchetto per lo piùlucid.pagingtaghelper

Ho scritto [per lo piùlucid.pagingtaghelper](https://github.com/scottgal/mostlylucid.pagingtaghelper) per evitare il codice di paginazione ripetitivo. E 'HTMX-primo ma funziona senza JavaScript troppo.

### Installazione

```bash
dotnet add package mostlylucid.pagingtaghelper
```

Aggiungi a `_ViewImports.cshtml`:

```razor
@addTagHelper *, mostlylucid.pagingtaghelper
```

### Caratteristiche chiave

Attuazione `IPagingModel<T>` E hai finito:

```csharp
public class BasePagingModel<T> : IPagingModel<T> where T : class
{
    public int Page { get; set; }
    public int TotalItems { get; set; }
    public int PageSize { get; set; }
    public string LinkUrl { get; set; }
    public List<T> Data { get; set; }
}
```

**Quello che ottieni**

- Configurazione zero richiesta
- Framework multipli dell'interfaccia utente (TailwindCSS + DaisyUI, Bootstrap 5, viste personalizzate)
- Supporto modalità oscura
- 8 lingue integrate
- Intestazioni ordinabili, selettori delle dimensioni della pagina
- Miglioramento progressivo (funziona senza JavaScript)
- Supporto token di continuazione per database NoSQL

L'helper tag genera collegamenti che mantengono stringhe di query, supportano le intestazioni personalizzate e si integrano senza soluzione di continuità con HTMX (vedi l'esempio sopra).

## Diagramma di flusso HTMX

Ecco come si integra l'intero sistema:

```mermaid
graph TB
    A[Browser] -->|"Initial page load"| B[Controller Action]
    B -->|"Request.IsHtmx() = false"| C[Return Full View]
    C --> D[Render Layout + Partial]

    A -->|"User clicks pagination/filter"| E[HTMX Request]
    E -->|"hx-get with headers"| F[Same Controller Action]
    F -->|"Request.IsHtmx() = true"| G{Check Headers}
    G -->|"pagerequest header"| H[Return Minimal Partial]
    G -->|"No special header"| I[Return Section Partial]

    H --> J[Swap Content in Target]
    I --> J

    J -->|"User clicks another link"| E

    style B stroke:#333,stroke-width:2px
    style F stroke:#333,stroke-width:2px
    style C stroke:#0066cc,stroke-width:2px
    style H stroke:#00cc66,stroke-width:2px
    style I stroke:#00cc66,stroke-width:2px
```

## Rispetto ad altri quadri

### Frammenti modello Django

Django ha aggiunto un corretto rendering parziale di template nella versione 6.0 (dicembre 2024) con frammenti di template. Prima di allora, gli sviluppatori di Django usavano tipicamente tag di inclusione o pacchetti di terze parti come django-render-block. ASP.NET Core ha avuto `PartialView()` dalla versione 1.0 nel 2016 - framework diversi, timeline diverse, ma la stessa destinazione: frammenti HTML per HTMX.

### Rails Turbo Frames

Ruby on Rails ha Turbo Frames (parte di Hotwire), che è simile nello spirito:

```erb
<%= turbo_frame_tag "posts" do %>
  <%= render @posts %>
<% end %>
```

La differenza è che Turbo richiede specifici frame marker su richiesta e risposta. HTMX è più flessibile - qualsiasi endpoint può restituire qualsiasi HTML, e si decide dove va con `hx-target`.

### Phoenix LiveView

Phoenix LiveView di Elixir adotta un approccio diverso con connessioni WebSocket persistenti e stato lato server:

```elixir
def handle_event("load_more", _params, socket) do
  {:noreply, assign(socket, posts: load_more_posts())}
end
```

LiveView è brillante per le applicazioni in tempo reale, ma richiede l'infrastruttura WebSocket e la memoria del server per le connessioni. HTMX utilizza semplice vecchio HTTP - apolide, cacheable, scalabile. Per un blog, questo è perfetto.

## Considerazioni sulle prestazioni

**Caching di output**: La `OutputCache` attributo varia per `hx-request` intestazione, caching pagine intere e parziali separatamente:

```csharp
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request", "pagerequest" })]
```

**Efficienza della rete**: Server-rendered HTML è spesso più piccolo di JSON + client-side template, richiede meno viaggi, e cache correttamente.

**Dimensione del bundle**: HTMX (14KB) + optional Alpine.js (15KB) + paging tag helper (0KB, lato server) = sotto i 30KB totali. Confronta quello con una tipica applicazione React (200KB+).

## Modelli avanzati

**Aggiornamenti ottimizzati dell'interfaccia utente** - Combina HTMX e Alpine per un feedback immediato:

```razor
<div x-data="{ count: @Model.CommentCount }">
    <button hx-post="/comment/like" x-on:click="count++" hx-on::after-request="count = $event.detail.xhr.response">
        Likes: <span x-text="count"></span>
    </button>
</div>
```

Il conteggio aggiorna immediatamente (ottimistico), quindi sincronizza con la risposta del server.

**Scambi fuoribordo** - Aggiornare più sezioni di pagina da una risposta:

```razor
<div id="main-content"><!-- Main response --></div>
<div id="notification-count" hx-swap-oob="true"><span>5 new</span></div>
```

Perfetto per i badge di notifica, per il conteggio dei carrelli, ecc. Copro questo modello in profondità [Mostrando Toast e Scambi con HTMX](/blog/showingtoastandswappingwithhtmx).

**Modelli Client-Side con WebAPI** - A volte si desidera un'esperienza intermedia: HTML fornito dal server per la maggior parte delle cose, ma JSON da una WebAPI per specifici contenuti dinamici. [estensione client-side-templates](https://htmx.org/extensions/client-side-templates/) ti permette di fare esattamente questo:

```html
<script src="https://unpkg.com/htmx-ext-client-side-templates@2.0.0/client-side-templates.js"></script>
<script src="https://unpkg.com/mustache@latest"></script>

<div hx-ext="client-side-templates">
    <template id="post-template" type="text/mustache">
        {{#posts}}
        <div class="post">
            <h3>{{title}}</h3>
            <p>{{excerpt}}</p>
        </div>
        {{/posts}}
    </template>

    <button hx-get="/api/posts"
            hx-target="#post-list"
            mustache-template="post-template">
        Load Posts
    </button>
    <div id="post-list"></div>
</div>
```

Questo approccio funziona con i modelli di Baffetti, Manubri o Nunjucks. Il WebAPI restituisce JSON, ma HTMX gestisce il lato client rendering. È particolarmente utile quando si dispone di un'API esistente o è necessario condividere i dati con le applicazioni mobili. Per maggiori dettagli sulle estensioni HTMX, tra cui client-side-template, vedere [l'articolo di accompagnamento](/blog/htmxandaspnetcore).

## & Suggerimenti Gotchas

**Strumento di debug:** Installare il [Estensione debug HTMX](https://chromewebstore.google.com/detail/htmx-debugger/) - mostra ogni richiesta, risposta e scambio in tempo reale.

### CSRF TokensCity name (optional, probably does not need a translation)

I token antiforgery di ASP.NET Core necessitano di un trattamento speciale con AJAX. HTMX.NET fornisce diverse opzioni pulite. `HtmxAntiforgeryScriptEndpoint`:

```csharp
// In Program.cs
app.MapHtmxAntiforgeryScript();
```

```html
<!-- In your layout head -->
<script src="@HtmxAntiforgeryScriptEndpoints.Path" defer></script>
```

O utilizzare l'helper tag: `<meta name="htmx-config" includeAspNetAntiforgeryToken="true" />`. Vedi [L'articolo di Khalid su HTMX Anti-Forgery Tokens](https://khalidabuhakmeh.com/htmx-requests-with-aspnet-core-anti-forgery-tokens) per i dettagli completi.

### Alpine.js @ Shorthand in Razor

Alpine'sCity name (optional, probably does not need a translation) `@click` cortocircuito in conflitto con il rasoio `@` sintassi. Usare invece la forma esplicita:

```razor
<button x-on:click="doSomething()">Click me</button>  <!-- Instead of @click -->
<div x-bind:class="isOpen ? 'block' : 'hidden'"></div>  <!-- Instead of :class -->
```

O scappare con `@@click`, ma la sintassi esplicita è più chiara.

### Gestione cronologia

**Controllo delle voci della cronologia:** Per impostazione predefinita, HTMX spinge ogni richiesta alla cronologia. Per pagine/filtri dove non si desidera inquinamento della cronologia:

```razor
<paging model="@Model" hx-push-url="false">  <!-- Don't add history entries -->
```

O usare `hx-replace-url="true"` per aggiornare l'URL senza aggiungere voci.

**Il problema del Fantasma Parziale:** Il browser indietro/avanti mostra solo un frammento parziale senza layout. `hx-history-elt` sul contenitore contenuto:

```html
<div class="container mx-auto" id="contentcontainer" hx-history-elt>
    @RenderBody()
</div>
```

Questo indica a HTMX quale elemento da istantanea, preservando il layout circostante durante il ripristino della cronologia.

### Caching CDN (Cloudflare, ecc.)

**Sintoma:** HTMX funziona localmente ma si rompe dietro una CDN - contenuti errati viene cached.

**Causa principale:** I CDN ignorano la `HX-Request` header. Il tuo server restituisce contenuti diversi in base a questo header, ma il CDN li caches identicamente.

**ASP.NET Core fix:** Uso `VaryByHeaderNames`:

```csharp
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request" })]
```

**Correttore CDN:** Configura le regole della cache da includere `HX-Request` nella chiave cache. Per Cloudflare: Cruscotto → Caching → Regole cache → Chiave cache personalizzata → Intestazioni → Includi `HX-Request`.

### Il dibattito hx-boost

[`hx-boost`](https://htmx.org/attributes/hx-boost/) converte i collegamenti normali in richieste AJAX. [Pagina delle eccellenze HTMX](https://htmx.org/quirks/) notes some core team members recommend evitarlo (scartamenti `<head>` contenuto, colpisce la località di comportamento), mentre altri trovano bene per le vittorie rapide.

```razor
<div hx-boost="true" hx-target="#contentcontainer">
    <a asp-action="Show" asp-route-slug="@post.Slug">Read More</a>
</div>
```

Questo blog lo usa ampiamente. Quando si punta a contenitori specifici, esplicito `hx-get` è più chiaro, ma `hx-boost` funziona se sei coerente. Disabilita selettivamente con `hx-boost="false"` sugli elementi per bambini.

## Conclusione

HTMX con ASP.NET Core parziales rappresenta un ritorno alla semplicità server-side senza sacrificare UX moderno. Ottieni:

- Interazioni dinamiche simili alla SPA
- Rendering lato server (grande per SEO)
- Caching HTTP corretto
- JavaScript minimo
- Miglioramento progressivo
- Instradamento di tipo sicuro con HTMX.NET
- Paginazione zero-config con per lo piùlucid.pagingtaghelper

L'approccio basato sul server ha resistito alla prova del tempo, e con HTMX, finalmente ha l'elegante tooling client-side che merita. È possibile costruire applicazioni web robuste e performanti utilizzando modelli che hanno funzionato per decenni - hanno appena aspettato lo strumento giusto per farli brillare di nuovo.

## Articoli correlati su questo blog

### Articolo "Companion"

Questo articolo fa parte di una serie in due parti su HTMX con ASP.NET Core:

1. **Questo articolo** - Si concentra sull'integrazione ASP.NET Core, viste parziali, HTMX.NET, e la paginazione
2. **[A Whistle-stop Tour delle estensioni HTMX](/blog/htmxandaspnetcore)** - Immersione profonda in eventi HTMX, ciclo di vita, architettura di estensione ed estensioni personalizzate

### Altri articoli HTMX

- [Aggiunta di Paging con HTMX](/blog/addpagingwithhtmx) - L'articolo originale sull'implementazione della paginazione con la vecchia paginazioneTagHelper
- [ASP.NET Core Caching con HTMX](/blog/aspnetcachingwithhtmx) - Immersione profonda nelle strategie di cache per le richieste HTMX
- [Aggiornamento automatico con Alpine e HTMX](/blog/autorefreshwithalpineandhtmx) - Combinare Alpine.js con HTMX per componenti reattivi
- [Rendere il tuo sito più SPA-like con HTMX](/blog/htmxtomakeyoursitemorespalike) - Navigazione SPA-like senza framework JavaScript
- [Utilizzando SweetAlert per indicatori HX](/blog/usingsweetalertforhxindicators) - Bellissimi indicatori di carico con HTMX
- [Mostrando Toast e Scambi con HTMX](/blog/showingtoastandswappingwithhtmx) - Avvisi toast attivati dal server

## Ulteriore lettura

**Documentazione ufficiale:**

- [Documentazione HTMX](https://htmx.org/docs/) - La documentazione ufficiale HTMX
- [Esempi HTMX](https://htmx.org/examples/) - Esempi pratici di modelli HTMX
- [Estensioni HTMX](https://htmx.org/extensions/) - Estensioni ufficiali HTMX
- [Documentazione Alpine.js](https://alpinejs.dev/) - Official Alpine.js docs
- [Esempi di Alpine.js](https://alpinejs.dev/examples) - Pratici modelli Alpine.js
- [Visualizzazioni parziali del nucleo ASP.NET](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/partial) - Guida di Microsoft alle viste parziali
- [ASP.NET Core Output Caching](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/output) - Documentazione ufficiale di cacheing

**Strumenti e librerie:**

- [HTMX.NET GitHub](https://github.com/khalidabuhakmeh/Htmx.Net) - Il codice sorgente della libreria HTMX.NET
- [HTMX.NET NuGet](https://www.nuget.org/packages/Htmx/) - HTMX.NET su NuGet
- [Htmx.TagHelpers NuGet](https://www.nuget.org/packages/Htmx.TagHelpers/) - Aiuto per il tag HTMX su NuGet
- [Sito web di Khalid Abuhakmeh](https://khalidabuhakmeh.com/) - Creatore di HTMX.NET, con eccellenti post sul blog
- [Khalid Abuhakmeh's GitHub](https://github.com/khalidabuhakmeh) - Progetti open-source più brillanti .NET
- [per lo piùlucid.pagingtaghelper GitHub](https://github.com/scottgal/mostlylucid.pagingtaghelper) - Il mio codice sorgente dell'helper del tag paging
- [per lo piùlucid.pagingtaghelper NuGet](https://www.nuget.org/packages/mostlylucid.pagingtaghelper/) - Il pacchetto su NuGet

**Risorse comunitarie:**

- [Discord HTMX](https://htmx.org/discord) - Supporto attivo della comunità
- [Saggi HTMX](https://htmx.org/essays/) - Articoli di riflessione sulla filosofia HTMX
- [Hypermedia Systems Book](https://hypermedia.systems/) - Libro online gratuito sulla costruzione di applicazioni ipermediali