---
title: "DLQ Panel"
description: "Dead-lettered deliveries with one-click replay."
component: true
---

```tsx
"use client";

import { useState } from "react";
import { DlqPanel, type DlqDeliveryRow } from "@/components/dlq-panel";
import { fixtureLogRows } from "@/fixtures/webhook-fixtures";

const DELIVERIES: DlqDeliveryRow[] = fixtureLogRows(5).map((row, index) => ({
  id: row.deliveryId,
  type: row.type,
  endpointId: row.endpointId,
  attemptCount: 8,
  lastStatusCode: index % 2 === 0 ? 503 : null,
  lastErrorClass: index % 2 === 0 ? null : "timeout",
  createdAt: row.timestamp,
}));

export function DlqPanelDemo() {
  const [replayed, setReplayed] = useState<string[]>([]);

  return (
    <DlqPanel
      deliveries={DELIVERIES.filter((delivery) => !replayed.includes(delivery.id))}
      onReplay={(delivery) => setReplayed((current) => [...current, delivery.id])}
    />
  );
}

```

## Installation

<ItemInstall name="dlq-panel" target="components/dlq-panel.tsx" />

## Usage

This component is presentational: it renders what you pass it and calls back on
interaction. In a live dashboard the data comes from `useDlq() + useReplayDelivery()`
([@repost/portal-react](/docs/ui/portal-react)), but any data of
the same shape works.

<ComponentSource name="dlq-panel-demo" title="components/dlq-panel-demo.tsx" />

## Props

| Prop | Type | Description |
| ---- | ---- | ----------- |
| `deliveries` | `DlqDeliveryRow[]` | Exhausted deliveries. |
| `onReplay` | `(delivery) => void` | Queue a replay. |
| `replayingId` | `string | null` | Disables that row's button. |
