File uploader

Here you can find a set of ready-made uploaders for the most frequent file uploading use-cases. Each uploader is highly customizable on its own and could be used as a custom build reference, or you can use it as is.

On this page you'll find



💎 Solution benefits

🌎 Supported browsers

Blocks are supported and tested in all major modern desktop and mobile browsers:

Internet Explorer is outdated and not supported anymore.

Regular uploader


Inline uploader


Minimalistic uploader


🛠 Configuration


All configurations, localization texts, icons, and styling are placed into CSS file (if you aren't familiar with this concept, read about blocks configuration), so you should connect the default one (or create your own):

  @import url(;
  .my-settings {
    --ctx-name: 'my-uploader';
    --cfg-pubkey: 'demopublickey';

<lr-uploader class="my-settings lr-wgt-common"> </lr-uploader>

There are two major parameters you should know:

  1. Your Uploadcare's project public key: --cfg-pubkey: 'YOUR_PUBLIC_KEY';.
  2. Workflow context name: --ctx-name: 'CONTEXT_NAME';.

Public key

You should get a Public API Key in your Uploadcare project's dashboard to use file uploading features.

For demo-only purposes, you can use demopublickey instead.

Context name

Our concept of workflow contexts is very similar to native HTML name attributes for the "radio" inputs. When you use the same names, elements act in one common context. In the case of "radio" inputs, all elements in the same context will know the state of the others (and you can make only one possible selection).

In the case of uploader, you can also set the context with a ctx-name attribute or --ctx-name custom CSS property. This helps to create the link between each uploader instance and its internal or external entities. By default, context is created automatically, but if you need to bind uploader to some other workflow, you can use the following approach:

<lr-uploader ctx-name="my-uploading-workflow"></lr-uploader>
<lr-data-output ctx-name="my-uploading-workflow"></lr-data-output>

For more information, read about "context" in Symbiote.js documentation.

CSS custom properties

All configurations could be provided via the set of CSS-variables:

.my-settings {
  --cfg-pubkey: 'demopublickey';
  --cfg-multiple: 1;
  --cfg-img-only: 0;
  --cfg-source-list: 'local, url, camera, dropbox, gdrive, facebook';

The variable value should be a correct JSON value. Strings should be taken in quotes. We use the 1 or 0 numbers to define boolean flags.

Any configuration value can be defined and redefined at any DOM-tree level regarding CSS selector specificity.

Parameters description

Name Description Values Default
--cfg-pubkey Your project Public Key string YOUR_PUBLIC_KEY
--cfg-multiple Allow to upload multiple files 1 or 0 1
--cfg-multiple-min Minimum number of files that can be selected number none
--cfg-multiple-max Maximum number of files that can be selected number none
--cfg-confirm-upload Enables user confirmation for upload starting 1 or 0 1
--cfg-img-only Accept images only 1 or 0 0
--cfg-accept Native file input accept attribute value comma separated string none
--cfg-external-sources-preferred-types Defines the list of preferred MIME types for external sources. See docs for details comma separated string none
--cfg-store Store files 1 or 0 -
--cfg-camera-mirror Flip camera image 1 or 0 0
--cfg-source-list Comma-separated list of file sources. See available sources below comma separated string` 'local, url, camera, dropbox, gdrive'
--cfg-max-local-file-size-bytes Maximum file size in bytes number none
--cfg-thumb-size Image thumbnail size 76 76
--cfg-show-empty-list Show uploads list when it's empty 1 or 0 0
--cfg-use-local-image-editor Enable local image editing 1 or 0 0
--cfg-use-cloud-image-editor Enable cloud image editing 1 or 0 0
--cfg-remote-tab-session-key Key to revoke Custom OAuth access. See docs for details string none
--cfg-cdn-cname Set Custom CNAME. See docs for details string ''
--cfg-base-url Set custom upload URL string ''
--cfg-secure-signature Set signature for Secure Uploads. See docs for details string none
--cfg-secure-expire Set expire for Secure Uploads. See docs for details string none
--cfg-secure-delivery-proxy Set proxy URL template for Secure Delivery. See here for details string none
--cfg-group-output Enables files group creation 1 or 0 0
--cfg-remove-copyright Remove copyright 1 or 0 0



.my-configuration {
  --cfg-source-list: 'url, local, instagram';


The parameter can be used with signed URLs. Defines template for your proxy backend URL.

This is replacement for the File Uploader v3 previewProxy option.

NOTE: There is no replacement for File Uploader v3 previewUrlCallback option. If you need such functionality, please create a feature request.

Value for --cfg-secure-delivery-proxy is a string template with the following variables:

That means that you can use {{previewUrl}} in your template to insert the URL of file to proxify.


.my-configuration {
  --cfg-secure-delivery-proxy: '{{previewUrl}}';

CSP settings

If the application works with sensitive user data (e.g personal photos), it is recommended to increase its security with CSP settings. Uploader is using Blob URLs for on-the-flight generated images and the stylesheets in some cases, so don't forget to add blob: source into the CSP settings:

  content="style-src 'self' blob:; script-src 'self'; img-src 'self' blob:;"

🎀 Styling

For the look & feel customization, you can use the "Elements" section in your browser developer tools panel. It's easy to find any uploader inner components and their contents because they have custom tag names. You don't need any specific tools, unlike with libraries like React. These tag names could be used as convenient CSS selectors.

There are three major levels of possible styling customizations:

  1. Light and dark theme flag: --darkmode:1; (enabled) or --darkmode:0; (disabled).
  2. The set of basic CSS variables used for the other styling calculations.
  3. Custom CSS rules for each element.

Basic theme for blocks

There are 4 levels of abstraction:

HSL color space

We use HSL color space because it allows us to easily calculate derivative colors. That's what prefixes --h-, --s-, and --l- are stand for.

Quick styling

In most cases switching the dark mode on or off and changing the accent color is enough to make block match your design.

--darkmode: 1;
--h-accent: 211;
--s-accent: 100%;
--l-accent: calc(50% - 5% * var(--darkmode));

Base values

Derivative values

Derivative values are calculated from the base values.

Common styles

Common styles define similar UI elements across different blocks: buttons, inputs, and links.

Component styles

Component styles are the most specific.

Shadow DOM

If you need additional isolation and styling security levels, you can get it with Shadow DOM. To enable it and encapsulate all styles into separated scope, use the css-src attribute:

<lr-uploader css-src="">

ðŸŠĪ Data handling

With the data output

We provide the dedicated block for the data output purposes — <lr-data-output>. This Custom Element can be connected to some workflow context and provide you with convenient data access.

Here is the code example:

<template id="output-template">
  <h3>Files uploaded:</h3>
  <div repeat="filesData">
    <lr-img width="300" set="@uuid: uuid"></lr-img>
    <div><a set="@href: cdnUrl">{{cdnUrl}}</a></div>
<lr-data-output use-console use-event use-template="#output-template"> </lr-data-output>

Let's walk through its attributes:

With the event listener

window.addEventListener('LR_DATA_OUTPUT', (e) => {

ðŸ”Ĩ Events

Upload flow events

You can catch all events in window scope:

window.addEventListener('LR_UPLOAD_START', (e) => {

To define what exact workflow caused an event, use the context name:

<lr-file-uploader-regular ctx-name="UPLOADER_1"></lr-file-uploader-regular>
<lr-file-uploader-regular ctx-name="UPLOADER_2"></lr-file-uploader-regular>
window.addEventListener('LR_UPLOAD_START', (e) => {
  if (e.detail.ctx === 'UPLOADER_1') {
    console.log('Uploading started in the FIRST uploader instance.',;
  } else if (e.detail.ctx === 'UPLOADER_2') {
    console.log('Uploading started in the SECOND uploader instance.',;


Activity is a current user interaction stage focused on the uploader application. It helps manage the visibility of components and switches between several UI states. To create an activity, you should register it in your custom block:

import { LR } from '@uploadcare/blocks';

class MyBlock extends LR.BlockComponent {
  initCallback() {
    const onActivate = () => {
      console.log('activity-name is activated');
    const onDeactivate = () => {
      console.log('activity-name is deactcivated');
    this.registerActivity('my-activity-name', {

Then, if some other component will call the registered activity, it will be activated with an active attribute, and the activation callback will be called.


import { LR } from '@uploadcare/blocks';

class MyOtherBlock extends LR.BlockComponent {
  onclick = () => {
    this.$['*currentActivity'] = 'my-activity-name';

Resulting HTML:

<lr-my-block activity="my-activity-name" active>...</lr-my-block>

Then you can use lr-my-block[active] selector to specify visibility or animations with CSS.

Here is the list of reserved pre-defined activities: