README.it.md
Rama main · réplica de lectura del repositorio original.
<div align="center">
<img src="public/Public-Page-iPhone-Dashboard-iMac.png" alt="Banner" width="100%" />
---
[English](README.md) · [العربية](README.ar.md) · [中文](README.zh.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · **Italiano** · [日本語](README.ja.md) · [Português (Brasil)](README.pt-BR.md) · [Русский](README.ru.md) · [Español](README.es.md) · [Türkçe](README.tr.md)
[](LICENSE)
[](https://hub.docker.com/r/omnirise/linkbreeze)
[](https://linkbreeze.omnirise.dev/)
[](https://omnirise.dev)
[](https://www.youtube.com/watch?v=_Ipf-_1B4BY)
[](https://github.com/OmniRise/LinkBreeze/actions/workflows/ci.yml)
[](https://github.com/OmniRise/LinkBreeze/releases/latest)
[](https://discord.gg/bAJMW3bAJa)
</div>
---
> **Smetti di pagare $15 al mese per Linktree.** LinkBreeze è un hub di link gratuito e self-hosted: veloce, personalizzabile, con analytics integrati. **Installalo con un solo comando.**
<div align="center">
[**🔗 Demo Live**](https://linkbreeze-demo.omnirise.dev/linkbreeze) ·
[**🔐 Dashboard Demo**](https://linkbreeze-demo.omnirise.dev/dashboard)
</div>
---
## ✨ Funzionalità
<div align="center">
<table>
<tr>
<td width="50%" valign="top">🔗 <strong>Supporto Multi-Pagina</strong><br/>Pagine illimitate, ognuna con il proprio slug, tema, link e analytics</td>
<td valign="top">🎨 <strong>Temi + Personalizzatore</strong><br/>11 preset più un personalizzatore completo basato su token con import/export</td>
</tr>
<tr>
<td valign="top">📊 <strong>Analytics Privacy-first</strong><br/>Visualizzazioni, click, referrer, dispositivi. Senza cookie, IP con hash, eliminati automaticamente</td>
<td valign="top">🧭 <strong>Migrazione Guidata</strong><br/>Importa da Linktree, Bento, Hopp.bio, LittleLink o da qualsiasi esportazione HTML/JSON</td>
</tr>
<tr>
<td valign="top">🔒 <strong>Self-Hosted</strong><br/>I tuoi dati, il tuo server. Niente tracker, niente pubblicità, niente abbonamento</td>
<td valign="top">🐳 <strong>Installazione con un Comando</strong><br/>Un comando curl. Rileva automaticamente Docker o Podman e sei online</td>
</tr>
<tr>
<td valign="top">📱 <strong>Widget Incorporati</strong><br/>YouTube, Spotify, SoundCloud, Vimeo e Bandcamp sulla tua pagina</td>
<td valign="top">🎯 <strong>Codici QR</strong><br/>Generati automaticamente, colori personalizzati, avatar o favicon al centro, SVG/PNG fino a 1024px</td>
</tr>
<tr>
<td width="50%" valign="top">🌐 <strong>Domini Personalizzati</strong><br/>Collega i tuoi domini alle pagine - i visitatori arrivano su jane.com, senza /slug</td>
<td valign="top">⏰ <strong>Backup Pianificati</strong><br/>Backup giornalieri/settimanali/mensili interni all'app con ripristino con un click, senza cron</td>
</tr>
</table>
⚡ **Zero JavaScript lato client. Caricamento in meno di 300ms. HTML puro renderizzato dal server.**
</div>
<details>
<summary>✨ Tutte le funzionalità</summary>
- **🔗 Gestione dei Link** - Aggiungi, riordina e personalizza link illimitati con drag-and-drop
- **🌐 Link con Favicon Automatica** - I link mostrano automaticamente la favicon del sito di destinazione, senza dover caricare icone
- **🖼️ Anteprime dei Link** - Aggiungi immagini ai tuoi link per schede di anteprima visive
- **⏰ Programmazione dei Link** - Pianifica l'apparizione o la scomparsa automatica dei link con controlli data/ora
- **🏷️ Slug di Reindirizzamento Personalizzati** - Short link stabili e condivisibili tipo `/go/tuo-nome` che sopravvivono a eliminazioni e ricreazioni
- **🧪 Test A/B** - Dividi il traffico di un link tra due destinazioni con assegnazione per visitatore stabile tra le visite, analitica per variante, percentuale di lift e promozione del vincitore con un clic ([guida](docs/ab-testing.md))
- **📈 Analytics Esterni** - Inietta Plausible, Umami, Matomo o Google Analytics con un semplice incolla
- **🖼️ Immagini di Anteprima Social (OG)** - Card di condivisione generate automaticamente dal tema della tua pagina, oppure carica le tue con controllo di adattamento, posizione e zoom
- **✏️ CSS Personalizzato** - Rifinisci la tua pagina con iniezione di CSS grezzo
- **📧 Raccolta Email** - Raccogli le email degli iscritti sulla tua pagina pubblica, esporta in CSV
- **🔔 Notifiche di Aggiornamento** - Banner nella dashboard quando è disponibile una nuova versione. Nessun phone-home, nessun aggiornamento automatico
- **🔑 Pannello Admin Veloce** - Tutto quanto sopra da una dashboard pulita e istantanea
- **🌐 Domini Personalizzati** - Collega i tuoi domini alle pagine; scope esclusivo o hub, reindirizzamenti canonici automatici, rigoroso blocco dell'host admin
- **⏰ Backup Pianificati** - Backup giornalieri/settimanali/mensili interni all'app con retention e ripristino con un click, senza cron richiesti
</details>
## 🚀 Avvio Rapido
**Un comando. Zero configurazione. Online in 30 secondi:**
```bash
curl -fsSL https://linkbreeze.omnirise.dev/install.sh | bash
```
Lo script rileva Docker o Podman, scarica l'immagine e avvia il container. Eseguilo con `sudo bash` e rispondi **y** per abilitare anche l'avvio automatico al boot.
Poi apri **http://localhost:3000** - la procedura guidata di configurazione richiede meno di 30 secondi.
<details>
<summary>🔍 Vuoi ispezionare lo script prima di eseguirlo?</summary>
```bash
curl -fsSL https://linkbreeze.omnirise.dev/install.sh -o install.sh
less install.sh
bash install.sh
```
</details>
**Preferisci un altro metodo?** Espandi quello che ti serve qui sotto.
<details>
<summary>🐳 Docker</summary>
Niente Node.js, niente npm, niente file di configurazione. Immagini multi-arch: `linux/amd64` e `linux/arm64` (Raspberry Pi 3/4/5, Apple Silicon, VPS ARM).
**Linux / macOS / CMD di Windows:**
```bash
docker run -d --name linkbreeze --restart unless-stopped -p 3000:3000 -v linkbreeze-data:/app/data docker.io/omnirise/linkbreeze:latest
```
**Windows PowerShell** - usa i backtick per andare a capo:
```powershell
docker run -d `
--name linkbreeze `
--restart unless-stopped `
-p 3000:3000 `
-v linkbreeze-data:/app/data `
docker.io/omnirise/linkbreeze:latest
```
> Le migrazioni del database vengono eseguite automaticamente all'avvio del container.
</details>
<details>
<summary>🧩 Docker Compose</summary>
Crea un `docker-compose.yml`:
```yaml
services:
linkbreeze:
image: docker.io/omnirise/linkbreeze:latest
ports:
- "3000:3000"
volumes:
- linkbreeze-data:/app/data
restart: unless-stopped
volumes:
linkbreeze-data:
```
```bash
docker compose up -d
```
Aggiornamento: `docker compose pull && docker compose up -d` · Log: `docker compose logs -f linkbreeze`
Preferisci compilare dal sorgente? `git clone https://github.com/OmniRise/LinkBreeze.git && cd LinkBreeze && docker compose up -d --build`
</details>
<details>
<summary>☁️ Coolify</summary>
1. **+ New Resource** → **Docker Compose Empty**
2. Incolla il file compose dalla sezione qui sopra
3. Imposta un dominio (ad es. `links.yourdomain.com`) - Coolify gestisce automaticamente Let's Encrypt
4. Clicca **Deploy**
</details>
<details>
<summary>📦 Synology NAS</summary>
Container Manager (DSM 7.2+):
1. Scarica l'immagine `docker.io/omnirise/linkbreeze:latest` (**Image** → **Add**, se non la trovi)
2. **Create** un container: nome `linkbreeze`, porta `3000 → 3000`, volume `/docker/linkbreeze/data → /app/data`, policy di riavvio `Unless stopped`
3. Clicca **Done** - online su `http://<nas-ip>:3000`
I dati permangono nel volume durante gli aggiornamenti dell'immagine.
</details>
<details>
<summary>🔧 Podman</summary>
```bash
podman run -d --name linkbreeze --restart unless-stopped -p 3000:3000 -v linkbreeze-data:/app/data docker.io/omnirise/linkbreeze:latest
```
Errori di permessi sul volume? Esegui prima `podman volume create linkbreeze-data`. Lo script di installazione in cima rileva Podman automaticamente.
</details>
<details>
<summary>🖥️ Portainer</summary>
1. **Stacks** → **Add stack**, chiamalo `linkbreeze`
2. Incolla il file compose dalla sezione Docker Compose qui sopra
3. Clicca **Deploy the stack**
Aggiornamenti: **Stacks** → `linkbreeze` → **Editor** → **Pull and redeploy**.
</details>
<details>
<summary>🔨 Manuale (senza Docker)</summary>
Richiede Node.js 18+.
```bash
git clone https://github.com/OmniRise/LinkBreeze.git
cd LinkBreeze
npm install
cp .env.example .env
# Edit .env to set your SECRET_KEY and DATABASE_PATH if needed
npm run db:migrate
npm run dev
```
Per la produzione: `npm run build && npm start`
</details>
<details>
<summary>🌍 Metti online sul tuo dominio</summary>
Una volta fatto il deploy, la tua pagina è su `https://your-domain.com/your-slug`.
1. Punta il record A del tuo dominio all'IP del tuo server
2. Esponi la porta 3000 o metti davanti un reverse proxy
3. Fatto
**File compose pronti all'uso** si trovano in [`examples/`](examples/) - un file autonomo per ogni scenario:
| Cosa vuoi fare | Usa questo file |
|---------------|-----------------|
| TLS automatico, senza configurazione manuale | `docker-compose.caddy.yml` o `docker-compose.https-portal.yml` |
| TLS automatico con una dashboard (Traefik) | `docker-compose.traefik.yml` |
| Nessuna porta aperta (zero-trust) | `docker-compose.cloudflare-tunnel.yml` |
| Usi già Nginx + Certbot | `docker-compose.nginx.yml` |
| Backup pianificati dalla UI (senza sidecar) | Integrato - abilitalo in Impostazioni -> Dati |
| Backup SQLite pianificati (sidecar con dump grezzo, S3 offsite) | `docker-compose.with-backup.yml` |
| Esecuzione su Kubernetes | `kubernetes.yaml` |
**Caddy** (consigliato - HTTPS automatico):
```
links.example.com {
reverse_proxy localhost:3000
}
```
**Nginx:**
```nginx
server {
server_name links.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
**Cloudflare Tunnel** (nessuna porta aperta, nessun acquisto di dominio necessario):
```bash
cloudflared tunnel --url http://localhost:3000
```
</details>
## 📸 Screenshot
<details>
<summary>Clicca per espandere</summary>
<br/>
<table>
<tr>
<td>Pagina Pubblica</td>
<td>Dashboard Admin</td>
</tr>
<tr>
<td><img src="public/screenshots/Public-Page(Aurora).jpeg" alt="Pagina Pubblica [Tema Aurora]" /></td>
<td><img src="public/screenshots/Admin-Dashboard.jpeg" alt="Dashboard Admin" /></td>
</tr>
<tr>
<td>Link</td>
<td>Profilo</td>
</tr>
<tr>
<td><img src="public/screenshots/Links.jpeg" alt="Pagina Link" /></td>
<td><img src="public/screenshots/Profile.jpeg" alt="Pagina Profilo" /></td>
</tr>
<tr>
<td>Tema</td>
<td>Riquadro Anteprima Live</td>
</tr>
<tr>
<td><img src="public/screenshots/Theme.jpeg" alt="Pagina Tema" /></td>
<td><img src="public/screenshots/Preview.jpeg" alt="Riquadro Anteprima Live" /></td>
</tr>
<tr>
<td>Impostazioni [Generali]</td>
<td>Impostazioni [Aspetto]</td>
</tr>
<tr>
<td><img src="public/screenshots/Settings(General).jpeg" alt="Pagina Impostazioni [Scheda Generali]" /></td>
<td><img src="public/screenshots/Settings(Appearance).jpeg" alt="Pagina Impostazioni [Scheda Aspetto]" />
<tr>
<td>Impostazioni [Sicurezza]</td>
<td>Impostazioni [Dati]</td>
</tr>
<tr>
<td><img src="public/screenshots/Settings(Security).jpeg" alt="Pagina Impostazioni [Scheda Sicurezza]" /></td>
<td><img src="public/screenshots/Settings(Data).jpeg" alt="Pagina Impostazioni [Scheda Dati]" /></td>
</tr>
</table>
</details>
## 🆚 Confronto
<div align="center">
| Funzionalità | Linktree | LinkStack | LittleLink | Shako | **LinkBreeze** |
|---------|----------|-----------|------------|-------|----------------|
| **Prezzo** | Gratis - $35/mese | Gratis | Gratis | Gratis | **Gratis** |
| **Pannello Admin** | ✅ | ✅ | ❌ | ❌ | **✅ Veloce** |
| **Multi-Pagina** | ❌ | ❌ | ❌ | ❌ | **✅ Illimitate** |
| **Link con Favicon Automatica** | ❌ | ❌ | ❌ | ❌ | **✅** |
| **Migrazione Guidata** | ❌ | ❌ | ❌ | ❌ | **✅** |
| **Analytics Integrati** | Base, quello completo è a pagamento | Base | ❌ | ❌ | **✅ Completo e privato** |
| **Raccolta Email** | A pagamento | ❌ | ❌ | ❌ | **✅** |
| **Widget Incorporati** | Parziale | ❌ | ❌ | ❌ | **✅** |
| **Programmazione Link** | A pagamento | ❌ | ❌ | ❌ | **✅** |
| **Temi** | A pagamento | Limitati | Solo CSS | File di configurazione | **✅ Sistema completo di token** |
| **Codici QR** | ✅ | ✅ | ❌ | ❌ | **✅ Personalizzabili** |
| **Self-Hosted** | ❌ | ✅ | ✅ | ✅ | **✅** |
| **Caricamento Pagina** | Hosted | App PHP | Veloce (statico) | Veloce (statico) | **<300ms, zero JS** |
</div>
## 💬 Comunità
<div align="center">
**Chiedi aiuto, mostra la tua pagina, vota cosa sviluppare dopo.**
[](https://discord.gg/bAJMW3bAJa)
</div>
## ⚙️ Configurazione
Tutta la configurazione avviene tramite variabili d'ambiente. **[`.env.example`](.env.example) è il riferimento ufficiale** - copialo e ogni variabile è documentata inline, inclusi i blocchi wallet.
| Variabile | Predefinito | Descrizione |
|----------|---------|-------------|
| `PORT` | `3000` | Porta del server |
| `DATABASE_PATH` | `./data/linkbreeze.db` | Percorso del file del database SQLite |
| `BACKUP_DIR` | `./data/backups` | Directory di archiviazione dei backup pianificati (tienila dentro il volume persistente `./data`) |
| `BACKUP_MIN_FREE_MB` | `50` | Salta la scrittura dei backup quando lo spazio libero scende sotto questo valore |
| `SECRET_KEY` | Auto-generata | Chiave di firma HMAC per le sessioni |
| `EXTRA_SCRIPT_SRC` | _(vuoto)_ | Domini di analytics separati da spazi per la CSP (ad es. `plausible.io umami.is`) |
| `LINKBREEZE_PRIMARY_HOST` | _(vuoto)_ | Host primario su cui vive l'admin; il blocco admin dei domini personalizzati restituisce 404 su ogni altro host (la variabile env ha la precedenza sull'impostazione admin) |
| `LINKBREEZE_TRUST_X_FORWARDED_HOST` | `false` | Considera affidabile `X-Forwarded-Host` per il routing dei domini - abilitalo solo dietro un proxy che lo SOVRASCRIVE (nginx, Caddy); l'header `Host` predefinito non può essere falsificato |
| `OIDC_CLIENT_SECRET` | _(vuoto)_ | Client secret per l'accesso unico OIDC (#124 multi-utente). Issuer, client ID, provisioning JIT e modalità di accesso si configurano in Impostazioni → Sicurezza. I segreti restano solo in variabili d'ambiente - le impostazioni vengono esportate integralmente nei backup |
| `LINKBREEZE_ALLOW_HTTP_ISSUER` | `false` | Deroga di test: consentire un issuer OIDC http su una LAN fidata (la produzione richiede https) |
<details>
<summary>💳 Variabili wallet pass (Google Wallet / Apple Wallet)</summary>
| Variabile | Descrizione |
|----------|-------------|
| `GOOGLE_WALLET_ISSUER_ID` | ID numerico dell'issuer dalla Google Pay & Wallet Console. Abilita i pulsanti "Add to Google Wallet" |
| `GOOGLE_WALLET_SERVICE_ACCOUNT_JSON` | JSON del service account (`client_email` + `private_key`) autorizzato per la Wallet API |
| `APPLE_WALLET_CERT_PEM` | Certificato di firma del Pass Type ID (PEM). Abilita i pulsanti "Add to Apple Wallet" |
| `APPLE_WALLET_KEY_PEM` | Chiave privata corrispondente al certificato di firma (PEM) |
| `APPLE_WALLET_KEY_PASSPHRASE` | Passphrase della chiave di firma, se crittografata |
| `APPLE_WALLET_WWDR_PEM` | Certificato intermedio Apple WWDR (PEM) |
| `APPLE_WALLET_TEAM_ID` | Il tuo Apple Team ID di 10 caratteri |
| `APPLE_WALLET_PASS_TYPE_ID` | Il tuo Pass Type ID (deve iniziare con `pass.`) |
Ogni pagina pubblica mostra un blocco di condivisione con un pulsante "Salva contatto" (vCard universale, sempre attivo). I pulsanti wallet si attivano automaticamente quando le credenziali sopra sono configurate. Google Wallet: account issuer gratuito, ma i pass vengono salvati solo per gli utenti di test whitelisted finché Google non concede l'accesso alla produzione. Apple Wallet: richiede un account Apple Developer a pagamento e l'installazione solo da Safari. I pass sono istantanee statiche - il QR sul pass apre sempre la pagina live. Impostazioni → Integrazione mostra lo stato delle credenziali per ogni wallet e avvisa quando il certificato di firma Apple sta per scadere.
</details>
**Usi analytics esterni?** Incolla lo snippet del tuo provider in Impostazioni → Integrazione → Script analytics, poi aggiungi il dominio del provider a `EXTRA_SCRIPT_SRC` così la CSP lo consente (ad es. `EXTRA_SCRIPT_SRC=plausible.io umami.is`). Ricostruisci dopo la modifica - la CSP è incorporata nella build.
Le impostazioni runtime (slug della pagina, titolo, SEO, tema) si gestiscono dalla dashboard admin e sono salvate nel database - nessuna modifica al codice necessaria.
## 🌐 Domini Personalizzati
Punta i tuoi domini alle pagine - un'istanza, tante identità. I visitatori arrivano su `https://jane.com/` e vedono direttamente la pagina di Jane, con reindirizzamenti canonici automatici, sitemap pronti per la SEO e un rigoroso blocco dell'host admin. I binding si attivano alla prima visita reale (DNS auto-verificante), e lo scope per pagina decide se un dominio È la pagina (esclusivo) o un hub per tutti gli slug.
Setup completo - DNS, TLS wildcard e configurazioni reverse proxy copia-e-incolla per Caddy, nginx e Traefik - in **[docs/custom-domains.md](docs/custom-domains.md)**.
## 🔌 API REST
Gestisci link, profilo e analisi da script, pipeline CI o strumenti di terze parti. Genera una chiave API in **Settings → Security → API access** (la chiave completa viene mostrata una sola volta - conservala in un posto sicuro) e inviala nell'header `Authorization` con lo schema HTTP Bearer. La rotazione è immediata per impostazione predefinita; se l'admin ha abilitato l'ora di grazia opzionale, la chiave precedente può continuare a funzionare fino alla chiusura della finestra o alla revoca. Limite: 120 richieste/minuto per chiave, più una guardia per IP. Gli endpoint di scrittura sono bloccati in modalità demo. Ogni istanza serve il proprio riferimento OpenAPI 3.1 su `/api/v1/docs` e `/api/v1/openapi.json`.
<details>
<summary>🔗 Endpoint</summary>
| Metodo | Percorso | Descrizione |
|--------|----------|-------------|
| GET | `/api/v1/links` | Elenca link (`?limit`/`?cursor` pagine, `?fields=` campi ridotti) |
| GET | `/api/v1/links/:id` | Ottieni un link per id |
| POST | `/api/v1/links` | Crea un link |
| PUT | `/api/v1/links/:id` | Aggiorna un link (parziale - cambiano solo i campi inviati) |
| DELETE | `/api/v1/links/:id` | Elimina un link |
| PUT | `/api/v1/links/reorder` | Riordina i link (`{ "ids": [3, 1, 2] }`) |
| POST | `/api/v1/links/import` | Crea link in blocco (1-100 elementi, risultati per elemento) |
| GET | `/api/v1/sections` | Elenca sezioni (`?pageId=N` filtra) |
| POST | `/api/v1/sections` | Crea una sezione |
| PUT | `/api/v1/sections/:id` | Aggiorna una sezione (parziale) |
| DELETE | `/api/v1/sections/:id` | Elimina una sezione (i suoi link tornano senza categoria) |
| PUT | `/api/v1/sections/reorder` | Riordina le sezioni (`{ "ids": [3, 1, 2] }`) |
| GET | `/api/v1/profile` | Ottieni il profilo |
| PUT | `/api/v1/profile` | Aggiorna il profilo (parziale) |
| GET | `/api/v1/analytics` | Visualizzazioni, clic e link principali (`?range=7d\|30d\|90d`) |
Le risposte di successo racchiudono il payload in `data`; gli errori sono `{ "error": { "code", "message" } }` con gli stati HTTP corrispondenti (401 chiave mancante o non valida, 400 validazione, 403 modalità demo, 429 limite). Le scritture dei link seguono la stessa validazione dell'interfaccia admin - lista consentita degli schemi URL inclusa. Anche le letture inviano un `ETag`; rimandalo come `If-None-Match` per ricevere un `304` vuoto finché non cambia nulla. Ogni risposta porta anche il contratto delle intestazioni: `X-RateLimit-Limit`, `X-RateLimit-Remaining` e `X-RateLimit-Reset` mostrano il budget al minuto (un `429` invia anche `Retry-After`), `Cache-Control: no-store` tiene le risposte autenticate fuori dalla cache, e un `401` risponde con `WWW-Authenticate`.
</details>
<details>
<summary>📦 Ricette API (curl)</summary>
```bash
# Configurazione una tantum
export LB_API_KEY="lbk_..."
export BASE="https://your-instance.example/api/v1"
```
```bash
# Elenca i link: lista completa o una pagina paginata con campi ridotti
# (--oauth2-bearer invia l'header Bearer per te)
curl -s --oauth2-bearer "$LB_API_KEY" "$BASE/links" | jq '.data | length'
curl -s --oauth2-bearer "$LB_API_KEY" "$BASE/links?limit=10&fields=title,url" | jq '.meta'
```
```bash
# Crea un link (201 restituisce la riga creata, con l'id)
curl -s -X POST --oauth2-bearer "$LB_API_KEY" -H "Content-Type: application/json" \
-d '{"title":"Docs","url":"https://example.com/docs","cardStyle":"rich"}' \
"$BASE/links" | jq '.data.id'
```
```bash
# Aggiornamento parziale: cambiano solo i campi inviati (null azzera)
curl -s -X PUT --oauth2-bearer "$LB_API_KEY" -H "Content-Type: application/json" \
-d '{"isActive": false}' "$BASE/links/12" | jq '.data.isActive'
```
```bash
# Riordina i link, poi leggi una metrica
curl -s -X PUT --oauth2-bearer "$LB_API_KEY" -H "Content-Type: application/json" \
-d '{"ids":[3,1,2]}' "$BASE/links/reorder" | jq '.data'
curl -s --oauth2-bearer "$LB_API_KEY" "$BASE/analytics?range=30d" | jq '.data.ctr'
```
```bash
# Crea una sezione, poi importa link in blocco (risultati per elemento)
curl -s -X POST --oauth2-bearer "$LB_API_KEY" -H "Content-Type: application/json" \
-d '{"pageId":1,"title":"Work"}' "$BASE/sections" | jq '.data.id'
curl -s -X POST --oauth2-bearer "$LB_API_KEY" -H "Content-Type: application/json" \
-d '{"items":[{"title":"A","url":"https://a.example"},{"title":"","url":"https://bad.example"}]}' \
"$BASE/links/import" | jq '.data.results'
```
```bash
# Lettura condizionale: riproduci l'ETag → 304 vuoto finché non cambia nulla
ETAG=$(curl -sI --oauth2-bearer "$LB_API_KEY" "$BASE/links" | tr -d '\r' | grep -i '^etag:' | cut -d' ' -f2)
curl -s -o /dev/null -w '%{http_code}\n' --oauth2-bearer "$LB_API_KEY" -H "If-None-Match: $ETAG" "$BASE/links" # → 304
```
Segui `meta.nextCursor` (rimandalo come `?cursor=`) per scorrere tutte le pagine. Il contratto completo leggibile da macchina è su `$BASE/openapi.json`.
</details>
## 🎨 Sistema di Temi
Sono inclusi 11 preset pronti all'uso: **Aurora** (flagship animato), **Glassmorphism**, **Neon Cyberpunk**, **Editorial Paper**, **Terminal Mono**, **Pastel Soft**, **Brutalist**, **Retro Sunset**, **Minimal Light**, **8-Bit Retro** e **Frutiger Aero**.
<details>
<summary>🎛️ Cosa controlla il personalizzatore</summary>
Il motore dei temi è un sistema di token basato su custom property CSS (`--lb-*`) - ogni colore, raggio, ombra e font della pagina pubblica è un token.
- **Sfondo** - 8 tipi (solido, gradiente, radiale, mesh, aurora, gradiente animato, immagine, pattern) con controlli per angolo, overlay e opacità
- **Colori** - accento, secondario, testo, testo attenuato, sfondo card, bordo card (hex o rgba)
- **Tipografia** - 15 Google Fonts selezionate, scala del font, peso, spaziatura lettere - oppure carica il tuo woff2/woff (max 2 MB). I font caricati sono serviti same-origin, incorporati negli export dei temi e portati nei backup
- **Stile card** - 7 stili di link (pill, rounded, sharp, glass, outline, neon, pixel), effetti hover, dimensione pulsante, raggio degli angoli, spessore bordo, intensità ombra
- **Layout** - larghezza del contenitore, allineamento (sinistra/centro/destra), densità (compatta/normale/rilassata)
- **Effetti** - bagliore con colore personalizzato, blur glass, texture noise, animazione di reveal
- **Duplica / importa / esporta** - clona qualsiasi tema come copia modificabile e condividilo come JSON
</details>
## 📖 Documentazione e Link
[Contribuire](CONTRIBUTING.md) · [Politica di Sicurezza](SECURITY.md) · [Changelog](CHANGELOG.md) · [Risoluzione dei Problemi](TROUBLESHOOTING.md) · [Domini Personalizzati](docs/custom-domains.md) · [Decisioni Architetturali](docs/adr/) · [Riferimento Configurazione](.env.example)
Sorgente: [GitHub](https://github.com/OmniRise/LinkBreeze) (canonico) · [GitLab](https://gitlab.com/omnirise00/linkbreeze) (mirror pubblico, sincronizzato automaticamente) · Immagine: [`docker.io/omnirise/linkbreeze`](https://hub.docker.com/r/omnirise/linkbreeze)
Issue e PR sono benvenute su entrambe le forge.
## 🤝 Contribuire
I contributi sono benvenuti! Vedi [CONTRIBUTING.md](CONTRIBUTING.md) per le linee guida.
## 📜 Licenza
MIT - fai quello che vuoi. Vedi [LICENSE](LICENSE).
## 🏢 Informazioni
Realizzato da [Manak-hash](https://github.com/Manak-hash) · Un progetto [OmniRise](https://omnirise.dev).