# Intro

{% hint style="warning" %}
**You don't feel like to read docs?** No problem, you can just go ahead and create an account and you will have all the information you need at your dashboard as well.
{% endhint %}

{% embed url="<https://www.file0.dev/signup>" %}
Create an account and skip the docs
{% endembed %}

For those who want to get a taste of FILE0 before signing up, let's not waste more of your time.

After creating an account you will need to hook up FILE0 with your project.


# Installation

You can connect FILE0 to any project by following these steps.

## 1. Install

Install the `file0` npm package. This will be your gateway to your files.\
You can import this package both in the server and client side.

```sh
npm install file0
```

```bash
pnpm add file0
```

```bash
yarn add file0
```

## 2. Connect

Connect to your project by adding your FILE0 app's secret key to you project's env variables.

```bash
F0_SECRET_KEY=f0_sk_*******************
```

**How to obtain the secret key?**

Create an account if you haven't already and copy the key from your app's setup guide.

{% embed url="<https://www.file0.dev/dashboard>" %}
Copy your secret key
{% endembed %}

## 3. Use FILE0 in your code

The environment variable will be automatically detected by the package, so you can start to execute commands right away.

```typescript
import { f0 } from 'file0';

await f0.set('image.png', Buffer.from('My image'));
```


# Upload

Uploading a file is as simple as calling the \`set\` method with the file name and the file content.

```typescript
import fs from "fs";
import { f0 } from "file0";

// Upload a json object
await f0.set("hello.json", JSON.stringify(myBigObject));

// Upload a text file from the file system
await f0.set("logs.txt", fs.readFileSync("./logs.txt"));

// Upload a blob
await f0.set("image.png", new Blob());

// Upload a public file
await f0.set("image.png", myFile, { public: true });

// Upload a file with expiration
await f0.set("image.png", myFile, { ttl: "30d" });
```


# Download

You can easily access your files in different formats (text, json, stream, etc...).

```typescript
import { f0 } from "file0";
import { Readable } from "stream";
import fs from "fs";

// Get file metadata (name, size, public url, etc..)
const metadata = await f0.get("logs.txt");

// Download a text file
const text = await f0.get("hello.txt", { as: "text" });

// Download a json object
const obj = await f0.get("data.json", { as: "json" });

// Download as a stream and save to the file system
const fileStream = await f0.get("logs.txt", { as: "stream"});
Readable
  .fromWeb(fileStream)
  .pipe(fs.createWriteStream("./logs.txt"));

// Download as a buffer
const file = await f0.get("image.png", { as: "buffer" });
// returns the web-compatible ArrayBuffer
// To convert it to a Node.js Buffer:
const nodejsBuffer = Buffer.from(file);
```


# Tokens (Client upload)

Managing large file uploads on the server comes with caveats. The recommended way is to authorize the client to upload a the specific file directly to File0, bypassing your server.

```typescript
import { f0 } from 'file0';

// Generate a file-scoped token
// With this token you can execute any command scoped to the given file.
const token = await f0.createToken('hello.txt', {
  expiresIn: '1h',
  maxUploadSize: '1mb',
});

// Use the token to upload the file
// Providing the file name is not required,
// because the token is already containing the file name.
await f0.useToken(token).set(myFile);

// You can also use the token to anything else,
// like to publish or download the file.
await f0.useToken(token).publish();
const text = await f0.useToken(token).get({ as: 'text'});
```


# Publish

Files are private by default, but you can make them public and share the public URL with anyone.

```typescript
import { f0 } from "file0";

// Publish a file
const url = await f0.publish("hello.txt");
// https://cdn.file0.dev/onjv1is7plntb93899xm2rw3.txt

// Unpublish a file
await f0.unpublish("hello.txt");
// Public URL is no longer valid
// If the file is published again, it will get a new public URL.
```


# List and Search

You can list files and apply filters. The returned list is paginated.

```typescript
import { f0 } from 'file0';

// List first 100 files
const { files, cursor, hasMore } = await f0.list();

// List the second 100 files
if (hasMore) {
  const { files, cursor, hasMore } = await f0.list({ cursor });
}

// List the first 1000 files
const { files, cursor, hasMore } = await f0.list({ limit: 1000 });

// List files that's name starts with 'user123/'
// and ends with '.png'
// and contains 'profile'
const files = await f0.list({
  endsWith: '.png', 
  startsWith: 'user123/',
  contains: 'profile'
});
```


# Delete

You can delete files by providing the file name.

```typescript
import { f0 } from "file0";

await f0.delete("hello.txt");
```


# File upload component (Next.js)

This example demonstrates how to upload a file from a Next.js application using tokens.

On the server side (pages router)

<pre class="language-typescript" data-title="pages/api/token.ts"><code class="lang-typescript"><strong>import { f0 } from "file0";
</strong>
export default async function handler(req, res) {
  // Authorize the user here...
  const token = await f0.createToken("example.json");
  res.json({ token });
}
</code></pre>

On the client side

{% code title="FileUpload.tsx" %}

```typescript
import { f0 } from "file0";

export function FileUpload() {
  const [file, setFile] = useState(null);

  const handleFileChange = (event) => {
      setFile(event.target.files[0]);
  };

  const upload = async () => {
    const { token } = await fetch("/api/token")
      .then((res) => res.json());

    f0.useToken(token).set(file);
  };

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      <button onClick={uploadFile}>Upload</button>
    </div>
  );
}
```

{% endcode %}


# Download button (Next.js)

This example demonstrates how to create a download button in a Next.js application using tokens.

On the server side (pages router)

{% code title="pages/api/token.ts" %}

```typescript
import { f0 } from "file0";
export default async function handler(req, res) {
  // Authorize the user here...
  const token = await f0.createToken("example.json", {
    expiresIn: '1h',
    maxUploadSize: '1mb'
  });
  res.json({ token });
}
```

{% endcode %}

On the client side

{% code title="DownloadButton.tsx" %}

```typescript
import { f0 } from "file0";
export function DownloadButton() {
  const download = async () => {
    const { token } = await fetch("/api/token")
      .then((res) => res.json());
    const blob = f0.useToken(token).get({ as: "blob" });
    const downloadUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = "example.json";
    a.target = "_blank";
    a.click();
    URL.revokeObjectURL(downloadUrl);
  };
  return (
    <button onClick={download}>Download</button>
  );
}
```

{% endcode %}


