Feedback de usuarios
Recoge feedback de tema, valoración y comentario con el widget listo para usar o con hooks que no exigen proveedor.
Las opiniones de los usuarios valen más cuando no son anónimas.
El feedback de Fluxo puede usar el mismo contexto de visitante que
SupportProvider. Cuando alguien deja una valoración, un tema o un comentario,
el envío se puede asociar al visitante y, si está identificado, al contacto. Eso
permite a tu equipo entender a quién se le atascó algo, ver el contexto del
feedback y hacer seguimiento en una conversación, en lugar de leer la respuesta
suelta de una encuesta.
Avisa a tus usuarios cuando una opinión quede asociada a su cuenta o a su historial de soporte. Recoge solo los metadatos que tu equipo necesite y aplica tus propios requisitos de consentimiento, retención y borrado.
Usa el widget <Feedback /> por defecto cuando quieras el camino más rápido.
Usa useFeedbackForm cuando quieras el mismo motor de feedback dentro de tu
propia interfaz con shadcn. Para pantallas de feedback totalmente propias, pasa
un client, un visitorId y, opcionalmente, un contactId explícitos en lugar
de envolver ese subárbol en SupportProvider.
Antes de empezar
Para el widget <Feedback /> listo para usar, completa primero el
inicio rápido de React. Tu aplicación
ya debería tener:
@fluxolat/reactinstaladoSupportProviderconfigurado con tu clave pública- un punto de entrada CSS de Fluxo importado en la raíz de tu aplicación
import { SupportProvider } from "@fluxolat/react";
import type { ReactNode } from "react";
import "@fluxolat/react/styles.css";
export function AppRoot({ children }: { children: ReactNode }) {
return <SupportProvider publicKey="pk_test_xxxx">{children}</SupportProvider>;
}SupportProvider le da al widget por defecto su contexto de cliente, sitio web,
visitante y contacto. Los hooks de feedback también pueden leer ese contexto,
pero es un recurso de reserva: si pasas un client explícito, puedes usarlos
fuera de
SupportProvider.
El camino más rápido
Renderiza el widget por defecto cuando quieras un panel de feedback completo sin encargarte de la interfaz.
import { Feedback } from "@fluxolat/react";
export function App() {
return (
<Feedback
topics={["Bug", "Feature request", "UX", "Other"]}
trigger="product_feedback"
/>
);
}El valor de trigger es tu etiqueta para explicar por qué se recogió este
feedback. Usa nombres como product_feedback, churn, nps_survey o
conversation_resolved.
Instala los ejemplos de shadcn
Los ejemplos de abajo usan Fluxo para el estado del feedback y componentes de shadcn para la interfaz.
Si todavía no tienes Fluxo instalado:
pnpm add @fluxolat/react
Los ejemplos sin proveedor que crean el cliente directamente también necesitan el paquete core:
pnpm add @fluxolat/core
Instala los componentes de shadcn que usan los ejemplos:
pnpm dlx shadcn@latest add button popover select textarea toggle-group
Después abre la pestaña Code en cualquiera de las vistas previas y copia el
componente a tu aplicación. Los dos ejemplos importan useFeedbackForm desde
@fluxolat/react/feedback, así que pueden enviar con el mismo contexto de
visitante y de contacto que tu widget de soporte.
Feedback con emojis
Empieza con un popover compacto: tema, comentario, valoración y un botón pequeño de envío.
Feedback con estrellas
El mismo hook puede alimentar una interfaz de valoración de cinco estrellas.
Construye la tuya
Usa useFeedbackForm cuando quieras el control total de la interfaz pero no
quieras rehacer el estado del formulario, la validación ni la fontanería del
envío. Omite client para usar el SupportProvider más cercano, o pasa
client, visitorId y, opcionalmente, contactId para un uso sin proveedor.
"use client";
import { useFeedbackForm } from "@fluxolat/react/hooks/use-feedback-form";
export function ProductFeedback() {
const feedback = useFeedbackForm({
topics: ["Bug", "Feature request", "UX", "Other"],
trigger: "product_feedback",
commentRequired: true,
});
return (
<form aria-describedby="feedback-status" onSubmit={feedback.handleSubmit}>
<label htmlFor="feedback-topic">Topic</label>
<select
aria-describedby={
feedback.fields.topic.isMissing ? "feedback-topic-error" : undefined
}
aria-invalid={feedback.fields.topic.isMissing}
id="feedback-topic"
onBlur={feedback.fields.topic.handleBlur}
onChange={(event) => feedback.handleTopicChange(event.target.value)}
value={feedback.topic}
>
<option value="">Select topic</option>
{feedback.availableTopics.map((topic) => (
<option key={topic} value={topic}>
{topic}
</option>
))}
</select>
{feedback.fields.topic.isMissing ? (
<p id="feedback-topic-error" role="alert">
Choose a topic.
</p>
) : null}
<label htmlFor="feedback-comment">Comment</label>
<textarea
aria-describedby={
feedback.fields.comment.isMissing
? "feedback-comment-error"
: undefined
}
aria-invalid={feedback.fields.comment.isMissing}
id="feedback-comment"
onBlur={feedback.fields.comment.handleBlur}
onChange={(event) => feedback.handleCommentChange(event.target.value)}
value={feedback.comment}
/>
{feedback.fields.comment.isMissing ? (
<p id="feedback-comment-error" role="alert">
Add a comment.
</p>
) : null}
<fieldset>
<legend>Rating</legend>
{[1, 2, 3, 4, 5].map((rating) => (
<button
aria-pressed={feedback.rating === rating}
key={rating}
onClick={() => feedback.handleRatingSelect(rating)}
type="button"
>
{rating}
</button>
))}
</fieldset>
<button disabled={feedback.submit.disabled} type="submit">
{feedback.submit.label}
</button>
<p aria-live="polite" id="feedback-status">
{feedback.submitted
? "Feedback sent."
: feedback.error?.message ?? ""}
</p>
</form>
);
}useFeedbackForm gestiona las piezas móviles que necesita cualquier interfaz de
feedback:
- el estado de apertura con
open,setOpenyhandleOpenChange - el estado de la valoración con
rating,hoveredRating,handleRatingSelectyhandleRatingHoverChange - el estado del tema y del comentario con valores normalizados
- el estado de validación de la valoración, los temas y los comentarios obligatorios
- los estados pendiente, de error y enviado
- las acciones de éxito con
sendAnotherydone
Las opciones más habituales son:
client: unFluxoClientexplícito para feedback sin proveedortopics: las categorías de feedback que se pueden elegirdefaultTopic: un tema preseleccionado detopicstrigger: el motivo por el que apareció este formulario de feedbacksource: de dónde vino este feedback; por defecto,widgetconversationId: asocia el feedback a una conversación de soporte concretavisitorId: obligatorio cuando ningún contexto de proveedor aporta un visitantecontactId: asocia el feedback a un contacto identificadocommentRequired: exige un comentario escrito antes de enviardefaultOpen: abre el popover o el diálogo desde el principioonSuccess: ejecuta código después de que Fluxo guarde el feedbackonError: gestiona un envío fallido
Formulario de feedback sin proveedor
"use client";
import { FluxoClient } from "@fluxolat/core";
import { useFeedbackForm } from "@fluxolat/react/hooks/use-feedback-form";
const client = new FluxoClient({ publicKey: "pk_test_xxxx" });
export function ProviderFreeFeedback({ visitorId }: { visitorId: string }) {
const feedback = useFeedbackForm({
client,
visitorId,
source: "headless",
topics: ["Bug", "Feature request", "UX", "Other"],
});
return (
<form onSubmit={feedback.handleSubmit}>
<button onClick={() => feedback.handleRatingSelect(5)} type="button">
Great
</button>
<button disabled={feedback.submit.disabled} type="submit">
{feedback.submit.label}
</button>
</form>
);
}API de envío de más bajo nivel
Usa useSubmitFeedback cuando ya controlas todo el formulario y solo necesitas
la escritura. Sigue la misma regla de proveedor opcional: omite client para
usar SupportProvider, o pasa entradas explícitas de runtime para un formulario
headless.
"use client";
import { useSubmitFeedback } from "@fluxolat/react/hooks/use-submit-feedback";
export function CustomFeedbackSubmit() {
const feedback = useSubmitFeedback({});
async function submit() {
await feedback.mutateAsync({
rating: 5,
topic: "UX",
comment: "The new onboarding screen is much clearer.",
trigger: "onboarding_feedback",
});
}
return (
<button disabled={feedback.isPending} onClick={submit} type="button">
Send feedback
</button>
);
}Si omites client, useSubmitFeedback lee el cliente de Fluxo y el contexto de
visitante, sitio web y contacto desde SupportProvider. En la mayoría de
aplicaciones con widget, pasa rating, topic, comment, trigger y,
opcionalmente, conversationId. El hook rellena visitorId y contactId a
partir del contexto.
Para formularios sin proveedor, pasa el cliente y el visitante explícitamente:
"use client";
import { FluxoClient } from "@fluxolat/core";
import { useSubmitFeedback } from "@fluxolat/react/hooks/use-submit-feedback";
const client = new FluxoClient({ publicKey: "pk_test_xxxx" });
export function HeadlessFeedbackSubmit({ visitorId }: { visitorId: string }) {
const feedback = useSubmitFeedback({ client });
return (
<button
disabled={feedback.isPending}
onClick={() =>
feedback.mutate({
rating: 5,
source: "headless",
visitorId,
})
}
type="button"
>
Send feedback
</button>
);
}Pasa visitorId o contactId a mano solo si estás construyendo una integración
de más bajo nivel y sabes que necesitas sobrescribir el contexto.
Datos del feedback
Cada envío guarda:
rating: obligatorio, del 1 al 5topic: categoría estructurada opcionalcomment: comentario escrito opcionaltrigger: etiqueta opcional de lo que provocó el formulariosource: por defecto,widgetconversationId: enlace opcional a una conversaciónvisitorId: el visitante que dejó el feedbackcontactId: el contacto identificado, cuando el visitante tiene uno
Esa asociación es lo importante. Una valoración baja de un cliente con sesión iniciada puede convertirse en un seguimiento de soporte real, no solo en un número en un panel.
Comprobar y resolver problemas
Después de enviar, espera al estado de envío del formulario y confirma que el
feedback aparece en el panel con el contexto de visitante y contacto esperado.
Un 401 suele significar que falta la clave pública o que no es válida. Un
403 suele significar que el nombre de host actual no está permitido. Si un
formulario sin proveedor no tiene visitante, pasa un visitorId válido; si no,
deja el formulario dentro de SupportProvider.
Exportaciones de los hooks
useFeedbackForm y useSubmitFeedback se exportan desde
@fluxolat/react/hooks, @fluxolat/react/feedback e importaciones profundas
explícitas como @fluxolat/react/hooks/use-feedback-form. Las aplicaciones de
Next.js pueden usar las exportaciones equivalentes de @fluxolat/next/hooks y
@fluxolat/next/feedback.
Los hooks de proveedor opcional tratan client con cuidado: omitirlo significa
«lee el contexto del proveedor», mientras que pasar client: null desactiva a
propósito el recurso al proveedor.
Referencia de tipos
Props de Feedback
Prop
Tipo
Opciones de useFeedbackForm
Prop
Tipo
Resultado de useFeedbackForm
Nombre
Tipo
Variables de envío de feedback
Parámetro
Tipo
¿Te resultó útil esta página?
Abre una incidencia de documentación ya rellenada para que el equipo pueda actuar.
En esta página
Antes de empezarEl camino más rápidoInstala los ejemplos de shadcnFeedback con emojisFeedback con estrellasConstruye la tuyaFormulario de feedback sin proveedorAPI de envío de más bajo nivelDatos del feedbackComprobar y resolver problemasExportaciones de los hooksReferencia de tiposProps de FeedbackOpciones de useFeedbackFormResultado de useFeedbackFormVariables de envío de feedback
