Nexoply

Handleidingen

Next.js-chatbot: voeg een AI-chatbot toe met next/script (App Router en Pages Router)

Voeg een AI-chatbot toe aan een Next.js-app: een <Chatbot />-component met next/script in app/layout.tsx of pages/_app.tsx. Geen npm-pakket, SSR-veilig.

Bijgewerkt op 6 oktober 2026 7 min lezen

In het kort

Maak een gratis Nexoply-account aan en kopieer je chatbotsleutel van de pagina Chatbot in je dashboard. Voeg in de App Router <Script src="https://nexoply.com/widget.js" data-chatbot={key} strategy="afterInteractive" /> uit next/script toe binnen <body> in app/layout.tsx; in de Pages Router zet je dezelfde <Script> in pages/_app.tsx. Er is geen npm-pakket om te installeren: de widget draait alleen in de browser, houdt het gesprek vast bij client-side navigatie en raakt je markup niet aan, dus er zijn geen hydratieproblemen.

  • Geen npm-pakket: één next/script-tag, of een kleine <Chatbot />-wrapper eromheen, in je root-layout (App Router) of _app (Pages Router).
  • Bewaar de sleutel in NEXT_PUBLIC_NEXOPLY_KEY; hij is openbaar, geen geheim, en geeft geen toegang tot je account.
  • Gebruik strategy="afterInteractive" (de standaardkeuze) of "lazyOnload" om hem na al het andere te laden.
  • SSR-veilig: hij draait alleen in de browser, wordt in een Shadow DOM aan document.body gekoppeld en overleeft routewijzigingen.
  • Open de chat vanuit je eigen knop met window.dispatchEvent(new Event("nexoply:open-chat")).

Voordat je begint

  • Een Nexoply-account. Meld je gratis aan: het Gratis-abonnement bevat 50 gesprekken per maand, zonder creditcard.
  • De bedrijfsinformatie in Nexoply: diensten en prijzen, veelgestelde vragen, voorwaarden, openingstijden en werkgebieden. Het snelst gaat het als je het adres van de website invult en Nexoply de openbare pagina's laat importeren (ook pagina's die met JavaScript worden gerenderd); jij controleert de voorstellen en er wordt niets toegevoegd zonder jouw akkoord.
  • Je chatbotsleutel. Open in het dashboard Chatbot (klik op Chatbot maken als je dat nog niet hebt gedaan). De installatiecode daar bevat de sleutel in het attribuut data-chatbot.

Bij een gewone HTML-site plak je de installatiecode simpelweg vóór </body>:

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

In Next.js bewerk je de HTML niet rechtstreeks, dus voeg je hetzelfde script toe met het ingebouwde next/script-component. De sleutel is openbaar: hij vertelt de widget alleen bij welk bedrijf hij hoort.

App Router: voeg het script toe aan app/layout.tsx

De root-layout omvat elke pagina, dus als je het script daar toevoegt, staat de chat op de hele site. Importeer Script uit next/script en plaats het binnen <body>, na {children}:

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

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        {/* Chatwidget van Nexoply: laadt in de browser na de hydratie */}
        <Script
          src="https://nexoply.com/widget.js"
          data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

Zet de sleutel daarna in een omgevingsvariabele. Door het voorvoegsel NEXT_PUBLIC_ neemt Next.js hem op in de browserbundel, en dat is hier geen probleem omdat de sleutel geen geheim is:

# .env.local (niet in git)
NEXT_PUBLIC_NEXOPLY_KEY=YOUR-KEY

Pages Router: voeg het script toe aan pages/_app.tsx

In de Pages Router omvat pages/_app.tsx elke pagina, dus daar komt dezelfde <Script>, naast <Component {...pageProps} />. Gebruik dezelfde variabele uit .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"
      />
    </>
  );
}

Gebruikt je project beide routers, voeg het script dan toe aan zowel app/layout.tsx als pages/_app.tsx. Twee keer laden kan geen kwaad: de widget wordt maar één keer per chatbotsleutel gekoppeld.

Optioneel: een herbruikbaar <Chatbot />-component

Heb je liever een <Chatbot />-component, zoals in de handleiding voor het React-chatbotcomponent? Zet de Script dan in een eigen bestand. next/script werkt in Server Components zolang je geen event handlers zoals onLoad meegeeft, dus dit bestand heeft geen "use client" nodig:

// components/Chatbot.tsx
import Script from "next/script";

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

Render <Chatbot /> daarna binnen <body> in app/layout.tsx, na {children}, of naast <Component {...pageProps} /> in pages/_app.tsx. Render het in de layout, niet in één losse pagina, zodat het op elke route laadt.

Een strategy kiezen, en hoe hij zich gedraagt

strategy="afterInteractive" laadt de widget direct nadat de pagina interactief is geworden, zodat de chatknop snel verschijnt. strategy="lazyOnload" wacht tot de browser niets te doen heeft en al het andere is geladen; kies die als je de eerste lading zo licht mogelijk wilt houden en het niet erg vindt dat de knop een moment later verschijnt. Bij beide blijft het script buiten het kritieke renderpad. Zie de documentatie van next/script voor details.

  • Client-side navigatie. De widget houdt het gesprek open terwijl bezoekers met <Link> of de router tussen pagina's wisselen, en controleert je paginaregels opnieuw als de URL verandert, zonder extra code.
  • Veilig met SSR en hydratie. Hij draait alleen in de browser en wordt aan document.body gekoppeld, buiten de markup die React hydrateert, dus hij veroorzaakt nooit hydration mismatches.
  • Shadow DOM. Je Tailwind- of globale CSS lekt niet in de chat, en zijn stijlen lekken niet in je app. Re-renders verwijderen hem nooit.
  • StrictMode en Fast Refresh. Effects die in development twee keer draaien of hot reloads kunnen geen tweede chat aanmaken: hij wordt één keer per sleutel gekoppeld.
  • Opslag. Hij plaatst geen cookies; hij gebruikt localStorage voor een anonieme bezoekers-id en sessionStorage voor het huidige gesprek.

Zelf een Next.js-chatbot bouwen of een gehoste gebruiken

Met Next.js is het goed te doen om je eigen chatbot te bouwen, en soms is dat de juiste keuze. De twee aanpakken passen bij verschillende taken:

  • Zelf bouwen met een chat-UI-bibliotheek of je eigen componenten, plus een route handler of API-route die een AI-model aanroept met je eigen API-sleutel. Je bent dan ook zelf verantwoordelijk voor de inhoud waarmee hij antwoordt, de opslag van gesprekken en bescherming tegen misbruik. Dat past als chat onderdeel is van je product, bijvoorbeeld een assistent die met de eigen gegevens van je gebruikers werkt.
  • Een gehoste AI-chatbot zoals Nexoply levert de interface, de AI en de backend samen. Hij beantwoordt vragen van bezoekers alleen met de bedrijfsinformatie die je toevoegt of importeert (diensten en prijzen, veelgestelde vragen, voorwaarden, openingstijden) en zegt het als hij iets niet weet. Er is geen AI-sleutel en er draait niets op je server; gesprekken, onbeantwoorde vragen en spambescherming regel je in het dashboard. Dat past bij een website voor klanten die vragen over het bedrijf moet beantwoorden.

Wil je volledige controle over de interface en het model, bouw hem dan zelf. Is het doel vragen van bezoekers beantwoorden zonder een backend te draaien, dan is de gehoste widget minder werk. Zie hoe Nexoply antwoordt met je bedrijfsinformatie.

Open de chat vanuit je eigen knop

Wil je een knop "Chat met ons" in je hero- of prijssectie? Verstuur het event nexoply:open-chat op window. Omdat de knop onClick gebruikt, moet het een client component zijn:

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

export function ChatButton() {
  return (
    <button
      type="button"
      // opent het chatvenster van Nexoply
      onClick={() => window.dispatchEvent(new Event("nexoply:open-chat"))}
    >
      Chat met ons
    </button>
  );
}

Gebruik <ChatButton /> in elke pagina of server component. Er is geen API om de widget na het laden te verwijderen: om de berichtknop op sommige pagina's te verbergen (bijvoorbeeld /checkout), voeg je een paginaregel met "Geen knop" toe onder Chatbot → Aanpassen → Berichtknop → Anders op sommige pagina’s.

Lokaal testen, toegestane websites en CSP

Start next dev, open http://localhost:3000 en er verschijnt een chatknop in de hoek. Stel een echte vraag, zoals "Werken jullie ook in het weekend?"; binnen een paar seconden staat het gesprek onder Gesprekken in je dashboard. Wijzigingen die je in het dashboard maakt, staan binnen ongeveer een minuut op de site, zonder opnieuw te deployen.

Stuurt je app een Content-Security-Policy-header mee (bijvoorbeeld vanuit middleware of next.config), sta Nexoply dan toe in:

  • script-src https://nexoply.com: om widget.js te laden.
  • connect-src https://nexoply.com: voor de verzoeken van de chat.
  • img-src https://nexoply.com: voor afbeeldingen zoals het logo en het knopicoon.

Problemen oplossen en volgende stappen

  • Geen knop, en data-chatbot is leeg in de paginabron. De omgevingsvariabele is niet gelezen: controleer het voorvoegsel NEXT_PUBLIC_, start next dev opnieuw en voeg bij je host de variabele toe en deploy opnieuw.
  • Het script staat in één pagina in plaats van in de layout. Zet het in app/layout.tsx of pages/_app.tsx, zodat het op elke route laadt.
  • De tag is aangepast. Hij moet het attribuut data-chatbot houden en een src die widget.js bevat.
  • Geblokkeerd door CSP of toegestane websites. Zoek naar fouten in de browserconsole en controleer de twee secties hierboven.
  • Chatbot uitgeschakeld. Controleer of de schakelaar Chatbot ingeschakeld aan staat.
  • Adblockers. Heel soms blokkeert een extensie chatwidgets. Probeer een privévenster zonder extensies.

Werkt alles, laat hem dan bij de site passen onder Chatbot → Aanpassen: knopicoon, label, kleuren en positie, of een zijtab aan de rand van het scherm (zoals "Hulp"); een andere look op telefoons; en paginaregels voor bepaalde pagina's (bijvoorbeeld een zijtab alleen op /pricing). Bekijk alle aanpassingsopties en hoe de assistent je bedrijf leert kennen, vergelijk de abonnementen en gesprekslimieten, of lees de handleiding voor het React-chatbotcomponent en de chatbothandleiding voor Vue en Nuxt.

Veelgestelde vragen

Is er een kant-en-klaar React-chatbotcomponent voor Next.js?

Er is geen officieel npm-pakket of componentenbibliotheek, en die heb je ook niet nodig. Het <Chatbot />-component in deze handleiding is een paar regels rond next/script die je naar je project kopieert. De widget is altijd het script https://nexoply.com/widget.js met een data-chatbot-attribuut, en alle instellingen staan in je Nexoply-dashboard.

Blijft de chat bestaan bij client-side navigatie?

Ja. Bezoekers houden hun gesprek terwijl ze met <Link> of de router tussen pagina's wisselen, en paginaregels worden opnieuw gecontroleerd als de URL verandert, zonder extra code. De widget staat op document.body, buiten je layouts, dus routewijzigingen verwijderen hem nooit.

Werkt het op Vercel?

Ja. Het is gewoon een scripttag die in de browser van de bezoeker laadt: er draait niets op je server, en er zijn geen API-routes of serverinstellingen om toe te voegen. Stel NEXT_PUBLIC_NEXOPLY_KEY in bij de omgevingsvariabelen van je Vercel-project en deploy opnieuw.

Heeft het invloed op Core Web Vitals of prestaties?

Het is ontworpen om dat niet te doen. Het script laadt asynchroon na de hydratie (afterInteractive) of als de browser niets te doen heeft (lazyOnload), dus het blokkeert het renderen nooit, en het wordt buiten de layout van je pagina gekoppeld.

App Router of Pages Router: welke moet ik gebruiken?

De router die je project al gebruikt; de widget werkt met beide hetzelfde. App Router: app/layout.tsx. Pages Router: pages/_app.tsx.

Kan ik hem pas laden na toestemming voor cookies?

Ja. Render de <Script> pas als de bezoeker akkoord heeft gegeven, bijvoorbeeld in een client component dat je toestemmingsstatus controleert. De widget zelf plaatst geen cookies.

Laat je website de vragen voor je beantwoorden

Voeg je bedrijfsinfo toe, test je assistent en zet hem op je website – allemaal met het gratis abonnement.