Skip to main content

Multiple Files

Upload and manage multiple files on a single record.

Schema

getMultipleFileSchema adds two fields to your schema:

  • files -- array of new files to upload
  • deleteFileIds -- IDs of existing files to remove
import { FileInput } from '@repo/storage'
import { z } from 'zod'

export const myFormSchema = z.object({
name: z.string(),
...FileInput.getMultipleFileSchema({
getUrl: file => `/my-resource/${resourceId}/files/${file.id}`,
}),
})

getUrl provides the serving URL for each existing file (used for preview).

Only one file field per form is currently supported.

Sync

Destructure files and deleteFileIds, then pass both to sync:

export const createMyResourceForm = form(myFormSchema, async (data) => {
const { files, deleteFileIds, ...restData } = data

await serverFileManager.createBucket('my-bucket')

await serverFileManager.sync('my-bucket', {
files,
deleteFileIds,
})
})

sync uploads all new files and deletes any files matching deleteFileIds from both S3 and the database.

Editing

Wrap the form in FileInput.Provider to populate existing files:

<script lang="ts">
import { FileInput } from '@repo/storage'

let { data } = $props()
</script>

<FileInput.Provider fileMeta={data.fileMeta}>
<TypedForm.Remote form={createMyResourceForm} schema={myFormSchema} enctype='multipart/form-data' />
</FileInput.Provider>