Zum Inhalt springen
duxt

Analytik-Ereignisse senden

Ein Callback, fünf Ereignisse, kein Anbieter — verdrahte duxts Leserinteraktionen mit der Analytik, die du ohnehin betreibst.

duxt meldet, was Leser mit einer Dokumentationsseite tun — suchen, einen Befehl kopieren, einen Endpoint ausprobieren, „War diese Seite hilfreich?“ beantworten — an eine einzige Funktion, die du schreibst. Sie liefert keinen Anbieter, kein SDK und kein Skript aus, und eine Seite, die diese Funktion nicht geschrieben hat, meldet nichts und lädt nichts zusätzlich herunter.

Schritte

  1. Schreibe die Callback-Funktion. Sie lebt in app.config.ts, neben dem Rest deiner duxt-Konfiguration, und bekommt ein Ereignis pro Interaktion übergeben:
    export default defineAppConfig({
      duxt: {
        analytics: {
          track(event) {
            // `event.name` ist der Diskriminator; `event.context` sagt, auf
            // welcher Seite, in welcher Locale, aus welcher Quelle und in
            // welcher Version es passiert ist.
            console.log(event.name, event.context.path);
          }
        }
      }
    });
    

    Die Callback-Funktion läuft nur im Browser. Ein Build und ein Vorab-Rendering rufen sie nie auf, ein statisches Rendering füllt deine Analytik also nicht mit Seiten, die ein Crawler geöffnet hat.
  2. Sende es dorthin, wo deine Analytik ohnehin liegt. Was auch immer dein Anbieter anbietet — ein SDK, das ohnehin auf der Seite liegt, oder eine eigene Route, damit der Browser des Lesers nie mit einem Dritten spricht, den du nicht gewählt hast:
    export default defineAppConfig({
      duxt: {
        analytics: {
          track(event) {
            const { name, context, ...properties } = event;
    
            // Dein Anbieter, deine Eigenschaftsnamen, deine
            // Einwilligungsschranke.
            window.plausible?.(name, { props: { ...context, ...properties } });
          }
        }
      }
    });
    
  1. Wähle die Ereignisse, die du willst, und lass den Rest fallen. Die Union ist geschlossen, ein switch deckt sie also erschöpfend ab, und was du nicht nennst, wird schlicht nicht gesendet:
track(event) {
  if (event.name === 'search' && event.results === 0) {
    // Der eine Bericht, den eine Dokumentationsseite fast immer will: ein
    // Begriff, nach dem jemand gesucht hat und den die Seite nicht
    // beantworten konnte.
    report('docs-search-miss', { query: event.query, ...event.context });
  }
}
  1. Prüfe, dass ein Ereignis ankommt, mit dem Kontext, den du erwartet hast — unter einem Versions- und Locale-Präfix, nicht nur an der nackten URL.

Die Ereignisse

Jedes Ereignis hat einen name, eigene Felder und einen context.

nameWird gesendet, wennTrägt
searchEine entprellte, nicht leere Suchanfrage zur Ruhe kommt — auch eine, die nichts gefunden hatquery, results, approximate
search-resultEin Leser einen Treffer öffnetquery, rank, to, collection
copyEin Codebeispiel der Ebene kopiert wirdkind, language, manager, sample
api-requestEine Try-it-Anfrage zur Ruhe kommtoperation, method, path, outcome, statusClass, duration
feedbackEin Leser „War diese Seite hilfreich?“ beantwortethelpful

search feuert einmal pro abgeschlossener Suchanfrage, nicht pro Tastenanschlag: Die Entprellung verwirft, was niemand zu Ende getippt hat, und ein Ergebnis, das ein neueres ablöst, wird nie gemeldet, weil der Leser es nie gesehen hat.

copy deckt die eigenen Codebeispiele der Ebene ab — einen Codeblock, einen ::code-group-Block, einen ::package-managers-Block, ein Request-Sample im Try-it-Client — und kind sagt, welches davon. „Seite als Markdown kopieren“ gehört nicht zu dieser Familie und sendet nichts: Es ist die Seite, kein Beispiel darin.

api-request beschreibt die Operation so, wie das OpenAPI-Dokument sie deklariert. path ist die Vorlage (/pets/{id}), nie die URL, die aufgerufen wurde.

Der Kontext

FeldHinweise
pathDer Dokumentationspfad, ohne Locale-Präfix, Query-String oder Fragment
localeDie Locale, in der die Seite gelesen wurde
sourceAus welcher Quelle die Seite stammt — fehlt auf einer Seite mit nur einer Quelle
versionWelche Version — fehlt, wo die Quelle nur eine hat

Was nie gesendet wird

Diese Liste ist der Sinn der Funktion, deshalb lohnt es sich, sie deutlich auszusprechen. Kein Ereignis trägt:

  • ein API-Credential, einen Header oder ein Token;
  • einen Request- oder Response-Body oder eine konkrete Request-URL;
  • den Text, der kopiert wurde;
  • den gerenderten Inhalt eines Suchtreffers;
  • irgendeine Browser-, Sitzungs- oder Leserkennung;
  • den Query-String oder das Fragment aus dem Pfad der Seite selbst.

duxt überträgt, puffert und speichert auch selbst nie etwas. Es gibt in der Ebene keine Warteschlange, keinen Wiederholungsversuch, keinen Speicher und keinen Netzwerkaufruf: Deine Funktion ist das Einzige, was die Seite je verlässt.

Deine Callback-Funktion wird nie abgewartet, und was sie wirft oder womit sie ablehnt, wird verschluckt — ein Anbieter, der ausfällt, darf nicht die Suche, das Kopieren, das Feedback oder die Anfrage mit sich reißen.

Seiten-Feedback, so oder so

feedback ist dieselbe Antwort, die DuxtPageFeedback schon immer gesendet hat. Das @feedback-Ereignis der Komponente und ihr Standard-Slot sind unverändert, sie zu umhüllen funktioniert also weiterhin, und keiner der beiden Wege braucht den anderen — nimm das Analytik-Callback, wenn du ein Ziel für alles willst, und die Hülle, wenn das Feedback allein irgendwo eigenes landen soll.

Checkliste

  • duxt.analytics.track ist gesetzt, und mehr war nicht nötig, um es einzuschalten
  • Das Ziel gehört dir — ein Anbieter deiner Wahl oder eine eigene Route
  • Die Einwilligung wird in track geprüft, falls deine Richtlinie danach fragt
  • Ein Ereignis kam mit dem Pfad, der Locale, der Quelle und der Version an, die du erwartet hast
  • Nichts in dem, was du weiterleitest, identifiziert den Leser
War diese Seite hilfreich?