← Tutti gli articoli
Home › Blog › AI in Next.js
Sviluppo Web

Aggiungere AI a un Sito Next.js: Streaming e UX

Guida tecnica 14 min di lettura Settembre 2024

Aggiungere AI a un'applicazione Next.js è diventato molto più semplice con l'AI SDK di Vercel. La parte complicata non è la chiamata all'API — è gestire lo streaming in modo che l'UX sia buona: testo che appare progressivamente, loading states chiari, gestione degli errori.

Il motivo per cui lo streaming conta così tanto è percettivo, non tecnico: una risposta di GPT-4 può richiedere 5-10 secondi per essere generata per intero. Aspettare 8 secondi con uno spinner sembra un'eternità; vedere il testo comparire parola dopo parola dopo mezzo secondo sembra istantaneo, anche se il tempo totale è identico. Tutto questo articolo è, in sostanza, come implementare bene quella percezione.

Setup: AI SDK di Vercel

npm install ai openai
# oppure per Claude:
npm install ai @anthropic-ai/sdk

Route API con streaming

// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

export const runtime = 'edge'; // Edge runtime per latenza minore

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await streamText({
    model: openai('gpt-4o'),
    system: 'Sei un assistente utile. Rispondi sempre in italiano.',
    messages,
    maxTokens: 1000,
  });

  return result.toDataStreamResponse();
}

Due dettagli che fanno la differenza in questo snippet: runtime = 'edge' instrada la funzione sui nodi edge di Vercel, più vicini geograficamente all'utente, riducendo la latenza prima ancora che parta la generazione. maxTokens non è solo un limite di costo — è anche una garanzia che la risposta non superi il timeout della funzione (vedi la sezione Deployment più sotto).

Componente chat con streaming

// components/Chat.tsx
'use client';
import { useChat } from 'ai/react';

export function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
    api: '/api/chat',
  });

  return (
    <div>
      <div className="messages">
        {messages.map(m => (
          <div key={m.id} className={`message ${m.role}`}>
            {m.content}
          </div>
        ))}
        {isLoading && <div className="typing-indicator">...</div>}
      </div>

      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Scrivi un messaggio..."
          disabled={isLoading}
        />
        <button type="submit" disabled={isLoading}>
          {isLoading ? 'Generando...' : 'Invia'}
        </button>
      </form>
    </div>
  );
}

L'hook useChat astrae gran parte della complessità dello stato: gestisce automaticamente l'array dei messaggi, lo stato di caricamento e l'aggiornamento progressivo del testo mentre arriva dallo stream, senza bisogno di gestire manualmente EventSource o parsing manuale dei chunk.

UX patterns per l'AI

Questi tre pattern coprono i casi che, se ignorati, fanno percepire un'interfaccia AI come "rotta" anche quando il backend funziona perfettamente.

1. Typing indicator durante lo streaming

// CSS per typing indicator
.typing-indicator::after {
  content: '▋';
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

2. Gestione errori con retry

const { messages, error, reload } = useChat({
  api: '/api/chat',
  onError: (error) => {
    console.error('Errore AI:', error);
    // mostra messaggio di errore all'utente
  }
});

// Bottone retry quando c'è un errore
{error && (
  <button onClick={reload}>Riprova</button>
)}

3. Rate limiting lato client

// Disabilita il submit se la generazione è attiva
// e aggiunge cooldown dopo ogni risposta
const [cooldown, setCooldown] = useState(false);

const handleSubmitWithCooldown = async (e) => {
  e.preventDefault();
  if (cooldown || isLoading) return;
  await handleSubmit(e);
  setCooldown(true);
  setTimeout(() => setCooldown(false), 2000);
};

Senza un cooldown o una disabilitazione esplicita del submit, è facile che un utente impaziente clicchi due volte, generando due richieste in parallelo (e pagando due volte per la stessa risposta).

Deployment e costi

  • Vercel Edge Functions: latenza minima, ma costo per richiesta — monitora il budget
  • Streaming timeout: Vercel ha un limite di 25s per le Edge Functions — imposta maxTokens per evitare timeout
  • Caching: per query identiche, usa unstable_cache di Next.js per ridurre le chiamate API

Un errore comune è dimenticare che il costo di un'integrazione AI su un sito pubblico scala con il traffico, non con lo sviluppo: una pagina con un chatbot esposta senza autenticazione né rate limiting può ricevere richieste automatizzate (bot, scraping, abuso) che generano una bolletta API inaspettata. Rate limiting lato server — non solo lato client come nell'esempio sopra — è la protezione che conta davvero.

Alternativa senza framework

Se non usi Next.js, puoi implementare lo stesso pattern con fetch + ReadableStream nativo in qualsiasi framework. L'AI SDK di Vercel supporta anche Express, FastAPI e altri backend.

Domande frequenti

Devo per forza usare l'Edge Runtime?

No. Il runtime Node.js standard funziona altrettanto bene ed è necessario se usi librerie non compatibili con l'ambiente Edge (alcuni SDK, accesso a filesystem). L'Edge Runtime conviene quando la latenza percepita è una priorità e le dipendenze lo supportano.

Come proteggo la chiave API se il codice gira lato client?

Non deve girare lato client. La chiamata al modello AI deve sempre passare da una API route del tuo backend (come nell'esempio app/api/chat/route.ts), dove la chiave resta in una variabile d'ambiente server-side — mai esposta al browser.

Lo streaming funziona bene anche su mobile con connessione lenta?

Sì, anzi è dove fa più differenza: su una connessione lenta, aspettare la risposta completa prima di mostrare qualcosa è ancora più frustrante. Assicurati solo che il typing indicator e la gestione errori (timeout, connessione persa) siano robusti, perché su mobile le interruzioni di rete sono più frequenti.

Integrazione AI nel tuo sito

Aggiungo funzionalità AI al tuo progetto web

Chat, generazione contenuti, analisi dati: dall'idea all'implementazione in produzione.

Contattami per collaborazioni →
Intelligenza Artificiale ✦ Automazioni n8n ✦ Musica Generativa ✦ Prompt Engineering ✦ RAG & LangChain ✦ MVP AI-powered ✦ Creative Technology ✦ Web Development ✦