> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.userbot.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.userbot.ai/_mcp/server.

# Com'è fatta una Mini App

Questa pagina serve a chi deve correggere una Mini App con precisione, o capire
perché una richiesta non è stata accolta. Non devi scrivere codice per usare
Userbot, ma sapere com'è fatta una Mini App cambia il modo in cui la descrivi.

## Un piccolo progetto web

Una Mini App nuova parte da uno scheletro già pronto: un progetto React costruito
con Vite e Tailwind, con alcuni componenti di interfaccia inclusi. Da quel
momento i file sono della Mini App, e l'AI li modifica come farebbe uno
sviluppatore. Li vedi tutti nella scheda **Codice** del costruttore.

| File                                              | A cosa serve                                                                             |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `index.html`                                      | La pagina di partenza (il file con l'etichetta **entry**)                                |
| `src/App.tsx`                                     | L'interfaccia e la logica della Mini App                                                 |
| `src/main.tsx`                                    | Avvia l'app e la collega a Userbot                                                       |
| `src/components/ui/…`                             | Pulsanti, campi, schede e etichette già pronti                                           |
| `src/lib/userbot.ts`                              | La funzione `callServer`, per chiamare le funzioni server                                |
| `package.json`, `vite.config.ts`, `tsconfig.json` | La configurazione del progetto                                                           |
| `miniapp.config.json`                             | La carta d'identità della Mini App: schema dei campi, funzioni server, domini consentiti |
| `server/…`                                        | Le [funzioni server](/miniapp-server), se servono                                        |

Le Mini App create prima di questo modello, fatte da un unico file HTML,
continuano a funzionare.

## Le tre funzioni che deve esporre

Una Mini App va usata da due parti diverse: una persona che compila i campi e un
modello che la chiama come strumento. Perché entrambe funzionino, la Mini App
espone tre funzioni. Nello scheletro sono `run`, `getOutput` e `setInputs`,
esportate da `src/App.tsx`, e `src/main.tsx` le collega ai nomi che Userbot
cerca.

| Funzione    | Nome per Userbot                 | Cosa fa                                                                     |
| ----------- | -------------------------------- | --------------------------------------------------------------------------- |
| `run`       | `__USERBOT_MINIAPP_RUN__`        | Riceve i parametri, esegue il lavoro, restituisce il risultato              |
| `getOutput` | `__USERBOT_MINIAPP_GET_OUTPUT__` | Restituisce l'ultimo risultato prodotto                                     |
| `setInputs` | `__USERBOT_MINIAPP_SET_INPUTS__` | Riempie i campi, o apre la vista giusta, con i valori che arrivano da fuori |

Le regole che le tengono insieme sono poche e rigide:

* Le chiavi del risultato di `run` sono **esattamente** i campi di output, né uno
  in più né uno in meno.
* `run` deve funzionare senza che nessuno tocchi l'interfaccia.
* L'interfaccia e `run` devono usare **la stessa logica**. È questa regola a
  garantire che il numero che vedi a schermo e il numero che riceve l'AI siano lo
  stesso numero.
* Tutto quello che esce deve essere rappresentabile in JSON: numeri, testi, valori
  vero/falso, elenchi.

Senza `run` il codice viene rifiutato e non arriva mai in anteprima.

## Lo schema: cosa entra e cosa esce

Lo schema è l'elenco dei campi di input e di output, ciascuno con un nome, un
tipo, la nota se è obbligatorio e, per le scelte, i valori ammessi. Sta in
`miniapp.config.json`, lo scrive l'AI insieme al codice, ed è quello che il
modello legge per capire cosa passare alla Mini App.

```json
{
  "entry": "index.html",
  "inputFields": [
    { "name": "quantita", "type": "number", "required": true },
    { "name": "categoria", "type": "enum", "options": ["Standard", "Premium", "Outlet"] }
  ],
  "outputFields": [{ "name": "totale", "type": "number" }],
  "serverFunctions": [],
  "allowedFetchDomains": [],
  "toolEntrypoint": null
}
```

I tipi disponibili sono quattro:

| Tipo      | Cosa contiene                  |
| --------- | ------------------------------ |
| `string`  | Testo                          |
| `number`  | Un numero                      |
| `boolean` | Vero o falso                   |
| `enum`    | Una scelta fra valori elencati |

Il pulsante **Parametri**, nel menu **⋯** del costruttore, mostra lo schema in
sola lettura.

![Il pannello dei parametri: sopra i campi in ingresso, ciascuno con nome, tipo, se è obbligatorio e, per le scelte, i valori ammessi; sotto quelli in uscita](/_fern-img/551b9068ece9bfa22918d42d3056c87269ca4098c5935cf9120e21f7be3c6faf.webp)

Per cambiarlo lo chiedi in chat (*«il campo categoria deve essere una scelta fra
Standard, Premium e Outlet»*, *«la quantità è obbligatoria»*) e l'AI riscrive
codice e schema insieme. Lo schema che usano gli agenti è quello della versione
pubblicata.

## Cosa può fare, e cosa no

Dentro il progetto può esserci tutto quello che si fa con React: moduli, tabelle,
grafici, più pagine, calcoli su liste lunghe.

* **Librerie: solo quelle ammesse.** Oltre a React ci sono, fra le altre, React
  Router, react-hook-form, zod, Recharts per i grafici, date-fns, le icone Lucide
  e alcuni componenti Radix. Un pacchetto fuori da questo elenco fa fallire la
  costruzione dell'anteprima.
* **Niente codice generato al volo.** `eval` e `new Function` sono vietati, e
  bloccano la pubblicazione.
* **Niente chiavi segrete nel codice.** Una chiave o una password scritta in
  chiaro blocca la pubblicazione.
* **Nessun accesso alle tue [integrazioni](/integrazioni), alla
  [Libreria](/documenti) o alla [conoscenza aziendale](/conoscenza-aziendale).**
  Se il risultato dipende da informazioni che stanno lì, vanno passate come
  parametri o cercate da un [agente](/quando-agente).
* **Internet e dati salvati, solo dal server.** Una Mini App può chiamare un
  servizio web e conservare dati fra un uso e l'altro attraverso le
  [funzioni server](/miniapp-server), e solo verso i domini che ha dichiarato.

## La verifica automatica

Ogni volta che l'AI scrive o modifica il codice, Userbot **non si fida della
parola**. Prima di mostrarti il risultato:

#### Controlla il progetto

Verifica che i file rispettino i limiti, che lo schema sia valido e che
`run` esista.

#### Apre la Mini App in un browser vero

Il progetto viene costruito e caricato in un browser, senza schermo, sul
server.

#### La esegue con parametri di prova

Chiama `run` con un valore d'esempio per ogni campo di input dichiarato.

#### Confronta il risultato con lo schema

Le chiavi restituite devono coincidere con i campi di output, esattamente. Se
`run` va in errore, restituisce qualcosa di diverso o non risponde entro 15
secondi, l'AI riceve il motivo e corregge.

Nel riquadro delle azioni del costruttore questo passaggio compare come
«Verifico RUN». Il codice che l'AI produce, quindi, è già stato eseguito almeno
una volta. Quello che la verifica non può sapere è se il risultato è **giusto**:
che il totale sia quello previsto dal tuo listino lo puoi dire solo tu.

Il controllo vale per quello che scrive l'AI. Quello che modifichi a mano nella
scheda **Codice** viene salvato così com'è: se rompi qualcosa, te ne accorgi
dall'anteprima, dove gli errori finiscono nel pannello **Problemi**.

## I limiti

| Cosa                                            | Limite                           |
| ----------------------------------------------- | -------------------------------- |
| File nel progetto                               | 80                               |
| Dimensione di un file                           | 400 KB                           |
| Dimensione totale del progetto                  | 4 MB                             |
| Durata di `run`                                 | 15 secondi, poi viene interrotta |
| Giri di lavoro dell'AI per ogni richiesta       | 10                               |
| Messaggi del costruttore tenuti in memoria      | gli ultimi 8                     |
| Riparazioni automatiche di fila da **Problemi** | 3                                |
| Punti di ripristino automatici conservati       | 10                               |
| Voci visibili nel pannello **Attività**         | 50                               |

I limiti delle funzioni server e dei dati salvati sono in
[Funzioni server e dati](/miniapp-server).

Il limite di otto messaggi spiega un comportamento che altrimenti sorprende: se in
una conversazione lunga torni su una richiesta di venti messaggi prima, il
costruttore non la ricorda più. Riscrivila per esteso invece di dire «come dicevo
prima».

#### [Crearne una](/creare-miniapp)

La procedura, dalla descrizione all'anteprima funzionante.

#### [Funzioni server e dati](/miniapp-server)

Chiamare servizi esterni e conservare dati, con i loro limiti.