Home/Blog/File uploader validation guide

File uploader validation guide

File validators let you apply specific restrictions during file uploads toย ensure quality and consistency. These validations can occur before, during, orย after the upload process.

Inย this article, youโ€™ll explore the validators that come with the Uploadcare File Uploader and build aย few custom validators for uploading files for anย e-commerce store that sells furniture.

Using these validators, you can ensure that all product images meet the required dimensions, file size, and consistency standards for the store.

Requirements for the e-commerce images

Before implementing the validators, here are the requirements your product images need toย meet:

  • Maximum file size: Limit the maximum file size toย 2ย MB toย keep load times fast and improve user experience.

  • Uniform dimensions: Ensure all images are 1080ร—1080ย pixels, giving them aย 1:1 aspect ratio and allowing clear, high-quality zooming.

  • Collection limit: Each collection ofย images for aย single product must include 3ย images (aย front, back, and side view) toย provide aย comprehensive view ofย the product.

  • Image background color: All images must have aย white background, which creates aย clean, professional look onย product pages.

Project setup

Letโ€™s set upย the File Uploader inย aย project toย implement the validators. You can add the file uploader toย your HTML page using the following code snippet.

First, import the File Uploader components:

<script type="module">
  import * as UC from 'https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@v1/web/file-uploader.min.js';
  UC.defineComponents(UC);
</script>

Next, import the File Uploader CSS:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@v1/web/uc-file-uploader-regular.min.css">

Finally, add the File Uploader components toย your HTMLย page:

<uc-config
  ctx-name="my-uploader"
  pubkey="YOUR_PUBLIC_KEY"
></uc-config>

<uc-file-uploader-regular
  ctx-name="my-uploader"
></uc-file-uploader-regular>

Replace YOUR_PUBLIC_KEY with your Uploadcare public key. This key authenticates your requests when uploading files using the File Uploader.

Types ofย validators

The File Uploader provides two types ofย validators toย ensure uploaded files meet your criteria: Built-in validators and Custom validators. Each type serves aย specific purpose and enforces different validation rules based onย your project requirements.

1. Built-in validators

The File Uploader includes predefined validators that cover the most common validation checks out ofย the box. Some ofย the built-in validators include:

  • max-local-file-size-bytes: Limits file size toย aย specified maximum. This helps optimize load times, particularly onย e-commerce platforms.

  • img-only: Restricts uploads toย images only. This ensures only images reach the e-commerce platform.

For the e-commerce project, use the built-in validators toย enforce aย file size limit ofย 2ย MB and allow only images. Update the <uc-config> component with the max-local-file-size-bytes and img-only attributes:

<uc-config
  ctx-name="my-uploader"
  pubkey="YOUR_PUBLIC_KEY"
  max-local-file-size-bytes="2000000"
  img-only
></uc-config>

With this configuration, the File Uploader only accepts image files and caps the size atย 2ย MB. This ensures all product images meet the required quality standards for the e-commerce platform.

Ifย anย uploaded file doesnโ€™t meet the specified requirements, the File Uploader displays anย error message toย the user, stating that the file isย too big.

File Uploader validation error messageFile Uploader validation error message

2. Custom validators

Custom validators let you define validation rules based onย your specific needs, such asย checking dimensions, file types, orย other custom parameters.

Custom validators are pure functions that return an error object (with a message and optional payload) if validation fails.

There are two types ofย custom validators:

  • File validator: Validates individual files.
  • Collection validator: Validates aย collection ofย files.

File validators

File validators validate individual files. Aย file validator function accepts the following parameters: entry, api, and a { signal } object.

File validators can beย synchronous (for instant checks) orย asynchronous (for intensive checks like API calls orย image analysis).

You define each validator asย aย function with the following type:

type SyncValidator = (
  file: OutputFileEntry,
  api: UploaderPublicApi
) => OutputErrorFile | undefined;

Orย asย anย object with a runOn property toย specify when the validator should run:

type ValidatorDescriptor = {
  runOn: 'add' | 'upload' | 'change';
  validator: SyncValidator | AsyncValidator;
};

The runOn property determines when the validator executes:

  • add: Runs before upload when the file isย added (use for filename orย basic checks)
  • upload: Runs after successful upload toย Uploadcare (use for image dimensions, metadata)
  • change: Runs onย add, upload, orย when editing with the Image Editor

Ifย not specified, validators default to runOn: 'change'.

Synchronous file validators

Sync validators work best for simple, instant checks that use file properties already available (like filename patterns orย file type validation).

For the e-commerce project, create aย sync validator toย ensure filenames follow aย naming convention:

const productFilenameValidator = {
  runOn: 'add',
  validator: (entry, api) => {
    if (!entry.name?.includes('product')) {
      return {
        message: `Filenames must contain 'product'`,
        payload: {
          received: entry.name,
        },
      };
    }
  },
};

const config = document.querySelector('uc-config');
config.fileValidators = [productFilenameValidator];

This validator runs when the file isย added (runOn: 'add') and checks the filename before any upload occurs. Ifย validation fails, itย returns anย error object with aย user-friendly message.

Invalid filename error messageInvalid filename error message

Asynchronous file validators

Async validators are ideal for intensive checks that require API calls, library processing, orย server-side validation. They receive an AbortSignal toย handle cancellation and timeouts.

Exampleย 1: Validate image dimensions

Toย ensure all product images are exactly 1080ร—1080ย pixels, use anย async validator that runs after upload:

const imageDimensions = {
  runOn: 'upload',
  validator: async (entry, api, { signal }) => {
    const { imageInfo } = entry.fileInfo || {};

    if (!imageInfo) {
      return;
    }

    if (imageInfo.width !== 1080 || imageInfo.height !== 1080) {
      return {
        message: 'Image width and height must be 1080px',
        payload: {
          expected: '1080x1080',
          actual: `${imageInfo.width}x${imageInfo.height}`,
        },
      };
    }
  },
};

const config = document.querySelector('uc-config');
config.fileValidators = [imageDimensions];
Dimensions validation error messageDimensions validation error message

This validator runs after upload (runOn: 'upload') because fileInfo with image dimensions isย only available after the file successfully uploads toย Uploadcare.

Exampleย 2: Verify the image contains furniture

For aย furniture e-commerce store, you want toย reject uploads that donโ€™t actually show furniture. Uploadcareโ€™s Object Recognition add-on uses AWS Rekognition toย analyze image content and return confidence-scored labels, making itย aย good fit for this kind ofย content check.

Since the Object Recognition API requires your secret key, you need toย route the check through your own backend. The validator calls your backend after upload; your backend handles the Uploadcare API calls and returns aย simple yes/no result.

Note: Object recognition isย available onย paid Uploadcare plans. Check the pricing page for details.

Start with the frontend validator. Itย runs after upload (runOn: 'upload') toย access the fileโ€™s UUID, which the Object Recognition API needs:

const furnitureValidator = {
  runOn: 'upload',
  validator: async (entry, api, { signal }) => {
    if (!entry.fileInfo?.imageInfo) {
      return;
    }

    try {
      const response = await fetch(
        `/api/check-furniture?uuid=${encodeURIComponent(entry.uuid)}`,
        { signal }
      );

      if (!response.ok) {
        // If the check fails, let the upload through rather than blocking the user
        return;
      }

      const { isFurniture, detectedLabels } = await response.json();

      if (!isFurniture) {
        return {
          message: 'Only furniture product images are accepted. Please upload an image of the furniture item.',
          payload: {
            detectedLabels,
          },
        };
      }
    } catch (error) {
      if (error.name !== 'AbortError') {
        console.error('Furniture check failed:', error);
      }
    }
  },
};

const config = document.querySelector('uc-config');
config.fileValidators = [furnitureValidator];

Onย the backend, your /api/check-furniture endpoint starts the recognition job, polls until itย completes, then checks the returned labels against aย list ofย furniture-related categories:

// Node.js / Express backend example
const FURNITURE_LABELS = [
  'Furniture', 'Chair', 'Table', 'Desk', 'Bed',
  'Couch', 'Sofa', 'Cabinet', 'Shelf', 'Bookcase',
];

app.get('/api/check-furniture', async (req, res) => {
  const { uuid } = req.query;

  const headers = {
    Accept: 'application/vnd.uploadcare-v0.7+json',
    'Content-Type': 'application/json',
    Authorization: `Uploadcare.Simple ${process.env.UPLOADCARE_PUBLIC_KEY}:${process.env.UPLOADCARE_SECRET_KEY}`,
  };

  // 1. Start the object recognition job
  const executeResponse = await fetch(
    'https://api.uploadcare.com/addons/aws_rekognition_detect_labels/execute/',
    {
      method: 'POST',
      headers,
      body: JSON.stringify({ target: uuid }),
    }
  );
  const { request_id } = await executeResponse.json();

  // 2. Poll until the job completes (with a safety cap to avoid infinite loops)
  const MAX_STATUS_CHECKS = 30;
  let status = "in_progress";
  let attempts = 0;
  let jobError = null;

  while (status === "in_progress" && attempts < MAX_STATUS_CHECKS) {
    attempts += 1;
    await new Promise((resolve) => setTimeout(resolve, 1000));

    const statusResponse = await fetch(
      `https://api.uploadcare.com/addons/aws_rekognition_detect_labels/execute/status/?request_id=${request_id}`,
      { headers }
    );

    if (!statusResponse.ok) {
      jobError = `Status check failed with HTTP ${statusResponse.status}`;
      break;
    }

    const statusBody = await statusResponse.json();
    status = statusBody.status;

    // Treat explicit error/failed statuses as terminal
    if (status === "error" || status === "failed" || statusBody.error) {
      jobError =
        statusBody.error ||
        `Object recognition job finished with status "${status}"`;
      break;
    }
  }

  if (status === "in_progress") {
    // Timed out waiting for the job to complete
    return res
      .status(504)
      .json({ error: "Timed out waiting for object recognition to finish." });
  }

  if (jobError) {
    return res.status(502).json({ error: jobError });
  }
  // 3. Fetch the file info with appdata to read the labels
  const fileResponse = await fetch(
    `https://api.uploadcare.com/files/${uuid}/?include=appdata`,
    { headers }
  );
  const fileData = await fileResponse.json();

  const labels =
    fileData.appdata?.aws_rekognition_detect_labels?.data?.Labels ?? [];
  const detectedLabels = labels.map((label) => label.Name);
  const isFurniture = FURNITURE_LABELS.some((label) =>
    detectedLabels.includes(label)
  );

  res.json({ isFurniture, detectedLabels });
});

When aย shopper uploads anย image that doesnโ€™t contain furniture, the validator displays the error message inย the File Uploader and includes the detected labels inย the payload for debugging.

Collection validators

Collection validators validate aย set ofย files. Aย collection validator function takes two parameters: collection and api. The collection parameter contains information about all the files, including their names, sizes, and types. The api parameter provides access toย the File Uploader API, which you can use toย perform additional actions orย checks.

For this example, weโ€™ll create aย collection validator that checks file names toย ensure anย uploaded product image collection contains aย front, back, and side image ofย the product. File names should include the word describing the view:

const hasAllViewAngles = (collection, api) => {
  const hasFrontView = collection.allEntries
    .some(entry => entry.isImage && entry.name.includes('front'));
  const hasSideView = collection.allEntries
    .some(entry => entry.isImage && entry.name.includes('side'));
  const hasBackView = collection.allEntries
    .some(entry => entry.isImage && entry.name.includes('back'));

  if (!hasFrontView || !hasSideView || !hasBackView) {
    return {
      message: 'Each product listing must include front, side, and back view images.',
    };
  }
};

The hasAllViewAngles validator checks whether the uploaded collection contains aย front, back, and side image ofย the product. Ifย any image isย missing, itย returns anย error message.

Toย apply the collection validator toย the File Uploader, use the following code:

const config = document.querySelector('uc-config');
config.collectionValidators = [hasAllViewAngles];

With the collection validator inย place, the File Uploader checks for the required images inย each product listing and displays anย error message ifย any are missing.

Collection validation error messageCollection validation error message

Displaying custom error messages

When you create aย custom validator, itย returns aย custom message toย display toย users when validation fails. The validator function returns anย object with a message property set toย the custom error message. The File Uploader shows this message toย the user when the validation condition isnโ€™t met.

For example, the imageDimensions validator returns anย error message ifย the image dimensions donโ€™t match the required 1080ร—1080ย pixels:

{
  message: 'Image width and height must be 1080px',
}

Localization ofย custom error messages

The File Uploader API lets you localize custom error messages ifย you already use localization inย the File Uploader, via the api parameter inย the validator function. The api parameter provides access toย the l10n function, which translates error messages into different languages.

For example, toย localize the error message for the imageDimensions validator, use the l10n function toย translate the message into different languages. Start byย importing aย localization file for the File Uploader just after importing the File Uploader components:

import es from 'https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@v1/locales/file-uploader/es.js';

Then, before calling UC.defineComponents(UC), add the following code toย define the localization for the File Uploader:

UC.defineLocale('es', {
  ...es,
  custom: {
    'image-dimensions-error': 'Las dimensiones de la imagen deben ser de 1080px',
  },
});

Next, update the uc-config component toย use the es locale:

<uc-config
  locale-name="es"
  ctx-name="my-uploader"
  pubkey="YOUR_PUBLIC_KEY"
></uc-config>

With the localization defined, use the l10n function inย the validator toย translate the error message into the specified language. For example, update the imageDimensions validator like this:

const imageDimensions = (entry, api) => {
  if (entry.fileInfo &&
     (entry.fileInfo.imageInfo.width !== 1080
     || entry.fileInfo.imageInfo.height !== 1080)) {
    return {
      message: api.l10n('image-dimensions-error'),
    };
  }
}

With this update, the error message for the imageDimensions validator displays inย Spanish when the image dimensions donโ€™t match the required 1080ร—1080ย pixels.

When aย file fails validation, users see the error message inย the File Uploader UI. You can also access errors programmatically for logging orย analytics:

const ctx = document.querySelector('uc-upload-ctx-provider');
ctx.addEventListener('change', e => {
  const collectionState = e.detail;
  
  collectionState.allEntries.forEach(entry => {
    if (entry.errors.length > 0) {
      entry.errors.forEach(error => {
        console.log('Error:', error.message);
        console.log('Details:', error.payload);
      });
    }
  });
});

Each validation error includes:

  • message: User-facing error text
  • payload: Optional object with additional details (actualย vs. expected values) for your appโ€™s logic

Summary

Whether youโ€™re checking image dimensions, enforcing file types, orย validating entire collections, the Uploadcare File Uploaderโ€™s validator system gives you full control over what gets uploaded and what doesnโ€™t. Combine built-in validators for quick wins with custom validators for anything your project needs, and youโ€™ve got aย flexible, consistent upload experience without the heavy lifting.

Give itย aย try inย your own project. Ifย you run into anything orย want toย share what youโ€™ve built, drop aย note orย join the conversation inย the Uploadcare community.

Ready to get started?

Join developers who use Uploadcare to build fileย handling quickly andย reliably.

Sign up for free