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

# Files

> Upload and download organization files through the authenticated Worker.

The generated app includes one public file path. It stores an opaque file ID in SQLite and keeps the R2 bucket, key, checksum, and upload state out of application rows.

## Declare the column

Declare one nullable `file()` column and include it in the table policy.

```ts src/schema.ts theme={null}
import { file } from "@chardb/core/files";

export const messages = cdbTable(
  "messages",
  {
    attachment: file("attachment", {
      maxSize: 5 * 1_024 * 1_024,
      contentTypes: ["image/jpeg", "image/png"],
    }),
  },
  {
    selfBy: "authorId",
    roles: {
      member: { read: "*", create: ["id", "body", "attachment", "createdAt"] },
      self: { update: ["body", "attachment"] },
    },
  },
);
```

This release accepts files up to the column limit, capped by the current proxied-upload maximum. The generated example accepts JPEG and PNG files up to 5 MiB.

## Bind the browser client

The browser uses a schema locator because `schema.ts` imports server-only Better Auth definitions.

```tsx theme={null}
import { fileRef } from "@chardb/core/files";

const messageAttachment = fileRef("messages", "attachment");

function Attachment({ rowId }: Props) {
  const attachment = db.useFile(messageAttachment);

  return (
    <a href={attachment.downloadUrl({ rowId })}>
      Download attachment
    </a>
  );
}
```

Upload before the message mutation, then store the returned opaque ID.

```tsx theme={null}
const post = db.useMutation(postMessage);
const uploaded = await attachment.upload({
  file: selectedFile,
  idempotencyKey: crypto.randomUUID(),
});

await post({
  id: uuidv7(),
  body,
  attachment: uploaded.fileId,
  clientCreatedAt: Date.now(),
});
```

The configured client adds the active organization to writes, uploads, and downloads. File routes use the Worker URL configured on `createChardbReactClient`, and the browser sends the Better Auth session cookie automatically. CharDB checks the active organization, current membership, table policy, row ID, and opaque file ID before returning bytes.

<Note>
  Do not store an R2 URL or object key. Store only the `FileId` returned by the upload.
</Note>

Use [Vectors](/vectors) when the row also needs semantic search.
