Persistencia de Conversa

Conversa persiste ao recarregar a pagina

Implementado em: 2026-04-02 Status: Ativo


Resumo

A conversa aberta no chat persiste ao recarregar a página (F5). O ticketId selecionado é salvo na URL como query parameter. Ao recarregar, o sistema lê o parâmetro e reabre a conversa automaticamente.


Como Funciona

Salvar na URL (ao selecionar conversa)

const selectTicket = useCallback((ticketId: number | null) => {
  setSelectedTicketId(ticketId)
  const url = new URL(window.location.href)
  if (ticketId) {
    url.searchParams.set("ticket", String(ticketId))
  } else {
    url.searchParams.delete("ticket")
  }
  window.history.replaceState({}, "", url.toString())
}, [])

Ler da URL (ao carregar página)

const searchParams = useSearchParams()
const [selectedTicketId, setSelectedTicketId] = useState<number | null>(() => {
  const param = searchParams.get("ticket")
  return param ? parseInt(param) : null
})

Fluxo completo

1. Usuário clica "João" → URL: /chat?ticket=45
2. F5 (recarregar)
3. useSearchParams lê ?ticket=45
4. selectedTicketId = 45
5. Tickets carregam da API
6. selectedTicket = tickets.find(t => t.id === 45)
7. Chat abre na conversa do "João" automaticamente

Detalhes Técnicos

  • window.history.replaceState — atualiza URL sem recarregar a página e sem criar entrada no histórico
  • useSearchParams — hook do Next.js App Router para ler query params
  • Suspense wrapper — necessário no Next.js para useSearchParams funcionar em Server Components
  • Zero overhead — nenhuma chamada extra, nenhum storage, apenas leitura de string da URL

Benefícios extras

Benefício Descrição
Deep link /chat?ticket=45 abre direto na conversa
Compartilhável Pode enviar link para outro atendente
Funciona em incógnito Não depende de localStorage
Histórico limpo replaceState não cria entradas extras no back/forward

Arquivo

frontend/src/app/(dashboard)/chat/page.tsx:

  • useSearchParams + Suspense wrapper
  • selectTicket() com replaceState
  • Inicialização do selectedTicketId a partir do query param

Este artigo foi útil?