# Document Ingest (/docs/components/document-ingest)



<ComponentPreview name="ai-document-upload" />

## Installation [#installation]

<Tabs items="[&#x22;Command&#x22;, &#x22;Manual&#x22;]">
  <Tab value="Command">
    <CodeBlockTabs defaultValue="npm">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="npm">
          npm
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="pnpm">
          pnpm
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="yarn">
          yarn
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="bun">
          bun
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="npm">
        ```bash
        npx shadcn@latest add @uploadcn/document-ingest
        ```
      </CodeBlockTab>

      <CodeBlockTab value="pnpm">
        ```bash
        pnpm dlx shadcn@latest add @uploadcn/document-ingest
        ```
      </CodeBlockTab>

      <CodeBlockTab value="yarn">
        ```bash
        yarn dlx shadcn@latest add @uploadcn/document-ingest
        ```
      </CodeBlockTab>

      <CodeBlockTab value="bun">
        ```bash
        bun x shadcn@latest add @uploadcn/document-ingest
        ```
      </CodeBlockTab>
    </CodeBlockTabs>
  </Tab>

  <Tab value="Manual">
    Install [Upload](/docs/components/upload) first, then copy:

    <ComponentSource name="document-ingest" />
  </Tab>
</Tabs>

## Usage [#usage]

```tsx
import { DocumentIngest } from "@/components/document-ingest"
```

```tsx
<DocumentIngest
  ingest={async (item, { setStage, signal }) => {
    const { jobId } = await startIngestion(item.result.key, { signal })
    for await (const stage of watchJob(jobId, { signal })) setStage(stage)
  }}
/>
```

Stages are `upload`, `parse`, `chunk`, `embed` and `index`. Report them from polling, server-sent events or webhooks: the UI only reflects what your backend says.

## Props [#props]

<TypeTable
  type="{
  adapter: {
    type: &#x22;UploadAdapter&#x22;,
    default: 's3Adapter({ endpoint: &#x22;/api/upload&#x22; })',
    description: &#x22;Where files go.&#x22;,
  },
  ingest: {
    type: &#x22;(item, { setStage, signal, setStatus, result }) => Promise<void>&#x22;,
    description:
      &#x22;Drives server-side ingestion after the bytes are stored. Throw to fail the item.&#x22;,
  },
  accept: {
    type: &#x22;string[]&#x22;,
    default: &#x22;PDF, DOCX, TXT, MD, HTML, CSV, JSON&#x22;,
  },
  maxFiles: { type: &#x22;number&#x22;, default: &#x22;50&#x22; },
}"
/>
