# Server Uploads with Vercel Blob

Vercel Blob is available on [all plans](/content/docs/plans/index.html). Those with the [owner, member, developer](/content/docs/rbac/access-roles#owner,%20member,%20developer-role/index.html) role can access this feature.

In this guide, you'll learn how to do the following:

- Use the Vercel dashboard to create a Blob store connected to a project
- Upload a file using the Blob SDK from the server

Vercel has a [4.5 MB request body size limit](/content/docs/functions/runtimes#request-body-size/index.html) on Vercel Functions. If you need to upload larger files, use [client uploads](/content/docs/vercel-blob/client-upload/index.html).

## Prerequisites

Vercel Blob works with any frontend framework. First, install the package:

### Installation Commands
#### TypeScript
```bash
pnpm i @vercel/blob
```
#### Python
```bash
yarn add @vercel/blob
```
#### JavaScript
```bash
npm i @vercel/blob
```
#### Bun
```bash
bun add @vercel/blob
```

## Create a Blob store

1. Go to your project's [Storage section in the sidebar](/content/d?to=%2F%5Bteam%5D%2F%5Bproject%5D%2Fstores&title=Go+to+Storage/index.html)
2. Select Create Storage, then choose Blob
3. Select Continue, then set the access to Private or Public
4. Use the name "Images" and select Create a new Blob store
5. Select the environments where you would like the read-write token to be included.

Once created, you are taken to the Vercel Blob store page.

## Prepare your local project

Since you created the Blob store in a project, we automatically created and added the following Environment Variables to the project for you:

- `BLOB_STORE_ID`: Identifies your Blob store
- `VERCEL_OIDC_TOKEN`: A short-lived token issued at runtime; rotated automatically
- `BLOB_READ_WRITE_TOKEN`: A long-lived static read-write token for code running outside Vercel or to generate client tokens for browser uploads

To use these Environment Variables locally, we recommend pulling them with the Vercel CLI:
```bash
vercel env pull
```

## Upload a file using Server Actions

The following example shows how to use a [Server Action](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations) with Next.js App Router to upload a file to Vercel Blob.

### Example Code (Form Component)
```typescript
import { put } from '@vercel/blob';
import { revalidatePath } from 'next/cache';

export async function Form() {
  async function uploadImage(formData: FormData) {
    'use server';
    const imageFile = formData.get('image') as File;
    const blob = await put(imageFile.name, imageFile, {
      access: 'private' /* or 'public' */,
      addRandomSuffix: true,
    });
    revalidatePath('/');
    return blob;
  }

return (
    <form action={uploadImage}>
      <label htmlFor="image">Image</label>
      <input
        type="file"
        id="image"
        name="image"
        accept="image/jpeg, image/png, image/webp"
        required
      />
      <button>Upload</button>
    </form>
  );
}
```

## Upload a file using a server upload page and route

You can upload files to Vercel Blob using Route Handlers/API Routes. The following example shows how to upload a file to Vercel Blob using a server upload page and route.

### Create a server upload page
```typescript
'use client';
import type { PutBlobResult } from '@vercel/blob';
import { useState, useRef } from 'react';

export default function AvatarUploadPage() {
     const inputFileRef = useRef<HTMLInputElement>(null);
     const [blob, setBlob] = useState<PutBlobResult | null>(null);
     return (
       <>
         <h1>Upload Your Avatar</h1>

<form
           onSubmit={async (event) => {
             event.preventDefault();

if (!inputFileRef.current?.files) {
               throw new Error('No file selected');
             }

const file = inputFileRef.current.files[0];

const response = await fetch(
               `/api/avatar/upload?filename=${file.name}`,
               {
                 method: 'POST',
                 body: file,
               },
             );

const newBlob = (await response.json()) as PutBlobResult;

setBlob(newBlob);
           }}
         >
           <input
             name="file"
             ref={inputFileRef}
             type="file"
             accept="image/jpeg, image/png, image/webp"
             required
           />
           <button type="submit">Upload</button>
         </form>
         {blob && (
           <div>
             Blob url: <a href={blob.url}>{blob.url}</a>
           </div>
         )}
       </>
     );
}
```

### Create a server upload route
```typescript
import { put } from '@vercel/blob';
import { NextResponse } from 'next/server';

export async function POST(request: Request): Promise<NextResponse> {
     const { searchParams } = new URL(request.url);
     const filename = searchParams.get('filename');

const blob = await put(filename, request.body, {
       access: 'private' /* or 'public' */,
       addRandomSuffix: true,
     });

return NextResponse.json(blob);
}
```

## Testing your page

1. Run your application locally and visit `/avatar/upload` to upload the file to your store. The browser will display the unique URL created for the file.
2. Review the Blob object metadata:
   - Go to the Vercel Project where you created the store
   - Open Storage in the sidebar and select your new store
   - Paste the blob object URL returned in the previous step in the Blob URL input box in the Browser section and select Lookup
   - The following blob object metadata will be displayed: file name, path, size, uploaded date, content type and HTTP headers

## Next steps
- Learn how to [use the methods](/content/docs/vercel-blob/using-blob-sdk/index.html) available with the `@vercel/blob` package.
