Use record ID instead of filename in the URL for Uploads

default discord avatar
unclaimed1052last year
2

Hello, I have a collection of Uploads that looks like this


import { CollectionConfig } from 'payload/types';

const QuestionsMedia: CollectionConfig = {
  slug: 'questions-media',
  admin: {
    // Text used as a label for grouping collection links together in the navigation.
    group: 'Media',
    useAsTitle: 'id',
  },
  access: {
    read: () => true,
  },
  labels: {singular: 'Question Media', plural: 'Questions Media'},
  upload: {
    staticURL: `/backend/media/questions`,
    staticDir: 'media/questions',
    adminThumbnail: 'thumbnail',
    mimeTypes: ['image/*'],
  },
  fields: [
    {
      type: 'text',
      name: 'alt',
      admin: {
        description: 'Descrivi brevemente cosa ci sta nell\'immagine'
      }
    }
  ],
};

export default QuestionsMedia;

To fetch images, I have to access this url

http://localhost/backend/media/questions/abc.jpg

. What I'm trying to accomplish is to make payload use the ID of the record instead of the filename inside the URL to fetch the image.


I tried to ask the payload bot, and he suggested to edit the

staticDir

like this


staticDir: 'media/questions/:id',

But this didn't work, it edited the url like this

http://localhost/backend/media/questions/:id/abc.jpg

Is there any way to change the URL to contain the ID instead of the filename? Thanks



Just a quick note, the base url to access payload looks like that because of some configuration I did with nginx, since it's part of a fullstack app im building

  • default discord avatar
    imcorfitzlast year

    Hmm... I think the problem basically is, that you in theory are doing static file serving. Therefore when requesting an asset using the ID, you actually need a DB lookup and processing on each file request, which isn't as performant.



    But... In theory you could create a custom api endpoint, and perform the id lookup to locate the file, and then set the response headers and deliver the asset in order to achieve it.



    You can also add a hook that generates a random filename for you, so the image path may not be as easy to recognise:


     hooks: {
        beforeOperation: [
          ({ operation, args }) => {
            if (operation === "create") {
              args.req.files.file.name =
                Math.random().toString(36).substring(2, 15) +
                Math.random().toString(36).substring(2, 15) +
                args.req.files.file.name.substring(
                  args.req.files.file.name.lastIndexOf(".")
                );
            }
          },
        ],
      },
  • default discord avatar
    unclaimed1052last year

    Seems like a good solution, thanks!

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.