Social Proof
Notifiche live di attività recenti (acquisti, iscrizioni, conteggi) per aumentare la fiducia. Include analytics, integrazioni Stripe/Shopify, webhook outbound firmati e binding A/B.
1. Setup widget
Se usi già lo snippet unico A/B, il Social Proof viene caricato automaticamente quando il dominio corrisponde a un sito configurato:
<script
src="https://project--YOUR_PROJECT.lovable.app/snippets/lvbl.js"
data-project-id="YOUR_PROJECT_ID"
data-proof="auto"
defer></script>In alternativa incolla lo snippet widget prima di </body>. Attributi:
data-site-key— la site key del sito proof (richiesto)data-debug— log in console
<script
src="https://project--YOUR_PROJECT.lovable.app/snippets/proof-widget.js"
data-site-key="YOUR_SITE_KEY"
data-debug
defer></script>2. Tracking eventi e conversioni
Il widget invia automaticamente impression, click e close. Per le conversioni:
<script>
// Inviato tramite il widget caricato in pagina
window.lvblProof && window.lvblProof.convert({
campaign_id: "<uuid-campagna>",
value: 49,
currency: "EUR"
});
</script>Oppure tramite HTTP diretto:
curl -X POST https://.../api/public/proof/track \
-H "Content-Type: application/json" \
-d '{
"site_key": "YOUR_SITE_KEY",
"campaign_id": "<uuid>",
"kind": "impression",
"visitor_id": "v_abc",
"page_url": "https://shop.example/checkout"
}'3. Token engine
Sostituiti sia in message_template sia nel custom HTML:
{{name}}— nome del soggetto evento{{city}}/{{country}}— geo (server-side da header CF){{event}}— etichetta tradotta (es. "ha acquistato"){{time_ago}}— relativo conIntl.RelativeTimeFormat(it/en){{value}}/{{currency}}
4. Templates
Selezionabili in campagna: toast, bubble, badge, banner, card-image, custom.
Il template custom accetta HTML libero renderizzato dentro Shadow DOM (nessun leak CSS). Usa data-proof-close per il pulsante chiusura.<script> non viene eseguito.
<div style="display:flex;gap:10px;padding:12px 14px;background:#0f172a;color:#fff;border-radius:12px;font-family:system-ui">
<div>🔥</div>
<div>
<strong>{{name}}</strong> {{event}}
<div style="font-size:12px;opacity:.7">{{city}} · {{time_ago}}</div>
</div>
<button data-proof-close style="background:transparent;border:0;color:#fff">×</button>
</div>5. Targeting, timing, cap
Per ogni campagna puoi configurare:
- Targeting: include/exclude path (glob
*), device, audience new/returning, filtri UTM, country - Timing: delay iniziale, display ms, gap min/max, pausa al hover
- Cap: max per sessione / giorno, cooldown dopo chiusura
6. Analytics
Tutte le interazioni sono persistite in proof_widget_events (kind = impression | click | close | convert) con dedup, geo e visitor id. Il pannello Analytics nel sito mostra KPI, timeseries, breakdown per campagna / country / page.
7. Integrazioni inbound
Stripe
# Endpoint da configurare in Stripe → Webhooks
POST https://.../api/public/proof/in/stripe?site_key=YOUR_SITE_KEY
# Headers: Stripe-Signature (verificato in HMAC con stripe_webhook_secret salvato nel sito)
# Event: checkout.session.completed → genera proof_event di tipo "purchase"Shopify
# Endpoint da configurare in Shopify → Notifications → Webhooks
POST https://.../api/public/proof/in/shopify?site_key=YOUR_SITE_KEY
# Header: X-Shopify-Hmac-Sha256 (base64) verificato con shopify_webhook_secret
# Topic: orders/paid → genera proof_event "purchase"Configura i webhook secret nel tab Integrazioni del sito.
8. Webhook outbound
Configura endpoint in Integrazioni → Outbound. Ogni delivery è firmato HMAC-SHA256 con header X-Lvbl-Signature e logato in proof_webhook_log.
// Verifica HMAC outbound (Node)
import crypto from "crypto";
function verify(rawBody, header, secret) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
// Eventi: event.created | widget.impression | widget.click | widget.convert
// Header firma: X-Lvbl-Signature9. Integrazione A/B
Nel tab A/B test del sito puoi legare un esperimento: ogni variante mappa a una campagna proof. Lo snippet assegna deterministicamente il visitatore e mostra solo la campagna scelta. La variante di controllo (null) non mostra nulla.
Payload variante:
{
"proof_campaign_id": "<uuid-campagna-proof>" // oppure null per controllo puro
}QA preview: ?lvbl_force=<expId>:<variantId>. Lo snippet emette lvbl_exposure e — alla convert() — anche lvbl_conversion, consumati dagli adapter analytics (GA4 / Mixpanel / dataLayer).
10. SDK Node
import { ProofClient } from "@lvbl/sdk-node";
const proof = new ProofClient({
baseUrl: "https://project--YOUR_PROJECT.lovable.app",
siteKey: "YOUR_SITE_KEY",
});
await proof.collect({
event_type: "purchase",
display_name: "Marco",
city: "Milano",
value: 49,
currency: "EUR",
});
await proof.convert({ campaign_id: "<uuid>", value: 49, currency: "EUR" });FAQ
- CORS: aggiungi i domini in Origini del sito.
- Cache config: 30s lato CDN, refresh forzato con
window.lvblProof.refresh(). - Bot: filtrati lato server via User-Agent (no track).
- Geo: derivata dagli header Cloudflare
cf-ipcountry/cf-ipcity.