ENPL Zaloguj Zacznij za darmo
// Integracje / Next.js

Visitant w Next.js

Jeden <Script> w głównym layoucie liczy odwiedzających razem ze zmianami tras po stronie klienta. Jedno małe middleware liczy boty AI, które nigdy nie uruchamiają JavaScriptu. Oba to kopiuj-wklej; bez SDK, bez paczki npm.

Czas: 10 minKod: 1 komponentCookies: 0

Czego potrzebujesz

  • Projekt Next.js (App Router albo Pages Router), który możesz wdrożyć. Przykłady są w TypeScripcie; wersja JavaScript jest taka sama bez typów.
  • Darmowe konto Visitant z dodaną domeną, np. twojastrona.pl.
  • Do części o botach AI: Klucz serwera strony z zakładki Ustawienia strony - Śledzenie botów AI (serwer) w panelu oraz hosting, który uruchamia middleware (serwer Node.js, Docker, Vercel albo inny adapter - nie statyczny build output: 'export').

Instalacja w 5 krokach

  1. 01 Dodaj Script do głównego layoutu

    Otwórz app/layout.tsx, zaimportuj Script z next/script i wyrenderuj go w <body> głównego layoutu, żeby był na każdej podstronie. Zamień twojastrona.pl na swoją domenę. strategy="afterInteractive" to wartość domyślna: skrypt ładuje się wcześnie, po starcie hydratacji - dokładnie to dokumentacja Next.js zaleca dla analityki.

    // app/layout.tsx
    import Script from 'next/script'
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="pl">
          <body>
            {children}
            <Script src="https://annuora.com/v.js" data-domain="twojastrona.pl" strategy="afterInteractive" />
          </body>
        </html>
      )
    }

    Pages Router? Wstaw ten sam <Script> w pages/_app.tsx obok <Component {...pageProps} />. Next.js ładuje go raz dla każdej trasy. Dodatkowe atrybuty, takie jak data-domain, trafiają do końcowego elementu <script>.

  2. 02 Zmiany tras liczą się same

    Tu nic nie dodajesz, ale warto wiedzieć, co się dzieje. Next.js nawiguje przez history.pushState. Tracker Visitant przy załadowaniu raz opakowuje pushState i nasłuchuje popstate (Wstecz i Dalej). Po każdej nawigacji porównuje nowy adres z ostatnim wysłanym i jeśli się różni, zapisuje odsłonę, a poprzednią zamyka z czasem aktywności i głębokością przewinięcia. Liczą się więc router.push, <Link> i przycisk Wstecz, a ponowne renderowanie z tym samym adresem nie liczy się podwójnie.

    Zmiany samego hasha (#sekcja) są pomijane, chyba że dodasz do Scriptu data-hash. Nie wywołuj sam visitant("pageview") w useEffect - to podwoiłoby liczby.

  3. 03 Wdróż i otwórz stronę

    Wdróż aplikację, otwórz produkcyjną domenę i przejdź przez kilka podstron. Tracker celowo ignoruje localhost, więc npm run dev nic nie pokaże w panelu; jeśli chcesz testować lokalnie, dodaj do Scriptu data-local.

  4. 04 Policz boty AI przez middleware

    Boty takie jak GPTBot czy ClaudeBot nigdy nie wykonują Scriptu, więc strona klienta ich nie widzi. Utwórz middleware.ts w katalogu głównym projektu (obok app albo w src) z poniższym kodem i zamień TWÓJ-KLUCZ na swój Klucz serwera. Kod sprawdza user agent z listą botów i tylko przy trafieniu wysyła jedno małe żądanie przez event.waitUntil, więc żądania ludzi nic nie kosztują. To ten sam fragment, który panel pokazuje z wpisanym Twoim kluczem.

    import { NextResponse } from 'next/server';
    const AI_UA = /bot|crawl|spider|GPTBot|ChatGPT-User|OAI-SearchBot|Claude|anthropic|Perplexity|Google-|GoogleOther|Applebot|meta-external|Meta-WebIndexer|Amazonbot|Amzn-|Bytespider|CCBot|MistralAI|DuckAssist|YouBot|xAI|Grok|cohere|Diffbot|Kimi|Qwen|Manus|Firecrawl/i;
    export function middleware(req, ev) {
      const ua = req.headers.get('user-agent') || '';
      if (AI_UA.test(ua)) ev.waitUntil(fetch('https://annuora.com/api/bot', {
        method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Visitant-Key': 'TWÓJ-KLUCZ' },
        body: JSON.stringify({ ua, path: req.nextUrl.pathname, ip: req.headers.get('x-forwarded-for') || '' })
      }).catch(() => {}));
      return NextResponse.next();
    }

    Next.js 16 lub nowszy: konwencja pliku zmieniła nazwę - nazwij plik proxy.ts, a eksportowaną funkcję proxy (ta sama treść, to samo event.waitUntil). middleware.ts nadal działa, ale jest oznaczony jako przestarzały; npx @next/codemod@canary middleware-to-proxy . zmieni nazwę za Ciebie. Jeśli wolisz, żeby middleware nie dotykało żądań o zasoby, dodaj matcher wykluczający _next/static i _next/image.

  5. 05 Potwierdź kanał botów

    Wdróż ponownie. W panelu otwórz Ustawienia strony - Śledzenie botów AI (serwer): ramka mówi Czekamy na pierwsze wejście bota, dopóki żaden nie zajrzy, a potem Działa: N wizyt botów zapisanych. Żeby sprawdzić od razu, poproś o dowolną stronę z user agentem bota: curl -A "GPTBot/1.4" https://twojastrona.pl/. Wejścia botów nigdy nie wliczają się do limitu zdarzeń w planie.

    Statyczny eksport (output: 'export') nie ma middleware, więc ten krok jest tam niemożliwy. Na Vercelu lub Netlify bez middleware albo za CDN-em, który serwuje strony z cache, użyj zamiast tego fragmentu dla Cloudflare Workers z panelu - on widzi każde żądanie, z cache czy bez.

Czy działa? Sprawdź w 60 sekund

Zrób to na wdrożonej stronie, z panelem Visitant otwartym w drugiej karcie.

  • Licznik osób teraz na górze panelu pokazuje 1, gdy Twoja produkcyjna strona jest otwarta.
  • Kliknij dwa wewnętrzne <Link> bez przeładowania: obie ścieżki pojawiają się w tabeli Strony, po jednej odsłonie. Naciśnij Wstecz: pierwsza ścieżka dostaje drugą odsłonę.
  • W narzędziach deweloperskich, zakładka Sieć, filtr api/e: jedno żądanie ze statusem 202 na każdą nawigację, żadnego przy ponownym renderowaniu z tym samym adresem.
  • Wykonaj curl -A "GPTBot/1.4" https://twojastrona.pl/; w ciągu minuty sekcja Boty AI czytające Twoją stronę w panelu pokaże GPTBot z 1 wejściem.
  • Wejdź na stronę z linku w odpowiedzi ChatGPT (albo dodaj ?utm_source=chatgpt.com do adresu): tabela Źródła pokaże ChatGPT w kanale AI.

Częste problemy

Lokalnie nic się nie pojawiaTak ma być: tracker nie działa na localhost, 127.0.0.1 ani na stronach file:. Dodaj do Scriptu data-local, żeby testować w trakcie pracy, i usuń go przed wdrożeniem, jeśli nie chcesz liczyć wizyt deweloperskich.
Każda zmiana trasy liczy się podwójnieCoś jeszcze zgłasza odsłony - ręczne visitant("pageview") w useEffect albo Script wyrenderowany dwa razy (główny i zagnieżdżony layout, albo _app i _document naraz). Zostaw dokładnie jeden.
Script działa, ale wejścia botów stoją na zerzeSprawdź Klucz serwera w middleware, upewnij się, że plik middleware leży w katalogu głównym projektu (albo w src) na tym samym poziomie co app, i sprawdź, czy build nie jest statycznym eksportem. Sprawdź też, czy matcher nie wyklucza Twoich stron.
TypeScript narzeka na sygnaturę middlewareZaimportuj typy: import type { NextRequest, NextFetchEvent } from 'next/server' i opisz parametry (req: NextRequest, ev: NextFetchEvent). Fragment to zwykły JavaScript, więc działa zarówno w plikach .js, jak i .ts.

Pytania

Czy nie lepiej użyć beforeInteractive?

Nie. beforeInteractive jest dla skryptów, bez których strona nie działa, i musi siedzieć w głównym layoucie. Analityka to dokładnie to, co dokumentacja Next.js wymienia przy afterInteractive; tracker i tak wysyła odsłonę, gdy tylko się uruchomi.

Czy Visitant działa z React Server Components i streamingiem?

Tak. Script renderuje główny layout, który jest komponentem serwerowym, a next/script zajmuje się stroną klienta. 'use client' nie jest potrzebne, bo nie używamy handlera onLoad.

Czy potrzebuję banera cookies?

Nie z powodu Visitant. Bez cookies, bez identyfikatorów w local storage, bez zapisywania adresów IP, hosting w UE. Jeśli masz już baner dla innych narzędzi, nie uzależniaj od niego Scriptu.

Jakie są limity planu Free?

5000 zdarzeń miesięcznie i 2 strony. Liczą się odsłony i własne zdarzenia; wejścia botów AI z middleware nigdy się nie liczą. 14-dniowy okres próbny planu Business nie wymaga karty.

Załóż darmowe konto - instrukcje w panelu pokażą się już z Twoją domeną i kluczem.

Zacznij za darmo →