> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anotherwrapper.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage

> Object storage for uploads and generated files

<Info>
  Storage is where your app keeps uploaded files and generated media. If you skip this, the basic app still runs, but upload-heavy features like document chat, image generation, and audio won't work properly.
</Info>

## What Uses Storage

Your app needs storage for:

* Chat document uploads (PDFs)
* Generated images
* Generated videos
* Generated audio
* User-uploaded files for vision and other tools

## Get It Running

<Steps>
  <Step title="Create a bucket">
    We recommend **Cloudflare R2** because it's S3-compatible and simple to set up. Create a bucket in the R2 dashboard.
  </Step>

  <Step title="Generate API credentials">
    Create an API token with read/write access to your bucket. Copy the S3 endpoint from your R2 dashboard.
  </Step>

  <Step title="Configure a public URL">
    Set up a custom domain or use the default `r2.dev` URL so your users can access stored files in the browser.
  </Step>

  <Step title="Add your env vars">
    <CodeGroup>
      ```env .env.local (Cloudflare R2) theme={null}
      STORAGE_REGION=auto
      STORAGE_ACCESS_KEY=your-access-key
      STORAGE_SECRET_KEY=your-secret-key
      STORAGE_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
      STORAGE_BUCKET=anotherwrapper
      STORAGE_PUBLIC_URL=https://cdn.yourdomain.com
      ```

      ```env .env.local (Generic S3-compatible) theme={null}
      STORAGE_REGION=us-east-1
      STORAGE_ACCESS_KEY=your-access-key
      STORAGE_SECRET_KEY=your-secret-key
      STORAGE_ENDPOINT=https://your-s3-endpoint.com
      STORAGE_BUCKET=your-bucket-name
      STORAGE_PUBLIC_URL=https://your-public-url.com
      ```
    </CodeGroup>
  </Step>

  <Step title="Restart and test">
    Restart your dev server, upload a file, and check that the stored file URL opens in the browser.
  </Step>
</Steps>

## What Each Env Var Does

| Variable             | Purpose                                                |
| -------------------- | ------------------------------------------------------ |
| `STORAGE_REGION`     | Region value expected by your provider (`auto` for R2) |
| `STORAGE_ACCESS_KEY` | Access key for your bucket                             |
| `STORAGE_SECRET_KEY` | Secret key for your bucket                             |
| `STORAGE_ENDPOINT`   | S3-compatible API endpoint                             |
| `STORAGE_BUCKET`     | Bucket name                                            |
| `STORAGE_PUBLIC_URL` | The public URL users will open in the browser          |

<Warning>
  **The most important rule:** `STORAGE_PUBLIC_URL` must point to the same bucket your app is uploading into. If your app writes to Bucket A but the public URL points to Bucket B, uploads will succeed but every link will be broken.
</Warning>

## Key Files

The main storage logic lives in:

* `lib/storage/object-storage.ts` -- uploads, deletes, and public URLs
* `lib/integrations/cloudflare.ts` -- Cloudflare-specific integration

## Verify It Works

<Check>
  Your storage setup is working if you can:

  * Upload a file through the app
  * See generated media save successfully
  * Open the stored file URL in your browser
</Check>

<AccordionGroup>
  <Accordion title="Wrong bucket name or endpoint">
    Double-check that `STORAGE_BUCKET` matches the exact name in your provider dashboard, and that `STORAGE_ENDPOINT` uses the correct account ID.
  </Accordion>

  <Accordion title="Public URL pointing to the wrong place">
    Your `STORAGE_PUBLIC_URL` must resolve to the same bucket you're uploading to. If you're using a CDN, make sure it's configured to serve from the right origin.
  </Accordion>

  <Accordion title="Env vars set but nothing works">
    Did you restart the app? Next.js doesn't pick up new env vars until you restart the dev server.
  </Accordion>
</AccordionGroup>
