Seiten-Feedback sammeln
DuxtPageFeedback umhüllen und die Antwort dort behalten, wo deine Analytik ohnehin liegt.
Jede Dokumentationsseite endet mit „War diese Seite hilfreich?“, und die Ebene tut nichts mit der Antwort: Sie hält sie für die Dauer des Besuchs im eigenen Zustand der Komponente, sendet ein Ereignis und speichert nichts. Die Komponente zu umhüllen ist der Weg, auf dem die Antwort bei dir ankommt.
Schritte
- Umhülle die Komponente der Ebene unter ihrem eigenen Namen. Nuxt löst
deine Datei zuerst auf —
app/components/DuxtPageFeedback.vuein deinem Projekt ersetzt also die der Ebene, und der@duxt-Alias erreicht das Original weiterhin über den Pfad, sodass die Hülle das Markup, die Übersetzungen und das Zurücksetzen bei Navigation der Ebene behält:<script setup lang="ts"> import DuxtPageFeedbackBase from '@duxt/components/DuxtPageFeedback.vue'; const route = useRoute(); // Das Ereignis trägt die Antwort und sonst nichts — die Seite, zu der sie // gehört, liest du selbst, und `fullPath` ist die, die die Locale-, // Repository- und Versionspräfixe behält, unter denen die Antwort tatsächlich // gegeben wurde. async function onFeedback(helpful: boolean) { await $fetch('/api/feedback', { method: 'POST', body: { path: route.fullPath, helpful } }); } </script> <template> <DuxtPageFeedbackBase @feedback="onFeedback" /> </template> - Gib der Antwort einen Ort zum Landen. Eine eigene Route, damit der
Browser des Lesers nie mit einem Dritten spricht, den du nicht gewählt hast:
export default defineEventHandler(async (event) => { const { path, helpful } = await readBody(event); // Dein Speicher, deine Analytik, deine Warteschlange. await recordFeedback({ path, helpful }); return { ok: true }; });
Ein clientseitiger Analytik-Aufruf funktioniert genauso — ersetze das$fetchin der Hülle durch das, was das SDK deines Anbieters anbietet. - Baue neu und beantworte die Frage einmal, dann prüfe, ob die Antwort mit dem erwarteten Pfad ankam — unter einem Versionspräfix, nicht nur an der nackten URL.
Ein eigenes Bedienelement rendern
Das Ereignis behält die Schaltflächen der Ebene. Um sie zu ersetzen, nimm stattdessen den Standard-Slot: Er legt denselben Zustand offen, aus dem die Komponente rendert, sodass das Zurücksetzen bei Navigation und der „Danke“-Zustand Sache der Ebene bleiben.
<script setup lang="ts">
import DuxtPageFeedbackBase from '@duxt/components/DuxtPageFeedback.vue';
</script>
<template>
<DuxtPageFeedbackBase v-slot="{ answered, answer }">
<form v-if="answered === undefined" @submit.prevent="answer(true)">
<label>
Sag uns, was fehlt
<textarea name="comment" />
</label>
<button type="submit">Senden</button>
</form>
<p v-else>Danke.</p>
</DuxtPageFeedbackBase>
</template>
answer(helpful) setzt den Zustand und sendet das Ereignis, Slot und Listener
lassen sich also kombinieren: Häng dein Formular an den Slot und behalte den
@feedback-Handler aus Schritt 1, um zu liefern, was es gesammelt hat.
Nichts in der Komponente identifiziert einen Besucher, und das bleibt bewusst so. Wenn du Antworten je Seite zählst, zähle sie als Antworten — ein Browser, der neu lädt und erneut antwortet, ist eine zweite Antwort und kein zweiter Leser, und das eine ins andere zu verwandeln ist eine Einwilligungsfrage, die zuerst deine Datenschutzerklärung beantworten muss.
Warum die Ebene nichts speichert
Ein Dokumentations-Theme, das standardmäßig nach Hause telefoniert, müsste ein Ziel für die Leser eines anderen aussuchen, und es gibt kein vertretbares: Die Ebene weiß weder, wo deine Analytik liegt, noch, was deine Datenschutzerklärung verspricht. Die Frage mit einem Ereignis und ohne Backend auszuliefern hält die Entscheidung dort, wo sie hingehört — aus demselben Grund werden die Rechtszeile im Fußbereich und die Repository-Links leer ausgeliefert (ADR 0005).
Checkliste
- Die Hülle rendert die Komponente der Ebene, statt sie nachzubauen
- Die Antwort wird mit dem Pfad gesendet, auf dem sie gegeben wurde, Präfixe eingeschlossen
- Das Ziel gehört dir — eine Route, eine Warteschlange oder ein SDK deiner Wahl
- Nichts in der Nutzlast identifiziert den Leser