Next.js Discord

Discord Forum

How to pass file object to server action

Answered
American black bear posted this in #help-forum
Open in Discord
Avatar
American black bearOP
I am creating an image upload to my backend. On frontend I use <input type="file" /> to get the File object which I plan to upload then I pass it to server action to add it to the database and minio storage.

However this pattern does not work since I get the following error when trying to achieve it like this:

Error: Only plain objects, and a few built-ins, can be passed to Server Actions. Classes or null prototypes are not supported.


My server action:

"use server"

async function uploadFile({file}: {file: File}) {
  // ...code
}
Answered by B33fb0n3
you can also convert your file into an buffer and send the buffer to the server action. It could look like this:
  const file = event.target.files[0]; // or get your file differently.
  const arrayBuffer = await file.arrayBuffer();
  const buffer = new Uint8Array(arrayBuffer);
  const response = await uploadFile(buffer);

Like that you can read the buffer inside your server action as well and upload it as file. It depends very much on your storage server on how to upload a file, so I can't provide you a code example. Buffer should be accepted by most services
View full answer

7 Replies

Avatar
you can create a form and use your uploadFile function as action. Like this:
<form action={uploadFile}>
...
</form>

Like that you can access the files directly in your function via the formdata.

"use server"

async function uploadFile(formData: FormData) {
  // ...code
}
Avatar
American black bearOP
I am using a shadcn with react-hook-form like in their examples. Is there any difference to calling form from onSubmit and action?

<form onSubmit={form.handleSubmit(onSubmit)} />


https://ui.shadcn.com/docs/components/form
Avatar
iirc like that you won't be able to get the formdata
Avatar
American black bearOP
I am not really using formData, I am using plain state to hold the form state. is that a bad practice?
Avatar
you can also convert your file into an buffer and send the buffer to the server action. It could look like this:
  const file = event.target.files[0]; // or get your file differently.
  const arrayBuffer = await file.arrayBuffer();
  const buffer = new Uint8Array(arrayBuffer);
  const response = await uploadFile(buffer);

Like that you can read the buffer inside your server action as well and upload it as file. It depends very much on your storage server on how to upload a file, so I can't provide you a code example. Buffer should be accepted by most services
Answer
Avatar
American black bearOP
I will try this thank you!
Avatar
happy to help