Recoger opiniones de página
Envuelve DuxtPageFeedback y guarda la respuesta donde ya vive tu analítica.
Cada página de documentación termina con «¿Te ha resultado útil esta página?», y la capa no hace nada con la respuesta: la mantiene en el estado del propio componente mientras dura la visita, emite un evento y no almacena nada. Envolver el componente es la forma de que la respuesta te llegue.
Pasos
- Envuelve el componente de la capa con su propio nombre. Nuxt resuelve tu
archivo primero, así que
app/components/DuxtPageFeedback.vueen tu proyecto reemplaza el de la capa — y el alias@duxtsigue alcanzando el original por ruta, de modo que la envoltura conserva el marcado, las traducciones y el reinicio al navegar de la capa:<script setup lang="ts"> import DuxtPageFeedbackBase from '@duxt/components/DuxtPageFeedback.vue'; const route = useRoute(); // El evento lleva la respuesta y nada más — la página a la que pertenece la // lees tú, y `fullPath` es la que conserva los prefijos de locale, // repositorio y versión bajo los que se dio realmente la respuesta. async function onFeedback(helpful: boolean) { await $fetch('/api/feedback', { method: 'POST', body: { path: route.fullPath, helpful } }); } </script> <template> <DuxtPageFeedbackBase @feedback="onFeedback" /> </template> - Dale a la respuesta un sitio donde aterrizar. Una ruta propia, para que
el navegador del lector nunca hable con un tercero que no elegiste:
export default defineEventHandler(async (event) => { const { path, helpful } = await readBody(event); // Tu almacenamiento, tu analítica, tu cola. await recordFeedback({ path, helpful }); return { ok: true }; });
Una llamada de analítica en el cliente funciona igual — sustituye el$fetchde la envoltura por lo que exponga el SDK de tu proveedor. - Recompila y responde la pregunta una vez, luego comprueba que la respuesta llegó con la ruta que esperabas — bajo un prefijo de versión, no solo en la URL desnuda.
Representar tu propio control
El evento conserva los botones de la capa. Para reemplazarlos, usa en su lugar el slot por defecto: expone el mismo estado desde el que se representa el componente, así que el reinicio al navegar y el estado de «gracias» siguen siendo tarea de la capa.
<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>
Cuéntanos qué falta
<textarea name="comment" />
</label>
<button type="submit">Enviar</button>
</form>
<p v-else>Gracias.</p>
</DuxtPageFeedbackBase>
</template>
answer(helpful) fija el estado y emite el evento, así que un slot y un
escuchador se combinan: cuelga tu formulario del slot y conserva el manejador
@feedback del paso 1 para entregar lo que haya recogido.
Nada en el componente identifica a un visitante, y así se queda a propósito. Si cuentas respuestas por página, cuéntalas como respuestas — un navegador que recarga y responde otra vez es una segunda respuesta, no un segundo lector, y convertir lo uno en lo otro es una cuestión de consentimiento que tu política de privacidad tiene que responder antes.
Por qué la capa no almacena nada
Un tema de documentación que llamara a casa por defecto tendría que elegir un destino para los lectores de otra persona, y no hay ninguno defendible: la capa no sabe ni dónde vive tu analítica ni qué promete tu política de privacidad. Entregar la pregunta con un evento y sin backend mantiene la decisión donde corresponde — la misma razón por la que la fila legal del pie y los enlaces al repositorio se entregan vacíos (ADR 0005).
Lista de comprobación
- La envoltura representa el componente de la capa en vez de reimplementarlo
- La respuesta se envía con la ruta en la que se dio, prefijos incluidos
- El destino es tuyo — una ruta, una cola o un SDK que elegiste
- Nada en la carga útil identifica al lector