Ir al contenido
Todos los artículos

Guías del producto

Cómo añadir prueba social a una app Next.js

Cómo instalar notificaciones de compra de Provedly y un contador de visitantes en vivo en una app Next.js, gestionar cambios de ruta y pasar el visitor id a Stripe.

Equipo de Provedly··6 min de lectura

Provedly funciona en una app Next.js con una sola etiqueta script, cargada una vez desde tu layout raíz. El widget se renderiza dentro de un Shadow DOM, así que no toca tu Tailwind ni tus CSS Modules, y el loader es idempotente entre cambios de ruta del lado del cliente. Lo único específico de Next es decidir dónde poner la etiqueta y, si quieres atribución, reenviar el visitor id a tu checkout.

La instalación de una línea

Crea un widget en el dashboard, copia el token y añade el script a tu layout raíz. Con el App Router, next/script es la forma limpia de hacerlo.

// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({
    children,
}: {
    children: React.ReactNode;
}) {
    return (
        <html lang="en">
            <body>
                {children}
                <Script
                    src="https://provedly.app/w/widget.js"
                    data-token="pp_your_token"
                    strategy="afterInteractive"
                />
            </body>
        </html>
    );
}

afterInteractive carga el script después de la hidratación, que es el equilibrio correcto para un elemento no crítico. No uses beforeInteractive; nada en una notificación de compra necesita bloquear la página. El bundle pesa unos 6 KB comprimido con gzip y el loader obtiene la configuración del widget desde GET /api/w/{token}/config, que devuelve los ajustes y hasta 30 registros recientes.

Si todavía usas el Pages Router, pon el mismo <Script> en pages/_app.tsx. El comportamiento es idéntico.

Cambios de ruta y el problema de las SPA

Las notificaciones se rigen por límites por sesión: por defecto, 3 segundos de espera inicial, 6 segundos en pantalla, 30 segundos de intervalo y como máximo 5 notificaciones por sesión. Esos límites los controla el widget, no la página, así que un visitante que recorre cinco páginas de producto no recibe cinco ciclos nuevos. Es intencional. Una notificación que vuelve a aparecer en cada navegación es la forma más rápida de que la descarten como spam.

El loader comprueba si ya existe una instancia antes de inicializarse, así que aunque tu layout vuelva a montar la etiqueta script no se renderizará dos veces. Si prefieres montarlo desde un componente de cliente, el patrón documentado es este:

'use client';
import { useEffect } from 'react';

export function ProofWidget() {
    useEffect(() => {
        if (document.querySelector('script[data-token="pp_your_token"]'))
            return;
        const s = document.createElement('script');
        s.src = 'https://provedly.app/w/widget.js';
        s.dataset.token = 'pp_your_token';
        s.async = true;
        document.body.appendChild(s);
    }, []);
    return null;
}

Renderiza <ProofWidget /> una sola vez, en el layout raíz. La segmentación por URL (todas las páginas, solo estas, todas excepto) se configura en el dashboard, así que no necesitas renderizado condicional en React para mantener el widget fuera de, por ejemplo, /account.

Estilos: qué controlas y qué no

Como el widget vive en un Shadow DOM, tu CSS global no puede alcanzarlo y su CSS no puede alcanzarte a ti. Eso descarta las típicas colisiones de nombres de clase y las sorpresas con z-index. En su lugar, eliges el aspecto en el dashboard: uno de cinco temas (Clean white, Deep ocean, Midnight, Electric violet, Sunset blaze), el formato del nombre, el formato de la ubicación y la posición. Lee Shadow DOM: por qué el widget no puede romper tu CSS si quieres los detalles.

Si usas una Content Security Policy estricta, permite https://provedly.app en script-src y connect-src. El widget hace peticiones a los endpoints de config, track y presence en ese origen y en ningún otro.

Cómo hacer que las compras sean "verificadas"

Una notificación que dice "Compra verificada" es una notificación que llegó a través de un webhook firmado. Para una app Next.js que cobra con Stripe Checkout, eso significa registrar https://provedly.app/api/hooks/stripe/{token} como endpoint de webhook para checkout.session.completed y pegar el signing secret en la pestaña Data del widget. El paso a paso completo está en Webhooks de Stripe para compras verificadas.

Si cobras desde tu propio backend, o con un proveedor que no tiene webhook de Provedly, envía los registros desde un Route Handler o una server action:

// app/api/orders/route.ts, after payment is confirmed
await fetch('https://provedly.app/api/v1/widgets/pp_your_token/records', {
    method: 'POST',
    headers: {
        Authorization: 'Bearer ' + process.env.PROVEDLY_API_KEY,
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: order.customerName,
        city: order.shipping.city,
        country: order.shipping.countryCode,
        product_name: order.lines[0].title,
        price: order.totalFormatted,
        external_id: order.id,
        visitor: order.provedlyVisitor,
    }),
});

Los registros enviados así se muestran, pero con la etiqueta "Imported", nunca "Verified". Esa es la regla de honestidad: solo un evento firmado criptográficamente por el proveedor de pagos se gana la marca. Consulta Usar la Records API para compras desde tu propio backend.

Atribución: reenvía el visitor id

El dashboard informa de los pedidos asistidos por prueba, es decir, un comprador que vio una notificación antes de comprar, emparejado por visitor id dentro de una ventana de 30 días. Para que haya coincidencia, la compra tiene que llevar el id. En el cliente, léelo con window.Provedly?.visitorId() y envíalo a tu código de checkout. Con Stripe, pásalo como metadata.provedly_visitor al crear la Checkout Session. Con la Records API, envíalo en el campo visitor.

Paso Dónde Qué pasar
Leer el id componente de cliente en el checkout window.Provedly?.visitorId()
Stripe Checkout servidor, al crear la sesión metadata: { provedly_visitor: id }
Records API servidor, después del pago "visitor": id

Sin id, no hay atribución. El dashboard nunca estima.

Lista de comprobación antes de publicar

  • Script en el layout raíz con strategy="afterInteractive".
  • Dominio de producción añadido en los dominios permitidos del sitio; añade los hosts de preview y staging de forma explícita, porque las previews de *.vercel.app no coinciden con tu dominio de producción.
  • CSP actualizada, si tienes una.
  • Webhook registrado (Stripe) o Records API conectada (backend propio).
  • Visitor id reenviado en el checkout.

Preguntas frecuentes

¿El widget funciona con React Server Components?

Sí. La etiqueta script es HTML plano que sale del layout; no necesita un límite de cliente. El componente opcional ProofWidget es un componente de cliente solo porque usa useEffect.

¿La notificación provoca desplazamientos de layout?

No. El widget tiene posición fija dentro de su propia shadow root y no ocupa espacio en el flujo del documento, así que no suma al CLS.

¿Puedo mostrarlo solo en las páginas de marketing y no dentro de la app?

Sí. Usa la segmentación por URL del dashboard ("all except" con /app/*, o "only these" con tus rutas de marketing) en lugar de renderizado condicional.

Empieza con el plan Free, que incluye compras verificadas y 2,000 impresiones al mes: crea una cuenta.

next.jsinstalaciónreact

Recibe los nuevos artículos por email

Prueba social honesta, compras verificadas y lo que de verdad mueve la conversión. Como mucho unos pocos emails al mes; date de baja con un clic.

Te enviamos un email para confirmar. Tu dirección solo se usa para este boletín; consulta la política de privacidad (en inglés).

Muestra pruebas que puedas respaldar.

Plan gratis, un sitio, 2,000 impresiones al mes y compras verificadas incluidas. En el plan gratis, la insignia enlaza a tu página de verificación, y de eso se trata.