Limite de cliente pequeno
Marque apenas o módulo de chat interativo com `use client`, em vez de transferir uma página ou layout inteiro para o navegador.
Use @openstaticfish/chattybox dentro de um limite de cliente focado enquanto o restante do seu aplicativo App Router permanece renderizado pelo servidor. ChattyBox lida com recuperação, citações, conversas e dimensionamento.
Conversa ilustrativa — não é um chat em direto.
O ChattyBox rastreia seu site, documentação, central de ajuda, CMS ou base de conhecimento existentes e, em seguida, incorpora um chatbot que responde com base no seu próprio conteúdo publicado, em vez da memória genérica do modelo.
Instale @openstaticfish/chattybox no aplicativo Next.js.
Adicione a chave de API do widget público e o URL da API como variáveis de ambiente NEXT_PUBLIC.
Crie um componente cliente para estado de chat e interação do navegador.
Importe esse componente cliente de uma página ou layout de componente de servidor.
Lançamento em três etapas
Mantenha o SDK na borda do cliente onde ocorre a interação por chat e preserve os componentes do servidor para o restante do aplicativo.
Use esses pontos de verificação para decidir se ChattyBox deve ficar ao lado de sua plataforma de documentos, substituir um assistente separado ou permanecer isolado para testes.
Marque apenas o módulo de chat interativo com `use client`, em vez de transferir uma página ou layout inteiro para o navegador.
Use uma chave de projeto segura para navegador com origens permitidas; nunca exponha credenciais de gerenciamento por meio de variáveis NEXT_PUBLIC.
Renderize mensagens e citações em sua própria navegação, área de conta, shell de documentos ou fluxo de trabalho de suporte.
Evite adicionar manipuladores de rota apenas para fazer proxy de uma API de navegador gerenciado, a menos que seu produto tenha um requisito concreto do lado do servidor.
O SDK usa credenciais de projeto visíveis no navegador e buscadas, portanto, inicialize-o em um módulo cliente. Mantenha segredos e APIs de gerenciamento fora das variáveis NEXT_PUBLIC.
'use client';
import { useState, type FormEvent } from 'react';
import { Chattybox, ChattyboxError, type ChatResponse } from '@openstaticfish/chattybox';
const chattybox = new Chattybox({
apiKey: process.env.NEXT_PUBLIC_CHATTYBOX_API_KEY!,
baseUrl: process.env.NEXT_PUBLIC_CHATTYBOX_API_URL!,
});
export function Chat() {
const [question, setQuestion] = useState('');
const [answer, setAnswer] = useState<ChatResponse | null>(null);
const [pending, setPending] = useState(false);
const [error, setError] = useState('');
async function ask(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const message = question.trim();
if (pending || !message || message.length > 2000) return;
setPending(true);
setError('');
try {
setAnswer(await chattybox.sendMessage({
message,
// Same ID includes up to 12 recent saved messages, not the full transcript.
conversationId: answer?.conversationId,
}));
setQuestion('');
} catch (failure) {
setError(failure instanceof ChattyboxError
? failure.status + ': ' + failure.message
: 'Chat could not be completed.');
} finally {
setPending(false);
}
}
const sources = answer?.sources.filter((source) => {
try { return ['https:', 'http:'].includes(new URL(source).protocol); }
catch { return false; }
}) ?? [];
return (
<section aria-label="Chat">
<form onSubmit={ask}>
<label>Question
<input value={question} maxLength={2000} disabled={pending}
onChange={(event) => setQuestion(event.target.value)} />
</label>
<button type="submit" disabled={pending || !question.trim()}>
{pending ? 'Sending...' : 'Send'}
</button>
</form>
{error && <p role="alert">{error}</p>}
<div aria-live="polite" aria-busy={pending}>
<p style={{ whiteSpace: 'pre-wrap' }}>{answer?.message}</p>
{sources.length > 0 && <ul aria-label="Sources">
{sources.map((source, index) => <li key={index}>
<a href={source} target="_blank" rel="noopener noreferrer">{source}</a>
</li>)}
</ul>}
</div>
</section>
);
}
// Import and render <Chat /> from your page or layout. This shows the latest answer, not a saved transcript.
// No automatic retries: see the SDK retry-safety guide before adding retries.Sim. Use-o em um componente cliente para estado de bate-papo interativo e renderize esse componente a partir de uma página ou layout do App Router.
Não para a integração normal do navegador. As chaves públicas do widget são projetadas para uso do cliente e podem ser restritas a origens aprovadas.
A chave pública do widget identifica um projeto, mas não é uma credencial de gerenciamento. Restrinja-o às suas origens de produção e visualização e nunca exponha segredos administrativos.
Sim. O guia de instalação hospedado mostra o próximo caminho do script quando você prefere uma UI mantida em vez de uma interface SDK personalizada.
Não é necessário cartão de crédito
Plano Free. Sem cartão.