#Trouble With Media Items

35 messages · Page 1 of 1 (latest)

loud hare
#

Hello, I'm genuinely at a loss and really need some guidance. I'm pretty sure most of my issues are from using the Starter Website Template instead of building my site up from scratch, but when I first started this project figured skipping some of the tedious steps would've been worth my time. I've gotten the site to the point where I want to get images working properly. Right now the site is up and I can see the content, but I can't fetch images from my Cloudflare R2.

I'm using the S3 Plugin as I've seen mentioned in tutorials and it is properly uploading the images from the Admin Panel. The trouble comes when the site tries to find the appropriate images, it's still trying to find the images in local storage. I'm using Vercel from my deployments, so I need to figure out where to make any changes to the Template code to allow it to find me R2 and ignore local storage properly.

Apologies if this is a duplicate issue or in the wrong sectio. Thank you in advance for any help.

timber masonBOT
slate gulch
#

Hey @loud hare can you clarify, are you using the AWS S3 plugin or the Cloudflare R2 plugin?

loud hare
#

The S3 plugin.
Most of the write-ups or tutorials I came across suggested using it over the R2 plugin.

#

@slate gulch

slate gulch
#

Ok, just wanted to make sure as you mentioned both in your message

#

so you have an Amazon S3 bucket and all your credentials in your env file?

#
S3_ACCESS_KEY_ID = from AWS IAM → Users → Security credentials → Access keys
S3_SECRET_ACCESS_KEY = shown once when creating the access key, can't be retrieved after
S3_REGION = wherever your bucket was created (us-east-1, eu-west-1, etc.)```
loud hare
slate gulch
#

That might explain the issue. If you are using Cloudflare then you need to use the R2 plugin. They are not interchangeable. S3 for AWS R2 for Cloudflare. Even if you have your env variables in there, if you don't have it setup properly your local instance is just going to default to uploading media to /api/media, which makes sense why you don't see your images once deployed

loud hare
slate gulch
#

Ohhh

#

you are right

#

my mistake!

#

So it does look like cloudflare exposes an S3-compatible HTTP endpoint for R2—meaning any S3 client can talk to it

#

So I think what you'd need to update for your ENV variables is:

S3_REGION=auto S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com

loud hare
#

That is currently how they are set.

s3Storage({
    enabled: true,
    clientUploads: true,
    collections:{
      media: {
        disableLocalStorage: true
      },
    },
    //@ts-ignore
    bucket: process.env.R2_BUCKET,
    config: {
      credentials: {
        //@ts-ignore
        accessKeyId: process.env.R2_ACCESS_KEY_ID,
        //@ts-ignore
        secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
      },
      region: 'auto',
      endpoint: `https://${process.env.R2_ENDPOINT}`,
      forcePathStyle: true,
    },
  })
slate gulch
#

and you have each of those envs defined on your Vercel project? I know you mentioned env above, just double checking all the simple things first

loud hare
slate gulch
#

Ok, if you go to a media item in payload and hover the name what does the URL look like

loud hare
#

Currently it seems my admin panel is down in production, when I spin it up on local host the url is localhost:3000/api/media/file/<image-file>

slate gulch
#

aha

#

Did you upload those files before you enabled the s3 plugin?

#

also what images specifically are not being found in production?

loud hare
#

It is possible, I've been working on this project for a couple months now. I can confirm the images are in the R2 Bucket, however.

#

Currently no images are being found in prod

slate gulch
#

Ok two things:

  1. Is your bucket set to private or public right now? If private, you need to set it to public-this is what gives you the *.r2.dev URL to use as R2_PUBLIC_URL
  2. Add this into your media config under disableLLocalStorage

generateFileURL: ({ filename }) => https://${process.env.R2_PUBLIC_URL}/${filename},

loud hare
#

Public access is currently disabled, let me change it and I'll check back

#

Cloudflare is providing me a warning that this link is not intended for production use

loud hare
#

Or would I use the S3 API url provided by Cloudflare?

slate gulch
#

Yes (to your first question) so it should look like this:

  enabled: true,
  clientUploads: true,
  collections: {
    media: {
      disableLocalStorage: true,
      generateFileURL: ({ filename }) =>
        `https://${process.env.R2_PUBLIC_URL}/${filename}`,
    },
  },
  bucket: process.env.R2_BUCKET || '',
  config: {
    credentials: {
      accessKeyId: process.env.R2_ACCESS_KEY_ID || '',
      secretAccessKey: process.env.R2_SECRET_ACCESS_KEY || '',
    },
    region: 'auto',
    endpoint: `https://${process.env.R2_ENDPOINT}`,
    forcePathStyle: true,
  },
})```

with these ENVs:

```R2_BUCKET=my-bucket
R2_ACCESS_KEY_ID=...
R2_SECRET_ACCESS_KEY=...
R2_ENDPOINT=<account-id>.r2.cloudflarestorage.com
R2_PUBLIC_URL=media.theirdomain.com```
loud hare
#

Ok, then I think the Media issue should be resolved. I think I'll have to open a new issue, however as my local deployment is showing up without styling and when I pushed my changes to my preview branch, Vercel logs are showing a build error:

Failed to compile.
Type error: Type 'typeof import("/vercel/path0/src/app/(frontend)/next/preview/route")' does not satisfy the constraint 'RouteHandlerConfig<"/next/preview">'.
  Types of property 'GET' are incompatible.
    Type '(req: { cookies: { get: (name: string) => { value: string; }; }; } & Request) => Promise<Response>' is not assignable to type '(request: NextRequest, context: { params: Promise<{}>; }) => void | Response | Promise<void | Response>'.
      Types of parameters 'req' and 'request' are incompatible.
        Type 'NextRequest' is not assignable to type '{ cookies: { get: (name: string) => { value: string; }; }; } & Request'.
          Type 'NextRequest' is not assignable to type '{ cookies: { get: (name: string) => { value: string; }; }; }'.
            The types returned by 'cookies.get(...)' are incompatible between these types.
              Type 'RequestCookie | undefined' is not assignable to type '{ value: string; }'.
                Type 'undefined' is not assignable to type '{ value: string; }'.
Next.js build worker exited with code: 1 and signal: null
 ELIFECYCLE  Command failed with exit code 1.
Error: Command "pnpm run build" exited with 1
timber masonBOT
slate gulch
#

Glad we got that sorted out! If this pops up again, let me know!