# Download Trigger

URL: https://ark-ui.com/docs/utilities/download-trigger
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/utilities/download-trigger.mdx

Trigger file downloads programmatically.

---

## Motivation

The `DownloadTrigger` component provides a convenient way to programmatically trigger file downloads in web
applications. It handles the complexities of downloading files, whether they are URLs, Blobs, or other data types.

## Examples

### Basic

Pass the data you want to download to the `data` prop, and specify the `fileName` and `mimeType` of the file.

**Example: basic**

#### React

```tsx
import { DownloadTrigger } from '@ark-ui/react/download-trigger'
import { DownloadIcon, FileIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const content = 'Hello, World! This is a sample text file.'

export const Basic = () => {
  return (
    <div className={styles.Root}>
      <div className={styles.Preview}>
        <FileIcon />
        <span className={styles.PreviewText}>{content}</span>
      </div>
      <DownloadTrigger className={button.Root} data={content} fileName="hello.txt" mimeType="text/plain">
        <DownloadIcon /> Download txt
      </DownloadTrigger>
    </div>
  )
}

```

#### Solid

```tsx
import { DownloadTrigger } from '@ark-ui/solid/download-trigger'
import { DownloadIcon, FileIcon } from 'lucide-solid'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const content = 'Hello, World! This is a sample text file.'

export const Basic = () => {
  return (
    <div class={styles.Root}>
      <div class={styles.Preview}>
        <FileIcon />
        <span class={styles.PreviewText}>{content}</span>
      </div>
      <DownloadTrigger class={button.Root} data={content} fileName="hello.txt" mimeType="text/plain">
        <DownloadIcon /> Download txt
      </DownloadTrigger>
    </div>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { DownloadTrigger } from '@ark-ui/vue/download-trigger'
import { DownloadIcon, FileIcon } from 'lucide-vue-next'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const content = 'Hello, World! This is a sample text file.'
</script>

<template>
  <div :class="styles.Root">
    <div :class="styles.Preview">
      <FileIcon />
      <span :class="styles.PreviewText">{{ content }}</span>
    </div>
    <DownloadTrigger :class="button.Root" :data="content" fileName="hello.txt" mimeType="text/plain">
      <DownloadIcon />
      Download txt
    </DownloadTrigger>
  </div>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { DownloadTrigger } from '@ark-ui/svelte/download-trigger'
  import { DownloadIcon, FileIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import styles from 'styles/download-trigger.module.css'

  const content = 'Hello, World! This is a sample text file.'
</script>

<div class={styles.Root}>
  <div class={styles.Preview}>
    <FileIcon />
    <span class={styles.PreviewText}>{content}</span>
  </div>
  <DownloadTrigger class={button.Root} data={content} fileName="hello.txt" mimeType="text/plain">
    <DownloadIcon /> Download txt
  </DownloadTrigger>
</div>

```

### Download SVG

Here's an example of how to download an SVG file.

**Example: svg**

#### React

```tsx
import { DownloadTrigger } from '@ark-ui/react/download-trigger'
import { DownloadIcon, FileIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/>
</svg>`

export const Svg = () => {
  return (
    <div className={styles.Root}>
      <div className={styles.Preview}>
        <FileIcon />
        <span className={styles.PreviewText}>circle.svg</span>
      </div>
      <DownloadTrigger className={button.Root} data={svgContent} fileName="circle.svg" mimeType="image/svg+xml">
        <DownloadIcon /> Download SVG
      </DownloadTrigger>
    </div>
  )
}

```

#### Solid

```tsx
import { DownloadTrigger } from '@ark-ui/solid/download-trigger'
import { DownloadIcon, FileIcon } from 'lucide-solid'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/>
</svg>`

export const Svg = () => {
  return (
    <div class={styles.Root}>
      <div class={styles.Preview}>
        <FileIcon />
        <span class={styles.PreviewText}>circle.svg</span>
      </div>
      <DownloadTrigger class={button.Root} data={svgContent} fileName="circle.svg" mimeType="image/svg+xml">
        <DownloadIcon /> Download SVG
      </DownloadTrigger>
    </div>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { DownloadTrigger } from '@ark-ui/vue/download-trigger'
import { DownloadIcon, FileIcon } from 'lucide-vue-next'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/>
</svg>`
</script>

<template>
  <div :class="styles.Root">
    <div :class="styles.Preview">
      <FileIcon />
      <span :class="styles.PreviewText">circle.svg</span>
    </div>
    <DownloadTrigger :class="button.Root" :data="svgContent" fileName="circle.svg" mimeType="image/svg+xml">
      <DownloadIcon />
      Download SVG
    </DownloadTrigger>
  </div>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { DownloadTrigger } from '@ark-ui/svelte/download-trigger'
  import { DownloadIcon, FileIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import styles from 'styles/download-trigger.module.css'

  const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/>
</svg>`
</script>

<div class={styles.Root}>
  <div class={styles.Preview}>
    <FileIcon />
    <span class={styles.PreviewText}>circle.svg</span>
  </div>
  <DownloadTrigger class={button.Root} data={svgContent} fileName="circle.svg" mimeType="image/svg+xml">
    <DownloadIcon /> Download SVG
  </DownloadTrigger>
</div>

```

### Promise

You can also trigger downloads from a promise that returns a `Blob`, `File`, or `string`.

**Example: with-promise**

#### React

```tsx
import { DownloadTrigger } from '@ark-ui/react/download-trigger'
import { DownloadIcon, ImageIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

export const WithPromise = () => {
  const fetchImage = async () => {
    const response = await fetch('https://picsum.photos/200/300')
    return response.blob()
  }

  return (
    <div className={styles.Root}>
      <div className={styles.Preview}>
        <ImageIcon />
        <span className={styles.PreviewText}>random-image.jpg (fetched on download)</span>
      </div>
      <DownloadTrigger className={button.Root} data={fetchImage} fileName="random-image.jpg" mimeType="image/jpeg">
        <DownloadIcon /> Download Image
      </DownloadTrigger>
    </div>
  )
}

```

#### Solid

```tsx
import { DownloadTrigger } from '@ark-ui/solid/download-trigger'
import { DownloadIcon, ImageIcon } from 'lucide-solid'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

export const WithPromise = () => {
  const fetchImage = async () => {
    const response = await fetch('https://picsum.photos/200/300')
    return response.blob()
  }

  return (
    <div class={styles.Root}>
      <div class={styles.Preview}>
        <ImageIcon />
        <span class={styles.PreviewText}>random-image.jpg (fetched on download)</span>
      </div>
      <DownloadTrigger class={button.Root} data={fetchImage} fileName="random-image.jpg" mimeType="image/jpeg">
        <DownloadIcon /> Download Image
      </DownloadTrigger>
    </div>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { DownloadTrigger } from '@ark-ui/vue/download-trigger'
import { DownloadIcon, ImageIcon } from 'lucide-vue-next'
import button from 'styles/button.module.css'
import styles from 'styles/download-trigger.module.css'

const fetchImage = async () => {
  const response = await fetch('https://picsum.photos/200/300')
  return response.blob()
}
</script>

<template>
  <div :class="styles.Root">
    <div :class="styles.Preview">
      <ImageIcon />
      <span :class="styles.PreviewText">random-image.jpg (fetched on download)</span>
    </div>
    <DownloadTrigger :class="button.Root" :data="fetchImage" fileName="random-image.jpg" mimeType="image/jpeg">
      <DownloadIcon />
      Download Image
    </DownloadTrigger>
  </div>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { DownloadTrigger } from '@ark-ui/svelte/download-trigger'
  import { DownloadIcon, ImageIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import styles from 'styles/download-trigger.module.css'

  const fetchImage = async () => {
    const response = await fetch('https://picsum.photos/200/300')
    return response.blob()
  }
</script>

<div class={styles.Root}>
  <div class={styles.Preview}>
    <ImageIcon />
    <span class={styles.PreviewText}>random-image.jpg (fetched on download)</span>
  </div>
  <DownloadTrigger class={button.Root} data={fetchImage} fileName="random-image.jpg" mimeType="image/jpeg">
    <DownloadIcon /> Download Image
  </DownloadTrigger>
</div>

```

## API Reference

**Component API Reference**

#### React

**DownloadTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `data` | `DownloadableData | (() => MaybePromise<DownloadableData>)` | Yes | The data to download |
| `fileName` | `string` | Yes | The name of the file to download |
| `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


#### Solid

**DownloadTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `data` | `DownloadableData | (() => MaybePromise<DownloadableData>)` | Yes | The data to download |
| `fileName` | `string` | Yes | The name of the file to download |
| `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download |
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


#### Vue

**DownloadTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `data` | `DownloadableData | (() => MaybePromise<DownloadableData>)` | Yes | The data to download |
| `fileName` | `string` | Yes | The name of the file to download |
| `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


#### Svelte

**DownloadTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `data` | `DownloadableData | (() => MaybePromise<DownloadableData>)` | Yes |  |
| `fileName` | `string` | Yes |  |
| `mimeType` | `FileMimeType` | Yes |  |
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |
