Search code examples
reactjsnext.jssupabasesupabase-js

Error: "Load failed" trying to upload images to supabase


In my next.js app I am trying to upload image from form. But I keep getting an error: [Error] Unhandled Promise Rejection: TypeError: Load failed And the file doesn't upload to supabase.

I checked the image variable via console, it is a File object. Here is how I do it, I followed the tutorial in documentation:

import * as Form from "@radix-ui/react-form";
import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  "url",
  "api-key",
);

export default function Warehouses() {

  async function uploadImage(e) {
    const image = e.files[0];

    const { data, error } = await supabase.storage
      .from("images")
      .upload("/", image);

    if (data) {
      console.log(data);
    } else {
      console.log(error);
    }
  }

  const onSubmit = (event) => {
    uploadImage(event.target.images);
  };

  return (
    <div>
        <Form.Root className="FormRoot" onSubmit={onSubmit}>
          <Form.Field className="FormField" name="images">
            <div
              style={{
                display: "flex",
                alignItems: "baseline",
                justifyContent: "space-between",
              }}
            >
              <Form.Label className="FormLabel">
                Upload Images
              </Form.Label>
            </div>
            <Form.Control asChild>
              <input
                type="file"
                id="images"
                name="images"
                multiple
              />
            </Form.Control>
          </Form.Field>

          <Form.Submit asChild>
            <Button>Create</Button>
          </Form.Submit>
        </Form.Root>
    </div>
  );
}

I will appreciate any help!

UPDATE

I get this error in Safari browser also:

[Error] Fetch API cannot load https://my-url/storage/v1/object/images/2 due to access control checks.

Here is what I get from console.log(image) inside uploadImage(): image variable

I also tried to check the connection to supabase with this code:

export async function getServerSideProps() {
  const buckets = await supabase.storage.listBuckets();
  console.log(buckets);
  
  return {
    props: {
      bucketList: buckets,
    },
  };
}

But I get this in the console: ``` { data: [], error: null } ``

Below are the policies to my supabase bucket "images":

enter image description here

Here is the first (select) policy edit window: enter image description here

And the insert policy: enter image description here

Here is how the policies were added to my bucket:

enter image description here

enter image description here


Solution

  • You are not uploading the file in a way that passes the insert policy you have in place.

    The issue is that you have the storage.foldername(name)[1] = 'public', but you are not uploading the image in a public folder. For this poilcy to pass, you need to upload the image into /public path instead of /. I assume what you meant here is that you are uploading an image to a public bucket, but that is different from uploading to a public path. I think you can remove the storage.foldername(name)[1] = 'public' statement.

    Also, there are other things you can remove as well. First, we recently added a feature to restrict the meme types of the object being uploaded to a bucket. You can set it like this to only accept jpg.

    restrict meme types

    About the role, the correct way to specify which role you want the policy to be applied to is to select the target roles from the policy editor. You can set this to anon to target anon users.

    With all of that, you should be left with the following simple policy for what you want to do.

    insert policy

    Note that having users sign in to your app is not essential, but might be something to consider before you start promoting your app, because otherwise anyone can upload images to your bucket without any restrictions.