Nexoply

Tutoriais

Como adicionar um chatbot com IA a um site Next.js (App Router e Pages Router)

Adicione um chatbot com IA ao Next.js com next/script em app/layout.tsx ou pages/_app.tsx. Sem pacote npm, compatível com SSR e navegação no cliente.

Atualizado em 30 de setembro de 2026 6 min de leitura

Em resumo

Crie uma conta gratuita na Nexoply e copie a chave do seu chatbot na página Chatbot do painel. No App Router, adicione <Script src="https://nexoply.com/widget.js" data-chatbot={key} strategy="afterInteractive" /> do next/script dentro de <body> em app/layout.tsx; no Pages Router, coloque o mesmo <Script> em pages/_app.tsx. Não há pacote npm para instalar: o widget roda só no navegador, mantém a conversa durante a navegação no lado do cliente e não mexe no seu markup, então não há problemas de hidratação.

  • Sem pacote npm: uma tag next/script no seu layout raiz (App Router) ou no _app (Pages Router).
  • Guarde a chave em NEXT_PUBLIC_NEXOPLY_KEY; ela é pública, não é um segredo e não dá acesso à sua conta.
  • Use strategy="afterInteractive" (a escolha padrão) ou "lazyOnload" para carregá-lo depois de todo o resto.
  • Compatível com SSR: roda só no navegador, é montado em um Shadow DOM no document.body e sobrevive às mudanças de rota.
  • Abra o chat pelo seu próprio botão com window.dispatchEvent(new Event("nexoply:open-chat")).

Antes de começar

  • Uma conta na Nexoply. Cadastre-se grátis: o plano Free inclui 100 conversas por mês, sem cartão.
  • As informações do negócio na Nexoply: serviços e preços, perguntas frequentes, políticas, horários e áreas de atendimento. O jeito mais rápido é digitar o endereço do site e deixar a Nexoply importar as páginas públicas (inclusive as geradas com JavaScript); você revisa as sugestões e nada é adicionado até você aprovar.
  • A chave do seu chatbot. No painel, abra Chatbot (clique em Criar chatbot se ainda não criou). O código de instalação que aparece ali traz a chave no atributo data-chatbot.

Em um site HTML simples, o código de instalação seria colado antes de </body>:

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

No Next.js você não edita o HTML diretamente, então adiciona o mesmo script com o componente nativo next/script. A chave é pública: ela só diz ao widget a qual negócio ele pertence.

App Router: adicione o script em app/layout.tsx

O layout raiz envolve todas as páginas, então adicionar o script ali coloca o chat no site inteiro. Importe Script de next/script e coloque-o dentro de <body>, depois 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 da Nexoply: carrega no navegador depois da hidratação */}
        <Script
          src="https://nexoply.com/widget.js"
          data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

Depois coloque a chave em uma variável de ambiente. O prefixo NEXT_PUBLIC_ faz o Next.js incluí-la no bundle do navegador, o que não tem problema aqui porque a chave não é um segredo:

# .env.local (não vai para o git)
NEXT_PUBLIC_NEXOPLY_KEY=YOUR-KEY

Pages Router: adicione o script em pages/_app.tsx

No Pages Router, pages/_app.tsx envolve todas as páginas, então o mesmo <Script> vai ali, ao lado de <Component {...pageProps} />. Use a mesma variável do .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"
      />
    </>
  );
}

Se o seu projeto combina os dois routers, adicione o script tanto em app/layout.tsx quanto em pages/_app.tsx. Carregá-lo duas vezes não causa problema: o widget é montado uma única vez por chave de chatbot.

Escolher uma estratégia e como ele se comporta

strategy="afterInteractive" carrega o widget logo que a página fica interativa, então o botão de chat aparece rápido. strategy="lazyOnload" espera o navegador ficar ocioso e todo o resto carregar; escolha essa opção se quiser o primeiro carregamento o mais leve possível e não se importar que o botão apareça um instante depois. Nenhuma das duas coloca o script no caminho crítico de renderização. Veja a documentação do next/script para mais detalhes.

  • Navegação no lado do cliente. O widget mantém a conversa aberta enquanto os visitantes passam de uma página para outra com <Link> ou o router, e confere de novo as suas regras de página quando a URL muda, sem código extra.
  • Seguro com SSR e hidratação. Roda só no navegador e é montado no document.body, fora do markup que o React hidrata, então nunca causa erros de hidratação.
  • Shadow DOM. O seu CSS global ou do Tailwind não afeta o chat, e os estilos dele não afetam o seu app. Novas renderizações nunca o removem.
  • StrictMode e Fast Refresh. Mesmo com efeitos rodando duas vezes em desenvolvimento ou hot reload, não surge um segundo chat: ele é montado uma vez por chave.
  • Armazenamento. Não usa cookies; usa localStorage para um identificador anônimo do visitante e sessionStorage para a conversa atual.

Abra o chat pelo seu próprio botão

Quer um botão "Fale com a gente" na seção principal ou de preços? Dispare o evento nexoply:open-chat no window. Como ele usa onClick, precisa ser um componente de cliente:

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

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

Use <ChatButton /> em qualquer página ou componente de servidor. Não há uma API para remover o widget depois de carregado: para esconder o botão de mensagem em algumas páginas (por exemplo /checkout), adicione uma regra de página com "Sem botão" em Chatbot → Personalizar → Botão de mensagem → Diferente em algumas páginas.

Teste local, sites permitidos e CSP

Rode next dev, abra http://localhost:3000 e um botão de chat aparece no canto. Faça uma pergunta real, como "Vocês atendem aos fins de semana?"; em segundos a conversa aparece em Conversas no seu painel. As mudanças que você faz no painel chegam ao site em cerca de um minuto, sem novo deploy.

Se o seu app envia um cabeçalho Content-Security-Policy (por exemplo pelo middleware ou pelo next.config), libere a Nexoply em:

  • script-src https://nexoply.com: para carregar o widget.js.
  • connect-src https://nexoply.com: para as requisições do chat.
  • img-src https://nexoply.com: para imagens como o logo e o ícone do botão.

Solução de problemas e próximos passos

  • Sem botão, e data-chatbot vazio no código da página. A variável de ambiente não foi lida: confira o prefixo NEXT_PUBLIC_, reinicie o next dev e, na hospedagem, adicione a variável e faça um novo deploy.
  • O script está em uma página só, e não no layout. Coloque-o em app/layout.tsx ou pages/_app.tsx para carregar em todas as rotas.
  • A tag foi alterada. Ela precisa manter o atributo data-chatbot e um src que contenha widget.js.
  • Bloqueado pela CSP ou pelos sites permitidos. Procure erros no console do navegador e confira as duas seções acima.
  • Chatbot desligado. Verifique se a chave Chatbot ativado está ligada.
  • Bloqueadores de anúncios. Raramente, uma extensão bloqueia widgets de chat. Teste em uma janela anônima sem extensões.

Quando estiver funcionando, deixe-o com a cara do site em Chatbot → Personalizar: ícone, texto, cores e posição do botão, ou uma aba lateral na borda da tela (como "Ajuda"); um visual diferente no celular; e regras de página para páginas escolhidas (por exemplo, uma aba lateral só em /pricing). Veja os recursos e como funciona, compare os preços ou leia os guias de React e Vue.

Perguntas frequentes

Existe um pacote npm da Nexoply para Next.js?

Não, e você não precisa de um. O widget é sempre o script https://nexoply.com/widget.js com um atributo data-chatbot, adicionado com next/script. Todas as configurações ficam no seu painel da Nexoply.

Funciona na Vercel?

Sim. É só uma tag script carregada no navegador do visitante: nada roda no seu servidor, e não há rotas de API nem configurações de servidor para adicionar. Defina NEXT_PUBLIC_NEXOPLY_KEY nas variáveis de ambiente do seu projeto na Vercel e faça um novo deploy.

Afeta as Core Web Vitals ou o desempenho?

Ele foi feito para não afetar. O script carrega de forma assíncrona depois da hidratação (afterInteractive) ou quando o navegador fica ocioso (lazyOnload), então nunca bloqueia a renderização, e é montado fora do layout da sua página.

App Router ou Pages Router: qual devo usar?

O que o seu projeto já usa; o widget funciona igual nos dois. App Router: app/layout.tsx. Pages Router: pages/_app.tsx.

Posso carregá-lo só depois do consentimento de cookies?

Sim. Renderize o <Script> só depois que o visitante aceitar, por exemplo em um componente de cliente que verifique o seu estado de consentimento. O widget em si não usa cookies.

Deixe o seu site responder às perguntas por você

Adicione as informações do seu negócio, teste o seu assistente e coloque-o no seu site - tudo no plano Grátis.