> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# Raccogli le chiavi provider rimanenti

Brevi procedure per i servizi rimasti: provider AI, Trigger.dev, storage S3, Sentry o PostHog, Turnstile e il tuo dominio.

## Come usare questa pagina

Ogni sezione qui sotto è una procedura di configurazione completa: crea l'account, trova la chiave, imposta i nomi env, verifica. Prendi solo le sezioni dei servizi che il tuo prodotto distribuisce — un sito senza funzioni AI non avrà mai bisogno della prima, e il kit continua a funzionare anche saltando ogni sezione qui.

Le stesse regole sui segreti di sempre: chiavi API e segreti webhook restano lato server, solo i valori con prefisso `NEXT_PUBLIC_`/`EXPO_PUBLIC_` possono raggiungere il client, i segreti di produzione vivono nel secret store dell'hosting, e il server di sviluppo rilegge l'env solo al riavvio.

[Torna alla lista degli account](https://supastack.dev/it/docs/web/external-accounts.md)


## Chiavi dei provider AI

L'`AI_PROVIDER` del kit accetta `openai`, `anthropic`, `openai-compatible` e `openrouter` — più `fake`, il sostituto locale predefinito. Scegline uno; la chiave del provider è l'unico account necessario, perché gli id dei modelli e i prezzi vengono dal catalogo nel database del kit, non da variabili env.

OpenAI: [platform.openai.com](https://platform.openai.com) → API keys → Create new secret key → copia `sk-…` → `OPENAI_API_KEY`. Anthropic: [console.anthropic.com](https://console.anthropic.com) → API Keys → Create Key → `sk-ant-…` → `ANTHROPIC_API_KEY`. Entrambi fatturano a token — pochi dollari di credito coprono lo sviluppo.

OpenRouter instrada ogni modello del catalogo attraverso una sola chiave: [openrouter.ai](https://openrouter.ai) → Keys → Create Key → `sk-or-…` → `AI_PROVIDER=openrouter` più `OPENROUTER_API_KEY`; gli opzionali `OPENROUTER_APP_NAME`/`OPENROUTER_SITE_URL` inviano header di attribuzione. `openai-compatible` copre qualsiasi endpoint di forma OpenAI: `OPENAI_COMPATIBLE_API_KEY` più `OPENAI_COMPATIBLE_BASE_URL`.

Verifica: riavvia, esegui un task AI e aspettati una risposta di modello reale invece del fake deterministico. Un errore di avvio che nomina la chiave significa che il flag del provider è attivo senza la sua chiave. Una risposta reale ha anche bisogno di `JOB_PROVIDER=trigger` dalla sezione Trigger.dev qui sotto più un modello abilitato nel catalogo del kit — [Configura l'AI](https://supastack.dev/it/docs/web/setup-ai.md) copre quel montaggio.

```
# apps/web/.env.local — pick ONE provider
AI_PROVIDER=openai
OPENAI_API_KEY=sk-…

# or AI_PROVIDER=anthropic
# ANTHROPIC_API_KEY=sk-ant-…

# or AI_PROVIDER=openrouter
# OPENROUTER_API_KEY=sk-or-…

# or AI_PROVIDER=openai-compatible
# OPENAI_COMPATIBLE_API_KEY=…
# OPENAI_COMPATIBLE_BASE_URL=https://your-endpoint/v1
```


## Trigger.dev

Salta a meno che il prodotto non abbia bisogno di esecuzioni reali di job in background — `JOB_PROVIDER=local` accoda i job in memoria senza eseguirli, il che è giusto per lo sviluppo.

1. Apri [app.trigger.dev](https://app.trigger.dev) → Sign up → crea un progetto.

2. Copia due valori: il project ref `proj_…` dalle impostazioni del progetto o dall'URL della dashboard → `TRIGGER_PROJECT_REF`, e la secret key dalla pagina delle API keys del progetto (`tr_dev_…` per l'ambiente dev, `tr_prod_…` per la produzione) → `TRIGGER_SECRET_KEY`. Entrambi restano lato server.

3. I task del kit vivono già in `apps/web/trigger` e `apps/web/trigger.config.ts` legge `TRIGGER_PROJECT_REF`. Da `apps/web` esegui `npx trigger.dev@latest dev` — registra i task presso il tuo progetto e li esegue in locale contro la chiave dev.

Verifica: il comando dev registra i task nel log; accodane uno nell'app e guardalo eseguire nella lista Runs della dashboard. Gli ambienti distribuiti eseguono `corepack pnpm --filter @supastack/web trigger:deploy` per pubblicare l'insieme dei task.

```
# apps/web/.env.local
JOB_PROVIDER=trigger
TRIGGER_PROJECT_REF=proj_…
TRIGGER_SECRET_KEY=tr_dev_…   # tr_prod_… in production

# run the worker alongside the app, from apps/web:
cd apps/web
npx trigger.dev@latest dev
```


## Storage compatibile S3 (Cloudflare R2)

Salta a meno che il prodotto non memorizzi file — `STORAGE_PROVIDER=memory` tiene gli upload nel processo per lo sviluppo.

Qualsiasi bucket compatibile S3 va bene; Cloudflare R2 è la scelta amica del piano gratuito. 1. Apri [dash.cloudflare.com](https://dash.cloudflare.com) → R2 Object Storage → Create bucket, dagli un nome e tieni il suggerimento di località predefinito.

2. Di nuovo nella panoramica R2 apri Manage R2 API Tokens → Create API token → permesso Object Read & Write, limitato a quel bucket → Create. Copia l'Access Key ID, la Secret Access Key e l'endpoint S3 mostrato — `https://<account-id>.r2.cloudflarestorage.com`.

3. Imposta i nomi env qui sotto. `STORAGE_REGION=auto` è la convenzione di R2 — il kit usa `us-east-1` di default, che R2 accetta comunque. `STORAGE_FORCE_PATH_STYLE` è già attivo di default per gli endpoint personalizzati, cosa che R2 vuole. Servire file pubblici richiede inoltre `STORAGE_PUBLIC_BASE_URL` o il cablaggio di una CDN; i file privati non hanno bisogno d'altro.

Verifica: riavvia e carica tramite l'app — l'oggetto appare nel browser del bucket R2. Un errore di firma o un 403 significa che al token manca la lettura/scrittura di oggetti su quel bucket; crea un token nuovo con lo scope corretto.

```
# apps/web/.env.local
STORAGE_PROVIDER=s3
STORAGE_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
STORAGE_REGION=auto
STORAGE_BUCKET=your-bucket
STORAGE_ACCESS_KEY_ID=…          # server-only
STORAGE_SECRET_ACCESS_KEY=…      # server-only
# STORAGE_PUBLIC_BASE_URL=       # optional public-URL base
```


## Sentry o PostHog (opzionale)

Del tutto opzionale: ogni valore di osservabilità è vuoto di default e il kit funziona benissimo senza — aggiungilo quando vuoi report di errori e analytics in produzione.

Sentry per gli errori: [sentry.io](https://sentry.io) → crea un progetto → scegli la piattaforma Next.js → la schermata di configurazione mostra il DSN `https://…@….ingest.sentry.io/…` → `SENTRY_DSN`. Le eccezioni arrivano poi a Sentry taggate con correlation id; il piano gratuito basta per iniziare.

PostHog per le analytics di prodotto in alternativa: [posthog.com](https://posthog.com) → crea un progetto → copia la chiave API del progetto `phc_…` → `NEXT_PUBLIC_POSTHOG_KEY` più `NEXT_PUBLIC_POSTHOG_HOST` (`https://us.i.posthog.com`, o il tuo host UE). Quelle due sono valori pubblici da browser per design; `SENTRY_DSN` resta lato server. `ALERT_WEBHOOK_URL` pubblica opzionalmente avvisi di fallimento verso un endpoint compatibile con Slack.

Verifica: riavvia, solleva un'eccezione di test (o riproduci l'evento di esempio di Sentry) e conferma che atterri nella lista Issues del progetto.

```
# apps/web/.env.local — all optional
SENTRY_DSN=https://…@….ingest.sentry.io/…

NEXT_PUBLIC_POSTHOG_KEY=phc_…
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

# ALERT_WEBHOOK_URL=https://hooks.slack.com/services/…
```


## Cloudflare Turnstile

Protezione anti-bot per i form pubblici e gli endpoint delle credenziali — `CAPTCHA_PROVIDER=off` di default, quindi aggiungilo prima di aprire la registrazione agli sconosciuti. Gratuito.

1. Apri [dash.cloudflare.com](https://dash.cloudflare.com) → Turnstile → Add widget → dagli un nome ed elenca gli hostname: `localhost` per lo sviluppo più il tuo dominio reale → Create.

2. Copia entrambi i valori: la Site Key — pubblica per design, si renderizza dentro il widget → `NEXT_PUBLIC_TURNSTILE_SITE_KEY` — e la Secret Key, che il server usa per verificare → `TURNSTILE_SECRET_KEY`.

3. `CAPTCHA_PROVIDER=turnstile` lo attiva; l'avvio fallisce nominando la chiave mancante. La guida captcha elenca esattamente quali superfici protegge il widget.

Verifica: apri `/auth` o il form di contatto — il widget si renderizza; gli invii senza una challenge risolta vengono rifiutati. Se il widget non si carica mai, l'hostname che stai visitando non è nell'elenco del widget.

[Vedi quali form protegge Turnstile](https://supastack.dev/it/docs/web/captcha.md)

```
# apps/web/.env.local
CAPTCHA_PROVIDER=turnstile
NEXT_PUBLIC_TURNSTILE_SITE_KEY=0x…   # public by design
TURNSTILE_SECRET_KEY=0x…             # server-only
```


## Un dominio tutto tuo

Un acquisto presso qualsiasi registrar — Cloudflare Registrar, Porkbun, Namecheap vanno tutti bene. Niente di tutto questo si copia nell'env; il dominio compare nel Services ID, nel DNS di Resend, negli hostname di Turnstile e nelle return URL di OAuth che hai configurato strada facendo.

Due modi per puntarlo all'app: per Cloud Run usa il mapping di dominio della guida al deployment — qualche clic di console più i record DNS che Google elenca. Oppure sposta il DNS sui nameserver di Cloudflare (il registrar scambia due record) — opzionale, ma è anche il modo ordinato di gestire bucket pubblici R2 e hostname di Turnstile in un unico posto.

[Mappa il dominio su Cloud Run](https://supastack.dev/it/docs/web/deploy-google-cloud.md)

[Configura poi il database](https://supastack.dev/it/docs/web/setup-database.md)


Per continuare la configurazione, leggi [Configura il database](https://supastack.dev/it/docs/web/setup-database.md).


## Successivo

[Configura il database](https://supastack.dev/it/docs/web/setup-database.md)
