Upload Widget

Cloudinary's upload widget is a complete, interactive user interface that enables your users to upload files from a variety of sources to your website or application. The widget, requiring just a couple lines of code to integrate, eliminates the need to develop in-house interactive media upload capabilities.

Important

  • Cloudinary supports only the documented configuration and the supplied files with the widget. Any direct changes to the widget code and its elements (for example, CSS and JS files) might break its functionality, and will not be supported.
  • The previous version of the upload widget has been deprecated and support for that version will be withdrawn in the near future. For information on the previous version of the upload widget, see the Upload widget v1.x documentation. See this KB Article for more information on migrating to the current version of the upload widget.

Upload widget main screen

The upload widget responsively resizes to fit in the available width, with the display functionality automatically adjusting on-the-fly for use in mobile applications.

Upload widget main screen

The widget offers uploading from a variety of sources: your local device, remote URL, the computer or mobile device camera, Google image search, and social media accounts including Dropbox, Instagram, Shutterstock, Google Drive, or Facebook. The widget supports drag & drop functionality, interactive cropping, upload progress indication, and thumbnail previews. The widget also monitors and handles uploading errors and offers extensive event handling for integrating your own code.

You can implement the widget for unsigned uploading directly from the browser to Cloudinary storage, without involving your servers in the process. The widget sends JavaScript callbacks on successful uploads, so you can integrate the upload process back into your existing media pipeline. You can additionally configure Cloudinary to send server-side callbacks. Advanced users can also use the upload widget with signed uploads for a more secure process when required.

Once uploaded, images and videos can be resized, cropped and manipulated by Cloudinary on-the-fly so they can be embedded as needed in your website or mobile app.

The upload widget requires only pure JavaScript to integrate and is easy to use within any web development framework.

Quick example

To use Cloudinary's upload widget in your site with unsigned uploads, include the widget's remote JavaScript file and then specify the following (minimum) information when calling the createUploadWidget method to initialize the widget:

  • Your Cloudinary account cloud name
  • The upload preset to use for uploading files to your account

Once initialized, the widget is ready to be rendered when needed. The following sample includes code for binding to the click event of a button element in a web page, in order to call the widget's open method and display the initialized widget:

Copy to clipboard
<button id="upload_widget" class="cloudinary-button">Upload files</button>

<script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script>  

<script type="text/javascript">  
var myWidget = cloudinary.createUploadWidget({
  cloudName: 'my_cloud_name', 
  uploadPreset: 'my_preset'}, (error, result) => { 
    if (!error && result && result.event === "success") { 
      console.log('Done! Here is the image info: ', result.info); 
    }
  }
)

document.getElementById("upload_widget").addEventListener("click", function(){
    myWidget.open();
  }, false);
</script>

You can try out this simple upload widget example by clicking the button below:

The following buttons were implemented with a few additional parameters to demonstrate additional capabilities.

These and many additional options are described on the rest of this page.

How to setup and integrate the upload widget into your site or app.

For most needs, you can set up the upload widget for unsigned uploads. Using unsigned uploads with your widget makes it quick and simple for you to provide a UI where users can upload content to your site.

Signed uploads require a bit more setup and coding, but provide a more secure upload process when required.

Tip
You can use the Cloudinary CLI to generate the basic code for an upload widget:

Copy to clipboard
cld make upload_widget

Unsigned uploads

Unsigned uploads are somewhat less secure than signed uploads. For example, it is possible for a customer to inspect your client-side HTML code to find your cloud name and preset, and use that information to upload unwanted files to your account. For this reason, unsigned uploads have some protective limitations. For example, existing assets cannot be overwritten. The options you set in the unsigned preset can also limit the size or type of files that users can upload to your account using that preset.

To setup and add an upload widget for unsigned uploads:

  1. Include the cloudinary widget JavaScript file in your web page:
    https://widget.cloudinary.com/v2.0/global/all.js

    For example:

    Copy to clipboard
    <script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript">  
    </script>

    Note

    If you want to support Internet Explorer 11, don't use any shortcut arrow functions (=>) in your code and include a relevant fallback polyfill script such as:

    Copy to clipboard
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min.js"></script>

  2. Optional. Set your cloud name globally. If you include multiple widgets in your web page, you can use the setCloudName method to instruct all widgets on the page to upload to your Cloudinary account. Alternatively, you can set the cloud name as a parameter of each widget creation call.

  3. Create an unsigned upload preset. In the Upload settings of the Cloudinary console, create a new, unsigned upload preset. This preset serves as a form of security override, allowing client-side unsigned uploads. You supply the preset name in your widget creation call.
    If you've never created an unsigned preset, you must first select to enable unsigned uploading. When you do this, an empty upload preset is automatically created for you. Alternatively, you can create an unsigned upload preset using the Admin API.
    You can optionally edit the preset to modify its name or apply any of the available upload options, such as applying incoming transformations to control the size or type of asset users can upload using your widget, or to automatically generate certain eager transformations on all uploaded assets. For details, see Upload presets.

  4. Add your widget. Use one of the widget initialization methods to create your widget. When you call the method, you specify the uploadPreset that you created in the previous step, your cloudName (if you did not set it globally), and any additional widget options you want to apply.
    For example, in the demo example earlier on this page, the createUploadWidget method call includes the cropping option, which enables users to define cropping coordinates, and the folder option, which uploads all images from the widget to a specified folder:

    Copy to clipboard
    var myCropWidget = cloudinary.createUploadWidget({
      cloudName: 'demo', uploadPreset: 'preset1', folder: 'widgetUpload', cropping: true}, 
      (error, result) => { console.log(error, result) })

Signed uploads

Instead of providing an upload preset name, you initialize the widget for signed uploads with the public API key and an upload signature that is generated either when the page is loaded or when the upload request is submitted.

To setup and implement the upload widget for signed uploads:

  1. Follow steps 1-2 above.

  2. Optional. Create a signed upload preset. When you use the upload widget for signed uploads, an upload preset is not necessary. But you can optionally create a signed preset if you want to define incoming or eager transformations on the uploaded image. Define the preset as described in Upload presets and supply the preset name in the uploadPreset option when you call the widget creation method.

  3. Select string or function as the upload_signature type and prepare the required code.

    • String:

      • Requires your page to connect to the web server on page load to generate the signature.
      • Requires that all parameters required for signing are known at page load time. If user-input will affect the parameters, for example, if you are using the widget's interactive cropping option, then you must use the function option.
      • The signature is valid for one hour from the timestamp used in the signature. If a user keeps the page open for a long time, the signature string may expire.
      • The signature string you provide must be generated from all parameters used, including 'source=uw' (this is a hidden parameter sent automatically by the upload widget, but must still be included in the string to sign). For example, a string to sign might look like: 'source=uw&timestamp=155307631&upload_preset=myPreset'.

      For details on generating the signature string, see Generating authentication signatures.

    • Function:

      • Requires you to create a function to generate the signature.
      • The function runs when the upload request is submitted, therefore, the timestamp does not risk expiring if the user keeps the page open.
      • The function receives the final parameters of the upload, including any parameters impacted by user interaction.

        Sample function:
        The following is an example of a function that uses a server-side endpoint to generate the signature.

        Copy to clipboard
          <script type="text/javascript">
            var generateSignature = function(callback, params_to_sign){
              $.ajax({
               url     : https://www.my-domain.com/my_generate_signature",
               type    : "GET",
               dataType: "text",
               data    : { data: params_to_sign},
               complete: function() {console.log("complete")},
               success : function(signature, textStatus, xhr) { callback(signature); },
               error   : function(xhr, status, error) { console.log(xhr, status, error); }
              });
            }
          </script>

    Important
    You must use the timestamp value provided by the widget (passed in params_to_sign) and not create your own timestamp value.

  4. Add your widget. Use one of the widget initialization methods to create your widget. When you call the method, you specify your cloudName (if you did not set it globally), the uploadSignature string or function, the uploadSignatureTimestamp (for string signatures only), and any additional widget options you want to apply.
    For example, the applyUploadWidget method creates the upload widget and calls the signature function shown in the previous step:

    Copy to clipboard
    cloudinary.applyUploadWidget(document.getElementById('upload_widget_opener'), 
      { cloudName: "demo", uploadSignature: generateSignature }, (error, result) => { });

Third-party upload sources

In addition to the 'My Files', 'Web Address', and 'Camera' sources, the upload widget supports a variety of third-party upload sources from which your users can upload images and videos. The sources are presented on multiple tabs (web) or options (mobile/responsive) for your users, so they can select the relevant source, browse through their files and select the ones they want to upload.

Upload widget sources

Note
When there are more than 8 options for sources, the menu tabs are replaced by a collapsible side menu:

Upload widget sources

The sources parameter

The sources parameter accepts an array of string values defining the source options to add to the upload widget, where each source defines a new upload tab or source option within the widget. The sources parameter can be included in the method used for creating the upload widget, and is only specified when you want to limit the available sources (all sources are added by default if this parameter is omitted). The possible values for the sources parameter are as follows:

Value Description
local Upload a file from your local device. Adds the My Files source option.
url Upload a file from a remote location. Adds the Web Address source option.
camera Upload an image file via the device's camera. Adds the Camera source option.
Notes:
- Desktop/laptop only - a mobile device's camera is accessed through the local (My Files) source option.
- Unavailable on Safari browsers which block the camera when used in an iFrame.
dropbox Upload a file from your Dropbox account. Adds the Dropbox source option.
image_search Upload a file from the web using Google's Search Engine. Adds the Image Search source option.
facebook Upload an image from a Facebook account. Adds the Facebook source option.
instagram Upload an image from an Instagram account. Adds the Instagram source option.
shutterstock Upload an image from a Shutterstock account. Adds the Shutterstock source option.
google_drive Upload a file from a Google Drive account. Adds the Google Drive source option.

Image Search source

The image_search option allows your users to select images from the web using your Google Custom Search account, and then upload them to your Cloudinary account. The search can be optionally confined to specific sites (e.g., your own website) and can be filtered by specified licensing criteria.

Image Search option

Important
To enable this search option, you must obtain an API Key from Google. The API Key is free to use within certain search rate limits, and there are various large scale commercial options as well. To enable Google Custom Search and generate your API Key see https://developers.google.com/custom-search/json-api/v1/overview.

To enable the image_search option, add the following parameters to the method you use for creating the upload widget:

  • sources (Array of strings) - Optional. If you add this parameter to limit the available options, make sure to include the image_search option.
  • googleApiKey (String) - The API key for your Google Custom Search account.
  • searchBySites (Array of Strings) - Optional. The domain names of sites you want to allow for the search. If more than one site is specified then a Search by Site dropdown will be added, so your users can select the site to search. To allow searching the entire web, use the value all. Default value: all
  • searchByRights (Boolean) - Optional. Set to true to add a dropdown box so that users can select a licensing filter to apply to the image search. Default value: false.

Basic example:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'image_search'],
  googleApiKey: 'AIrFcR8hKiRo' }, (error, result) => { });

Example with sites filter and rights filter:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'image_search'],
  googleApiKey: 'AIrFcR8hKiRo',
  searchBySites: ["all", "cloudinary.com"],
  searchByRights: true }, (error, result) => { });

Image Search select

Dropbox source

The dropbox option allows your users to login to their own Dropbox account, browse through their folders and files, and then select the files to upload to your Cloudinary account. This option requires that the upload widget is embedded in a secure (HTTPS) page because the user sign-in to Dropbox must be over a secure connection.

To enable this upload option for your users, you must obtain an App key from Dropbox:

  1. Create a new app on the Dropbox App Console: Click My apps, select the Dropbox API and Full Dropbox options, name your app, and click the Create app button.
  2. On the next page, set the following redirect URI for your Dropbox application: https://widget.cloudinary.com/v2.0/global/auth/index.html
  3. Copy the auto-generated App key for your Dropbox app: this will be configured as the value of the dropboxAppKey parameter when including Dropbox as an upload source in the upload widget (see below).
  4. Your Dropbox app is initially created in Development status for testing purposes. You can enable additional users with the Enable additional users button, and when your app is ready to go live, you need to click on the Apply for Production status to enable all your users to upload via the Dropbox app.
  5. For more information on creating Dropbox apps, see their documentation and take note of their branding guidelines.

Dropbox source Dropbox login

To enable the Dropbox source, add the following parameters to the method you use for creating the upload widget:

  • sources (Array of strings) - Optional. If you add this parameter to limit the available options, make sure to include the dropbox option.
  • dropboxAppKey (String) - The App key to your Dropbox App.

For example:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'dropbox'],
  dropboxAppKey: '1dsf42dl1i2' },  (error, result) => { });

Facebook source

The facebook option allows your users to login to their own Facebook account, browse through their photos (photos they have uploaded, photos they are tagged in, or albums they have created) and then select the images to upload to your Cloudinary account.

Facebook source Facebook login

To enable the Facebook source, add the following parameters to the method you use for creating the upload widget:

  • sources (Array of strings) - Optional. If you add this parameter to limit the available options, make sure to include the facebook option.
  • facebookAppId (String) - Optional. The App ID of your own application for accessing your users' Facebook accounts. If not provided, uses the Cloudinary Media Upload app.

For example:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'facebook'],
  facebookAppId: '2dds35jdw21' }, (error, result) => { });

Instagram source

The instagram option allows your users to login to their own Instagram account, browse through their photos, and then select the images to upload to your Cloudinary account.

Instagram source

To enable the Instagram source, add the following parameters to the method you use for creating the upload widget:

  • sources (Array of strings) - Optional. If you add this parameter to limit the available options, make sure to include the instagram option.
  • instagramClientId (String) - Optional. The App ID of your own application for accessing your users Instagram accounts. If not provided, uses the Cloudinary Media Upload app.

For example:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'instagram'],
  instagramClientId: 'd7aadf962m' }, (error, result) => { });

Shutterstock source

The shutterstock option allows your users to log in to their own Shutterstock account, browse the assets and then select the ones to upload to your Cloudinary account. If they have not yet purchased the Shutterstock asset they select, they can purchase it as part of this process.

Shutterstock login

To enable the Shutterstock source, add the following parameter to the method you use for creating the upload widget:

  • sources (Array of strings) - Optional. If you add this parameter to limit the available options, make sure to include the shutterstock option.

For example:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'shutterstock']}, (error, result) => { });

Google Drive source

The google_drive option allows your users to login to their own Google Drive account, browse through their files and then select the files to upload to your Cloudinary account.

Google Drive source

To enable the Google Drive source, add the following parameters to the method you use for creating the upload widget:

  • sources (Array of strings) - Optional. If you add this parameter to limit the available options, make sure to include the google_drive option.
  • googleDriveClientId (String) - Optional. The Client ID of your own Google Drive application for accessing your users' Google Drive accounts. If not provided, uses the Cloudinary Google Drive app.

For example:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  sources: [ 'local', 'url', 'google_drive'],
  googleDriveClientId: '1wsds35jrt34dsssw21' }, (error, result) => { });

Note

The Google Drive source is not supported by either Internet Explorer 11 or by Safari browsers.

API events

The upload widget methods include a callback function for implementing event handling. The callback has the following signature: function(error, result), where error is either null if successful or an error message if there was a failure, while result is a JSON object detailing the triggered event.

For example, to log a message to the console when a user clicks the 'show completed' button:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  showCompletedButton: true,  
  }, (error, result) => {
    const eventData = result.data;
    if (eventData.event === "show-completed") {
      eventData.info.items.forEach((item) => {
        console.log(`show completed for item with id: 
        ${item.uploadInfo.public_id}`); //uploadInfo is the data returned in the upload response
      });
    }
});

For a full listing of available events, see the Events section in the Upload Widget API reference.

Pre-batch validation

If you need to run any validation on the files in the upload queue before they are uploaded to your Cloudinary account, you can set the preBatch parameter with a function to run beforehand. If the code in your function determines that the upload should be canceled, you can include the cancel boolean parameter set to true when calling the callback function.

For example, to cancel the upload if the file name is 'TopSecret':

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  preBatch: (cb, data) => {
    if (data.files[0].name === "TopSecret") {
      cb({cancel: true}); 
    },
    else { 
      cb(); 
    }
  }, (error, result) => { });

Prepare upload parameters

If you need to do any preparation on the files in the upload queue before they are uploaded to your Cloudinary account, you can set the prepareUploadParams parameter with a function to run beforehand. Use this function to prepare any upload parameters you might need, such as to specify tags or metadata for each file, or even prepare an upload signature for a signed upload, as in the following example:

Copy to clipboard
cloudinary.openUploadWidget({
  upload_preset: "preset1",
  cloud_name: "demo",
  prepareUploadParams: (cb, params) => {
    params = [].concat(params);  //params can be a single object or an array of objects
    Promise.all(params.map((req) =>
      makeAjaxRequest("https://mysite.example.com/prepare", req)
        .then((response) => Object.assign({
          signature: response.signature,
          api_key: response.api_key,
        }, response.upload_params))
    ))
      .then((results) =>
        cb(results.length === 1 ? results[0] : results));
  }
}, (error, result) => { });

Note
If the prepareUploadParmas parameter is included then the uploadSignature parameter is ignored. If you also need to provide a signature, make sure to include that code in your prepareUploadParams function and pass the signature as part of the data passed to the callback (cb).

Tagging suggestions

You can add tagging suggestions that appear while your users are typing in the Add a Tag (Advanced options) text field, by providing a function that is called whenever the text changes in the field. Your function should call the callback function with the list of tagging suggestions to display. Add the getTags parameter with the function to call, and make sure to also set the showAdvancedOptions parameter to true.

The following example demonstrates a mini auto-complete function that returns only suggestions matching the current text entered in the field:

Copy to clipboard
const tags = ["extract", "amazing", "apple", "dog", "grass", "planes", "rocket", "rock", "movies", 
  "music", "sad", "light", "open", "mosaic", "entertainment", "test", "testament", "beach", 
  "vacation", "weather", "letter", "orchard"];
const getMyTags = (cb, prefix) => cb(prefix ? tags.filter((t) => !t.indexOf(prefix)) : tags);

cloudinary.openUploadWidget({
  cloudName: "demo", 
  uploadPreset: "preset1",
  showAdvancedOptions: true,        
  getTags: getMyTags, //provide callback to retrieve tagging suggestions
  }, (error, result) => { });

Upload preset selection

You can offer your users an additional Advanced option with a selection of Upload Presets to choose from, by providing a function that is called to provide the list of presets to offer. Your function should call the callback function with the list of tagging suggestions to display. Add the getUploadPresets parameter with the function to call, and make sure to also set the showAdvancedOptions parameter to true.

The following example demonstrates a upload preset selection function that returns 3 presets:

Copy to clipboard
const presets = ["signed", "video", "eager"];
const getMyUploadPresets = (cb) => cb(presets);

cloudinary.openUploadWidget({
  cloudName: "demo", 
  uploadPreset: "preset1",   // default preset
  showAdvancedOptions: true,
  getUploadPresets: getMyUploadPresets
  },  (error, result) => { });

Look and feel customization

The look & feel of the upload widget can be fully customized. You can modify the colors, fonts, and other elements by providing your own customization.

Custom styling is specified using the styles parameter, which accepts a JSON structure defining the default elements to override. Styles are further divided as follows:

  • palette for defining the colors of the various elements as an RGB or RGBA hex triplet or quadruplet, or a 3- or 4-digit RGB/RGBA hex.
  • fonts for defining the font to use for all the text elements. Currently the widget only supports fonts from Google (available via fonts.googleapis.com).

The following example sets all elements to their default values (for reference purposes) - in practice you only need to include the elements you want to override:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  styles:{
    palette: {
      window: "#FFF",
      windowBorder: "#90A0B3",
      tabIcon: "#0E2F5A",
      menuIcons: "#5A616A",
      textDark: "#000000",
      textLight: "#FFFFFF",
      link:  "#0078FF",
      action:  "#FF620C",
      inactiveTabIcon: "#0E2F5A",
      error: "#F44235",
      inProgress: "#0078FF",
      complete: "#20B832",
      sourceBg: "#E4EBF1"
    },
    fonts: {
        "'Cute Font', cursive": "https://fonts.googleapis.com/css?family=Cute+Font",
    }
  }, (error, result) => { });

Tip
Use the Upload Widget Demo page to visualize the upload widget customization options, and when you are happy with the colors you have selected, Copy the palette customization code to the clipboard.

Localization

The text used in the upload widget can be fully customized for different languages. The translations for each language are specified using the text parameter, which accepts a JSON structure defining the value to use for each text element in each language. The language parameter sets which of the language options to use from those defined in the text parameter (en by default). To override any of the default values, you only need to include the elements you want to override.

All the default values can be found at: https://widget.cloudinary.com/v2.0/global/text.json.

For example, to only customize the queue title, queue title_uploading_with_counter, and the crop title:

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  language: "en",  
  text: {
    "en": {
        "queue": {
            "title": "Files to upload",
            "title_uploading_with_counter": "Uploading {{num}} files"
        },
        "crop": {
            "title": "Crop your image"

        }
    }
  }
}, (error, result) => { });

Note
Elements that support a variable value (specified inside double braces {{...}}) are replaced with the actual value at runtime. Only the elements that already contain the double braces in the default localization file support variables.

Encryption

Files can be encrypted and then uploaded to Cloudinary as raw files. These files cannot be previewed within Cloudinary and will need to be decrypted after downloading them. To add this feature to the upload widget, add the encryption parameter and include an encryption key and initialization vector (key and iv). For example

Copy to clipboard
cloudinary.openUploadWidget({
  cloudName: "demo", uploadPreset: "preset1",
  encryption: {
    key: "ff234fe526725753fa45b53325", 
    iv: "cd8a46d72e26a365dca78ef"
  }
}, (error, result) => { });

Upload widget reference

For details on all the available methods, parameters and events, see the Upload Widget reference.

✔️ Feedback sent!