Widget and Secure URLs

When the Authenticated URLs option is enabled, a widget will not be able to show image previews because it's unaware of your tokens. So, you will need a widget to proxy requests through your proxy backend.

Without using the Authenticated URLs option, your widget loads images directly from our CDN:

-> (GET) https://ucarecdn.com/{uuid}/

Enabling the Authenticated URLs option requires your widget to load images through your proxy backend:

-> (GET) https://domain.com/preview?url=https%3A%2F%2Fcdn.domain.com%2F{uuid}%2F
-> (Redirect) https://cdn.domain.com/{uuid}/?token={token}&expire={expire}

The behavior described above is provided by the two widget options: previewProxy and previewUrlCallback. Depending on your use case, you can implement one or another.

Option previewProxy

Just specify a URL for your proxy backend endpoint. For instance:

UPLOADCARE_PREVIEW_PROXY = 'https://domain.com/preview?'

Your widget will now load image previews via the following URL:


As you can see, it simply appends a query parameter with the image preview URL to your previewProxy option, i.e.:

newPreviewUrl = previewProxy + 'url={previewUrl}'

By default widget uses url as the query parameter name. However, it is smart enough to detect parameters passed with some different naming, e.g.:

'https://domain.com/preview?' + 'url={previewUrl}'
'https://domain.com/preview?foo=bar' + '&url={previewUrl}'
'https://domain.com/preview?foo=bar&myUrl=' + '{previewUrl}'

The option suits the following use cases:

  • Your application uses cookie-based auth
  • Your proxy backend is located in the same domain as your app (otherwise cookies will not be sent)
  • You don't need any other image-related data beside URLs

However, if you do want to send extra data to your Proxy backend, you should use previewUrlCallback instead. JWT tokens or image metadata are good examples of those extras.

Option previewUrlCallback

In case you want full control over the widget preview URLs, go with the previewUrlCallback option. The setting should hold the function with a signature like:

(previewUrl, fileInfo) => previewUrl


UPLOADCARE_PREVIEW_URL_CALLBACK = function(previewUrl, fileInfo) {
    const jwtToken = getJWTToken()
    return `https://domain.com/preview?` +
      `url=${encodeURIComponent(previewUrl)}&` +
      `uuid=${fileInfo.uuid}&` +

When you specify previewUrlCallback, option previewBase will be ignored. So you should use one of them, not both.

Proxy backend

Your Proxy backend is just an API endpoint of your application.

It should be capable of doing the following:

  • Accept escaped preview URL as GET parameter
  • Check user authorization
  • Generate expired access tokens for that URL
  • Append access tokens to the URL
  • Send redirect to that URL

Those were the basic steps, you can extend the list if you want.

Don't forget to check user credentials on your backend. Make sure not to authenticate anonymous user requests, unless you want to.


Here is the simple example of a proxy backend on Node.js.

app.get('/preview', (req, res) => {
  const url = req.query.url
  const user = req.user

  if (!user) {
    res.status(403).send('Authorization failed')

  const expire = Math.round(Date.now() / 1000) + 120
  const token = generateToken(url, expire)

  const secureUrl = url + `?token=${token}&expire=${expire}`


We’re always happy to help with code, integration, and other stuff. Search our site for more info or post your question in our Community Area.