# File Storage

For storing large files outside the database, configure the `fileStore` interface. This is useful for handling file uploads, temporary files, and other binary data that shouldn't be stored in the database.

## Configuration

The `fileStore` interface requires three methods:

- `storeFile(content)` - Store a file and return a unique reference
- `getFile(fileRef)` - Retrieve a file by its reference
- `deleteFile(fileRef)` - Delete a file by its reference

## Platform Examples

### Generic Implementation

```js title="index.js"
configuration.fileStore = {
  async storeFile(content) {
    // Store file and return reference
    return fileReference;
  },
  async getFile(fileRef) {
    // Retrieve file by reference
    return fileBuffer;
  },
  async deleteFile(fileRef) {
    // Delete file by reference
  }
};
```

### AWS S3

```js title="index.js"
import AWS from 'aws-sdk';

const s3 = new AWS.S3();

configuration.fileStore = {
  async storeFile(content) {
    const fileId = `file_${Date.now()}_${Math.random()}`;
    await s3.putObject({
      Bucket: 'my-bucket',
      Key: fileId,
      Body: content
    }).promise();
    return fileId;
  },
  async getFile(fileId) {
    const result = await s3.getObject({
      Bucket: 'my-bucket',
      Key: fileId
    }).promise();
    return result.Body;
  },
  async deleteFile(fileId) {
    await s3.deleteObject({
      Bucket: 'my-bucket',
      Key: fileId
    }).promise();
  }
};
```

**S3 Setup:**

1. Install AWS SDK: <PackageManagers pkg="aws-sdk" />
2. Configure AWS credentials (environment variables, IAM role, or credentials file)
3. Create an S3 bucket in your AWS account
4. Grant appropriate permissions to your application
### Cloudflare KV

```ts title="worker/app.ts"
import { env } from 'cloudflare:workers';
import type { ClientConfig } from '@crowdin/app-project-module';

const configuration: ClientConfig = {
  // ... other config
  fileStore: {
    getFile: async (fileId: string): Promise<Buffer> => {
      const data = await env.KVStore.get(fileId, 'arrayBuffer');
      if (!data) {
        throw new Error(`File not found: ${fileId}`);
      }
      return Buffer.from(data);
    },
    storeFile: async (content: Buffer): Promise<string> => {
      const fileId = `file_${crypto.randomUUID()}`;
      // Files expire after 24 hours (86400 seconds)
      await env.KVStore.put(fileId, content, { expirationTtl: 86400 });
      return fileId;
    },
    deleteFile: async (fileId: string): Promise<void> => {
      await env.KVStore.delete(fileId);
    }
  }
};
```

**KV Setup:**

1. Create namespace: `npx wrangler kv namespace create KVStore`
2. Add to `wrangler.jsonc`:
   ```json
   "kv_namespaces": [
     {
       "binding": "KVStore",
       "id": "your-kv-namespace-id"
     }
   ]
   ```
See the [Cloudflare Workers deployment guide](/app-project-module/deployment/#cloudflare-workers) for a complete example.