Nexoply

Tutoriales

Cómo agregar un chatbot con IA a un sitio Next.js (App Router y Pages Router)

Agrega un chatbot con IA a Next.js con next/script en app/layout.tsx o pages/_app.tsx. Sin paquete npm, compatible con SSR y la navegación del cliente.

Actualizado el 30 de septiembre de 2026 6 min de lectura

En resumen

Crea una cuenta gratuita en Nexoply y copia la clave de tu chatbot desde la página Chatbot de tu panel. En el App Router, agrega <Script src="https://nexoply.com/widget.js" data-chatbot={key} strategy="afterInteractive" /> de next/script dentro de <body> en app/layout.tsx; en el Pages Router, pon el mismo <Script> en pages/_app.tsx. No hay paquete npm que instalar: el widget solo se ejecuta en el navegador, mantiene la conversación durante la navegación del lado del cliente y no toca tu marcado, así que no hay problemas de hidratación.

  • Sin paquete npm: una etiqueta next/script en tu layout raíz (App Router) o en _app (Pages Router).
  • Guarda la clave en NEXT_PUBLIC_NEXOPLY_KEY; es pública, no un secreto, y no da acceso a tu cuenta.
  • Usa strategy="afterInteractive" (la opción habitual) o "lazyOnload" para cargarlo después de todo lo demás.
  • Compatible con SSR: solo se ejecuta en el navegador, se monta en un Shadow DOM sobre document.body y sobrevive a los cambios de ruta.
  • Abre el chat desde tu propio botón con window.dispatchEvent(new Event("nexoply:open-chat")).

Antes de empezar

  • Una cuenta de Nexoply. Regístrate gratis: el plan Free incluye 100 conversaciones al mes, sin tarjeta.
  • La información del negocio en Nexoply: servicios y precios, preguntas frecuentes, políticas, horarios y zonas de servicio. Lo más rápido es escribir la dirección del sitio y dejar que Nexoply importe las páginas públicas (incluidas las que se generan con JavaScript); tú revisas las sugerencias y no se agrega nada hasta que lo apruebes.
  • La clave de tu chatbot. En el panel, abre Chatbot (haz clic en Crear chatbot si todavía no lo creaste). El código de instalación que aparece ahí trae la clave en su atributo data-chatbot.

En un sitio HTML simple, el código de instalación se pegaría antes de </body>:

<script src="https://nexoply.com/widget.js" data-chatbot="YOUR-KEY" async></script>

En Next.js no editas el HTML directamente, así que agregas el mismo script con el componente integrado next/script. La clave es pública: solo le indica al widget a qué negocio pertenece.

App Router: agrega el script en app/layout.tsx

El layout raíz envuelve todas las páginas, así que al agregar el script ahí el chat aparece en todo el sitio. Importa Script de next/script y colócalo dentro de <body>, después de {children}:

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

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        {/* Widget de chat de Nexoply: carga en el navegador después de la hidratación */}
        <Script
          src="https://nexoply.com/widget.js"
          data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

Luego pon la clave en una variable de entorno. El prefijo NEXT_PUBLIC_ hace que Next.js la incluya en el paquete del navegador, lo cual está bien aquí porque la clave no es un secreto:

# .env.local (no se sube a git)
NEXT_PUBLIC_NEXOPLY_KEY=YOUR-KEY

Pages Router: agrega el script en pages/_app.tsx

En el Pages Router, pages/_app.tsx envuelve todas las páginas, así que el mismo <Script> va ahí, junto a <Component {...pageProps} />. Usa la misma variable de .env.local:

// pages/_app.tsx
import type { AppProps } from "next/app";
import Script from "next/script";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />
      <Script
        src="https://nexoply.com/widget.js"
        data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
        strategy="afterInteractive"
      />
    </>
  );
}

Si tu proyecto combina los dos routers, agrega el script tanto en app/layout.tsx como en pages/_app.tsx. Cargarlo dos veces no causa problemas: el widget se monta una sola vez por clave de chatbot.

Elegir una estrategia y cómo se comporta

strategy="afterInteractive" carga el widget justo cuando la página se vuelve interactiva, así que el botón de chat aparece rápido. strategy="lazyOnload" espera a que el navegador esté libre y todo lo demás haya cargado; elígelo si quieres que la primera carga sea lo más ligera posible y no te importa que el botón aparezca un momento después. Ninguna de las dos pone el script en la ruta crítica de renderizado. Consulta la documentación de next/script para más detalles.

  • Navegación del lado del cliente. El widget mantiene la conversación abierta mientras los visitantes pasan de una página a otra con <Link> o el router, y vuelve a revisar tus reglas de página cuando cambia la URL, sin código extra.
  • Seguro con SSR e hidratación. Solo se ejecuta en el navegador y se monta en document.body, fuera del marcado que React hidrata, así que nunca provoca errores de hidratación.
  • Shadow DOM. Tu CSS global o de Tailwind no afecta al chat, y sus estilos no afectan a tu app. Los re-renderizados nunca lo eliminan.
  • StrictMode y Fast Refresh. Aunque los efectos se ejecuten dos veces en desarrollo o recargues en caliente, no se crea un segundo chat: se monta una vez por clave.
  • Almacenamiento. No usa cookies; usa localStorage para un identificador anónimo del visitante y sessionStorage para la conversación actual.

Abre el chat desde tu propio botón

¿Quieres un botón "Chatea con nosotros" en tu sección principal o de precios? Dispara el evento nexoply:open-chat en window. Como usa onClick, debe ser un componente de cliente:

"use client";
// components/ChatButton.tsx

export function ChatButton() {
  return (
    <button
      type="button"
      // abre la ventana de chat de Nexoply
      onClick={() => window.dispatchEvent(new Event("nexoply:open-chat"))}
    >
      Chat with us
    </button>
  );
}

Usa <ChatButton /> en cualquier página o componente de servidor. No hay una API para quitar el widget una vez cargado: para ocultar el botón de mensaje en algunas páginas (por ejemplo /checkout), agrega una regla de página con "Sin botón" en Chatbot → Personalizar → Botón de mensaje → Distinto en algunas páginas.

Prueba local, sitios permitidos y CSP

Ejecuta next dev, abre http://localhost:3000 y aparece un botón de chat en la esquina. Haz una pregunta real, como "¿Trabajan los fines de semana?"; en segundos la conversación aparece en Conversaciones en tu panel. Los cambios que hagas en el panel llegan al sitio en aproximadamente un minuto, sin volver a desplegar.

Si tu app envía un encabezado Content-Security-Policy (por ejemplo desde un middleware o next.config), permite Nexoply en:

  • script-src https://nexoply.com: para cargar widget.js.
  • connect-src https://nexoply.com: para las solicitudes del chat.
  • img-src https://nexoply.com: para imágenes como el logo y el ícono del botón.

Solución de problemas y próximos pasos

  • No hay botón y data-chatbot está vacío en el código de la página. No se leyó la variable de entorno: revisa el prefijo NEXT_PUBLIC_, reinicia next dev y, en tu hosting, agrega la variable y vuelve a desplegar.
  • El script está en una sola página en lugar del layout. Ponlo en app/layout.tsx o pages/_app.tsx para que cargue en todas las rutas.
  • Se modificó la etiqueta. Debe conservar el atributo data-chatbot y un src que contenga widget.js.
  • Bloqueado por CSP o por los sitios permitidos. Busca errores en la consola del navegador y revisa las dos secciones anteriores.
  • Chatbot apagado. Comprueba que el interruptor Chatbot activado esté encendido.
  • Bloqueadores de anuncios. En raras ocasiones, una extensión bloquea los widgets de chat. Prueba en una ventana privada sin extensiones.

Cuando funcione, adáptalo al sitio en Chatbot → Personalizar: ícono, texto, colores y posición del botón, o una pestaña lateral en el borde de la pantalla (como "Ayuda"); un aspecto distinto en celulares; y reglas de página para páginas elegidas (por ejemplo, una pestaña lateral solo en /pricing). Mira las funciones y cómo funciona, compara los precios o lee las guías de React y Vue.

Preguntas frecuentes

¿Hay un paquete npm de Nexoply para Next.js?

No, y no lo necesitas. El widget es siempre el script https://nexoply.com/widget.js con un atributo data-chatbot, agregado con next/script. Toda la configuración está en tu panel de Nexoply.

¿Funciona en Vercel?

Sí. Es solo una etiqueta script que se carga en el navegador del visitante: nada se ejecuta en tu servidor y no hay rutas de API ni configuraciones de servidor que agregar. Define NEXT_PUBLIC_NEXOPLY_KEY en las variables de entorno de tu proyecto en Vercel y vuelve a desplegar.

¿Afecta las Core Web Vitals o el rendimiento?

Está pensado para no hacerlo. El script carga de forma asíncrona después de la hidratación (afterInteractive) o cuando el navegador está libre (lazyOnload), así que nunca bloquea el renderizado, y se monta fuera del diseño de tu página.

App Router o Pages Router: ¿cuál debo usar?

El que ya use tu proyecto; el widget funciona igual con los dos. App Router: app/layout.tsx. Pages Router: pages/_app.tsx.

¿Puedo cargarlo solo después del consentimiento de cookies?

Sí. Renderiza el <Script> solo cuando el visitante haya aceptado, por ejemplo en un componente de cliente que revise tu estado de consentimiento. El widget en sí no usa cookies.

Deja que tu sitio web responda las preguntas por ti

Añade la información de tu negocio, prueba tu asistente y ponlo en tu sitio web, todo con el plan gratuito.