# Instalar el widget de chat en Next.js y React

> Añade el widget de intoCHAT a una app de Next.js con next/script en el layout raíz, o a una app de React con index.html o useEffect, sin burbujas duplicadas.

El widget de intoCHAT es un script normal, no un componente de React. Lee el ID de tu agente de su atributo `data-chatbot-id` y añade la burbuja a `document.body`, fuera de tu árbol de React, así que ni los re-renders ni los cambios de ruta la afectan.

## Next.js con App Router

Carga el script una sola vez en el layout raíz con el componente `Script` de `next/script`:

```tsx
import Script from 'next/script'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://www.intochat.ai/api/embed.js"
          data-chatbot-id="YOUR_AGENT_ID"
          strategy="lazyOnload"
        />
      </body>
    </html>
  )
}
```

- **El atributo data.** Next.js pasa los atributos adicionales como `data-chatbot-id` al elemento script final, que es donde el widget lo busca.
- **La estrategia.** `lazyOnload` carga el widget cuando el navegador está inactivo, después del resto de recursos de la página. `afterInteractive`, la opción predeterminada, lo carga antes, así que la burbuja aparece antes. Las dos funcionan.
- **No uses `beforeInteractive`.** Esa estrategia es para scripts que la página necesita antes de ser interactiva. El widget de chat no es uno de ellos, y cargarlo tan pronto solo compite con tu propio código.
- **Server Components.** El layout puede seguir siendo un Server Component, porque este `Script` no tiene manejadores de eventos.

Next.js carga el script una sola vez, aunque el visitante cambie de ruta. Con el Pages Router, añade el mismo `Script` en `pages/_app`.

Para mostrar el chat solo en algunas rutas, pon el `Script` en un layout anidado. Una vez cargada, la burbuja sigue en la página tras la navegación en el cliente hacia otras rutas, hasta la siguiente carga completa.

## React con Vite o Create React App

Elige una de las dos opciones, no ambas. El script de inserción ignora una segunda copia para el mismo agente, así que usar las dos solo lo carga dos veces.

**Opción 1: index.html.** Pega la etiqueta script de la pestaña **Share** justo antes de `</body>` en `index.html`: en la raíz del proyecto con Vite, o en `public/index.html` con Create React App.

**Opción 2: un componente.** Útil si quieres decidir en el código si se carga el widget, por ejemplo solo en producción:

```jsx
import { useEffect } from 'react'

export default function IntoChatWidget() {
  useEffect(() => {
    // Load the widget only once, even when StrictMode runs effects twice
    if (document.getElementById('intochat-embed')) return

    const script = document.createElement('script')
    script.id = 'intochat-embed'
    script.src = 'https://www.intochat.ai/api/embed.js'
    script.setAttribute('data-chatbot-id', 'YOUR_AGENT_ID')
    document.body.appendChild(script)
  }, [])

  return null
}
```

Renderiza `IntoChatWidget` una sola vez, en tu componente raíz, por ejemplo `App`. Define el atributo antes de añadir el elemento a la página, como arriba.

### StrictMode y burbujas duplicadas

En desarrollo, el StrictMode de React ejecuta los efectos dos veces. La comprobación del `id` al principio del efecto evita que el script se añada dos veces. Aunque no estuviera, no tendrías una segunda burbuja, porque el script de inserción añade solo una por agente y página. No elimines el script en una función de limpieza: eso no quita la burbuja, que sigue en `document.body` hasta la siguiente carga completa.

## Acciones del lado del cliente

El agente puede llamar a funciones de tu app durante un chat, por ejemplo para leer un estado o abrir un formulario. Regístralas con `window.IntoChatActions.register`. Consulta [Acciones del lado del cliente](/es/docs/client-actions).

## Content Security Policy

Permite `https://www.intochat.ai` en `script-src`, `connect-src` y `frame-src`. Si tu política usa nonces, pasa el `nonce` al componente `Script`: Next.js lo transmite igual que el atributo data.

## Comprobarlo

Abre cualquier ruta. La burbuja aparece en la esquina inferior y se mantiene al navegar. Dos burbujas significan que se cargan dos códigos con distintos ID de agente. Ninguna burbuja y "Chatbot not found." en la consola significan que el ID del agente no es correcto. Más casos en [Solución de problemas](/es/docs/troubleshooting) y más contexto en las guías de [Next.js](/es/integraciones/nextjs) y [React](/es/integraciones/react).
