Feedback de usuários
Colete feedback de tema, avaliação e comentário com o widget pronto para usar ou com hooks que não exigem provider.
O feedback dos usuários vale mais quando não é anônimo.
O feedback do Fluxo pode usar o mesmo contexto de visitante do
SupportProvider. Quando alguém deixa uma avaliação, um tema ou um comentário,
o envio pode ser associado ao visitante e, se ele estiver identificado, ao
contato. Isso permite que o seu time entenda quem ficou travado, veja o contexto
do feedback e faça o acompanhamento em uma conversa, em vez de ler a resposta
solta de uma pesquisa.
Avise os seus usuários quando um feedback ficar associado à conta ou ao histórico de suporte deles. Colete apenas os metadados de que o seu time precisa e aplique os seus próprios requisitos de consentimento, retenção e exclusão.
Use o widget <Feedback /> padrão quando quiser o caminho mais rápido. Use
useFeedbackForm quando quiser o mesmo motor de feedback dentro da sua própria
interface com shadcn. Para telas de feedback totalmente próprias, passe um
client, um visitorId e, opcionalmente, um contactId explícitos em vez de
envolver essa subárvore em SupportProvider.
Antes de começar
Para o widget <Feedback /> pronto para usar, conclua primeiro o
início rápido do React. O seu app
já deve ter:
@fluxolat/reactinstaladoSupportProviderconfigurado com a sua chave pública- um ponto de entrada CSS do Fluxo importado na raiz do seu app
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 dá ao widget padrão o seu contexto de cliente, site, visitante
e contato. Os hooks de feedback também conseguem ler esse contexto, mas ele é um
recurso de reserva: se você passar um client explícito, pode usá-los fora de
SupportProvider.
O caminho mais rápido
Renderize o widget padrão quando quiser um painel de feedback completo sem precisar cuidar da interface.
import { Feedback } from "@fluxolat/react";
export function App() {
return (
<Feedback
topics={["Bug", "Feature request", "UX", "Other"]}
trigger="product_feedback"
/>
);
}O valor de trigger é a sua etiqueta para explicar por que esse feedback foi
coletado. Use nomes como product_feedback, churn, nps_survey ou
conversation_resolved.
Instale os exemplos do shadcn
Os exemplos abaixo usam o Fluxo para o estado do feedback e componentes do shadcn para a interface.
Se você ainda não instalou o Fluxo:
pnpm add @fluxolat/react
Os exemplos sem provider que criam o cliente diretamente também precisam do pacote core:
pnpm add @fluxolat/core
Instale os componentes do shadcn usados pelos exemplos:
pnpm dlx shadcn@latest add button popover select textarea toggle-group
Depois abra a aba Code em qualquer uma das prévias e copie o componente para
o seu app. Os dois exemplos importam useFeedbackForm de
@fluxolat/react/feedback, então conseguem enviar com o mesmo contexto de
visitante e de contato do seu widget de suporte.
Feedback com emojis
Comece com um popover compacto: tema, comentário, avaliação e um botão pequeno de envio.
Feedback com estrelas
O mesmo hook pode alimentar uma interface de avaliação de cinco estrelas.
Construa a sua
Use useFeedbackForm quando quiser controle total da interface mas não quiser
refazer o estado do formulário, a validação nem o encanamento do envio. Omita
client para usar o SupportProvider mais próximo, ou passe client,
visitorId e, opcionalmente, contactId para um uso sem provider.
"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 gerencia as peças móveis de que qualquer interface de feedback
precisa:
- o estado de abertura com
open,setOpenehandleOpenChange - o estado da avaliação com
rating,hoveredRating,handleRatingSelectehandleRatingHoverChange - o estado do tema e do comentário com valores normalizados
- o estado de validação da avaliação, dos temas e dos comentários obrigatórios
- os estados pendente, de erro e enviado
- as ações de sucesso com
sendAnotheredone
As opções mais comuns são:
client: umFluxoClientexplícito para feedback sem providertopics: as categorias de feedback que podem ser escolhidasdefaultTopic: um tema pré-selecionado detopicstrigger: o motivo pelo qual esse formulário de feedback apareceusource: de onde veio esse feedback; por padrão,widgetconversationId: associa o feedback a uma conversa de suporte específicavisitorId: obrigatório quando nenhum contexto de provider fornece um visitantecontactId: associa o feedback a um contato identificadocommentRequired: exige um comentário escrito antes de enviardefaultOpen: já abre o popover ou o diálogo de inícioonSuccess: executa código depois que o Fluxo guardar o feedbackonError: trata um envio que falhou
Formulário de feedback sem provider
"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 envio de mais baixo nível
Use useSubmitFeedback quando você já controla o formulário inteiro e só
precisa da escrita. Ele segue a mesma regra de provider opcional: omita client
para usar o SupportProvider, ou passe entradas explícitas de runtime para um
formulário 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>
);
}Se você omitir client, useSubmitFeedback lê o cliente do Fluxo e o contexto
de visitante, site e contato do SupportProvider. Na maioria dos apps com
widget, passe rating, topic, comment, trigger e, opcionalmente,
conversationId. O hook preenche visitorId e contactId a partir do
contexto.
Para formulários sem provider, passe o cliente e o visitante explicitamente:
"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>
);
}Passe visitorId ou contactId na mão só se você estiver construindo uma
integração de mais baixo nível e souber que precisa sobrescrever o contexto.
Dados do feedback
Cada envio guarda:
rating: obrigatório, de 1 a 5topic: categoria estruturada opcionalcomment: comentário escrito opcionaltrigger: etiqueta opcional do que provocou o formuláriosource: por padrão,widgetconversationId: link opcional para uma conversavisitorId: o visitante que deixou o feedbackcontactId: o contato identificado, quando o visitante tem um
Essa associação é o que importa. Uma avaliação baixa de um cliente logado pode virar um acompanhamento de suporte real, não só um número em um painel.
Verificar e solucionar problemas
Depois de enviar, aguarde o estado de envio do formulário e confirme que o
feedback aparece no painel com o contexto de visitante e contato esperado. Um
401 normalmente significa que a chave pública está faltando ou é inválida. Um
403 normalmente significa que o hostname atual não é permitido. Se um
formulário sem provider não tiver visitante, passe um visitorId válido; caso
contrário, mantenha o formulário dentro do SupportProvider.
Exportações dos hooks
useFeedbackForm e useSubmitFeedback são exportados de
@fluxolat/react/hooks, @fluxolat/react/feedback e de importações profundas
explícitas como @fluxolat/react/hooks/use-feedback-form. Apps Next.js podem
usar as exportações equivalentes de @fluxolat/next/hooks e
@fluxolat/next/feedback.
Os hooks de provider opcional tratam client com cuidado: omiti-lo significa
"leia o contexto do provider", enquanto passar client: null desativa de
propósito o recurso ao provider.
Referência de tipos
Props do Feedback
Prop
Tipo
Opções de useFeedbackForm
Prop
Tipo
Resultado de useFeedbackForm
Nome
Tipo
Variáveis de envio de feedback
Parâmetro
Tipo
Esta página foi útil?
Abra uma issue de documentação já preenchida para que a equipe possa agir.
Nesta página
Antes de começarO caminho mais rápidoInstale os exemplos do shadcnFeedback com emojisFeedback com estrelasConstrua a suaFormulário de feedback sem providerAPI de envio de mais baixo nívelDados do feedbackVerificar e solucionar problemasExportações dos hooksReferência de tiposProps do FeedbackOpções de useFeedbackFormResultado de useFeedbackFormVariáveis de envio de feedback
