Skip to main content

Overview

Uploadcare File Uploader is built with Web Components, making it compatible with React applications. This guide shows you how to integrate the uploader into your React projects using TypeScript.

Installation

Install the File Uploader package from npm:
npm install @uploadcare/file-uploader

Basic Setup

Step 1: Import and Define Components

Create a component to initialize the File Uploader:
App.tsx
import { useEffect, useRef } from 'react';
import * as UC from '@uploadcare/file-uploader';
import '@uploadcare/file-uploader/index.css';

function App() {
  const initialized = useRef(false);

  useEffect(() => {
    if (!initialized.current) {
      UC.defineComponents(UC);
      initialized.current = true;
    }
  }, []);

  return (
    <div>
      <uc-config
        ctx-name="my-uploader"
        pubkey="YOUR_PUBLIC_KEY"
      />
      <uc-file-uploader-regular
        ctx-name="my-uploader"
      />
    </div>
  );
}

export default App;
Replace YOUR_PUBLIC_KEY with your actual Uploadcare public key from your dashboard.

Step 2: TypeScript Support

To enable TypeScript support and JSX types for the Web Components, add the following to your component file or a types declaration file:
types.d.ts
/// <reference types="@uploadcare/file-uploader/types/jsx" />
Alternatively, add it to your tsconfig.json:
tsconfig.json
{
  "compilerOptions": {
    "types": ["@uploadcare/file-uploader/types/jsx"]
  }
}

Available Solutions

The File Uploader provides three pre-built solutions:
Full-featured uploader with modal dialog:
<uc-file-uploader-regular ctx-name="my-uploader" />
Best for:
  • Standard file upload workflows
  • Apps needing a modal interface
  • Multiple file uploads with preview

Configuration

All configuration is managed through the uc-config component. Here are common options:
<uc-config
  ctx-name="my-uploader"
  pubkey="YOUR_PUBLIC_KEY"
  multiple={true}
  img-only={false}
  source-list="local, url, camera, dropbox, gdrive"
  max-local-file-size-bytes={52428800}
/>

Key Configuration Props

PropTypeDescription
ctx-namestringContext name to link uploader and config
pubkeystringYour Uploadcare public key
multiplebooleanAllow multiple file selection
img-onlybooleanRestrict uploads to images only
source-liststringComma-separated list of upload sources
max-local-file-size-bytesnumberMaximum file size in bytes
For a complete list of configuration options, see the Configuration Reference.

Handling Upload Events

Listen to upload events using refs and event listeners:
FileUploadComponent.tsx
import { useEffect, useRef } from 'react';
import * as UC from '@uploadcare/file-uploader';
import '@uploadcare/file-uploader/index.css';

function FileUploadComponent() {
  const uploaderRef = useRef<any>(null);
  const ctxProviderRef = useRef<any>(null);

  useEffect(() => {
    UC.defineComponents(UC);

    const ctxProvider = ctxProviderRef.current;
    if (!ctxProvider) return;

    // Handle file upload success
    const handleUploadSuccess = (e: CustomEvent) => {
      console.log('File uploaded:', e.detail);
      const { uuid, cdnUrl, name } = e.detail;
      // Save file info to your state or database
    };

    // Handle file added to upload list
    const handleFileAdded = (e: CustomEvent) => {
      console.log('File added:', e.detail);
    };

    // Handle errors
    const handleError = (e: CustomEvent) => {
      console.error('Upload error:', e.detail);
    };

    ctxProvider.addEventListener('file-upload-success', handleUploadSuccess);
    ctxProvider.addEventListener('file-added', handleFileAdded);
    ctxProvider.addEventListener('upload-error', handleError);

    return () => {
      ctxProvider.removeEventListener('file-upload-success', handleUploadSuccess);
      ctxProvider.removeEventListener('file-added', handleFileAdded);
      ctxProvider.removeEventListener('upload-error', handleError);
    };
  }, []);

  return (
    <div>
      <uc-config
        ctx-name="my-uploader"
        pubkey="YOUR_PUBLIC_KEY"
      />
      <uc-file-uploader-regular
        ref={uploaderRef}
        ctx-name="my-uploader"
      />
      <uc-upload-ctx-provider
        ref={ctxProviderRef}
        ctx-name="my-uploader"
      />
    </div>
  );
}

export default FileUploadComponent;

Form Integration

Integrate the uploader with React forms:
FormWithUpload.tsx
import { useEffect, useRef, useState } from 'react';
import * as UC from '@uploadcare/file-uploader';
import '@uploadcare/file-uploader/index.css';

function FormWithUpload() {
  const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
  const ctxProviderRef = useRef<any>(null);

  useEffect(() => {
    UC.defineComponents(UC);

    const ctxProvider = ctxProviderRef.current;
    if (!ctxProvider) return;

    const handleUploadSuccess = (e: CustomEvent) => {
      setUploadedFiles(prev => [...prev, e.detail.uuid]);
    };

    ctxProvider.addEventListener('file-upload-success', handleUploadSuccess);

    return () => {
      ctxProvider.removeEventListener('file-upload-success', handleUploadSuccess);
    };
  }, []);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log('Submitted with files:', uploadedFiles);
    // Send uploadedFiles to your API
  };

  return (
    <form onSubmit={handleSubmit}>
      <uc-config
        ctx-name="my-uploader"
        pubkey="YOUR_PUBLIC_KEY"
        multiple={true}
      />
      <uc-file-uploader-regular ctx-name="my-uploader">
        <uc-form-input ctx-name="my-uploader" name="files" />
      </uc-file-uploader-regular>
      <uc-upload-ctx-provider
        ref={ctxProviderRef}
        ctx-name="my-uploader"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

export default FormWithUpload;

Custom Styling

Customize the uploader appearance using CSS variables:
App.css
uc-file-uploader-regular {
  --uc-primary-color: #007bff;
  --uc-secondary-color: #6c757d;
  --uc-border-radius: 8px;
}

Reusable Hook

Create a custom hook for cleaner integration:
useFileUploader.ts
import { useEffect, useRef } from 'react';
import * as UC from '@uploadcare/file-uploader';
import '@uploadcare/file-uploader/index.css';

interface UploadEvents {
  onUploadSuccess?: (detail: any) => void;
  onFileAdded?: (detail: any) => void;
  onError?: (detail: any) => void;
}

export function useFileUploader(events: UploadEvents = {}) {
  const ctxProviderRef = useRef<any>(null);
  const initialized = useRef(false);

  useEffect(() => {
    if (!initialized.current) {
      UC.defineComponents(UC);
      initialized.current = true;
    }
  }, []);

  useEffect(() => {
    const ctxProvider = ctxProviderRef.current;
    if (!ctxProvider) return;

    const handleUploadSuccess = (e: CustomEvent) => {
      events.onUploadSuccess?.(e.detail);
    };

    const handleFileAdded = (e: CustomEvent) => {
      events.onFileAdded?.(e.detail);
    };

    const handleError = (e: CustomEvent) => {
      events.onError?.(e.detail);
    };

    ctxProvider.addEventListener('file-upload-success', handleUploadSuccess);
    ctxProvider.addEventListener('file-added', handleFileAdded);
    ctxProvider.addEventListener('upload-error', handleError);

    return () => {
      ctxProvider.removeEventListener('file-upload-success', handleUploadSuccess);
      ctxProvider.removeEventListener('file-added', handleFileAdded);
      ctxProvider.removeEventListener('upload-error', handleError);
    };
  }, [events]);

  return { ctxProviderRef };
}
Use the hook in your components:
function App() {
  const { ctxProviderRef } = useFileUploader({
    onUploadSuccess: (detail) => console.log('Uploaded:', detail),
    onError: (detail) => console.error('Error:', detail),
  });

  return (
    <div>
      <uc-config ctx-name="my-uploader" pubkey="YOUR_PUBLIC_KEY" />
      <uc-file-uploader-regular ctx-name="my-uploader" />
      <uc-upload-ctx-provider ref={ctxProviderRef} ctx-name="my-uploader" />
    </div>
  );
}

Best Practices

1

Initialize once

Call defineComponents() only once during the app lifecycle, typically in a useEffect with empty dependencies or at the root level.
2

Use unique context names

If you have multiple uploaders on the same page, use different ctx-name values for each.
3

Clean up event listeners

Always remove event listeners in the cleanup function of useEffect to prevent memory leaks.
4

Handle errors gracefully

Implement error handlers to provide feedback to users when uploads fail.

Troubleshooting

TypeScript errors with JSX

If you see TypeScript errors about unknown elements, ensure you’ve added the JSX types reference:
/// <reference types="@uploadcare/file-uploader/types/jsx" />

Components not rendering

Make sure you’ve called defineComponents(UC) before rendering the components in the DOM.

CSS not loading

Ensure you’ve imported the CSS file:
import '@uploadcare/file-uploader/index.css';

Next Steps

Configuration

Explore all configuration options

Events API

Learn about available events

Live Examples

View complete React examples

Next.js Integration

Learn about Next.js-specific considerations

Build docs developers (and LLMs) love