Skip to main content

Migrate DropZone from Polaris React

Replace Polaris React DropZone with s-drop-zone. The component selects files and validates accepted file types. Your app still owns file-size and business validation, upload requests, progress, persistence, retry, and removal.


Anchor to Migrate file selection and uploadMigrate file selection and upload

The following destination preserves image-only, multiple-file selection. Reconnect validation and upload handling through the events described below.

Migrating an image upload

<s-drop-zone accept="image/*" label="Upload images" multiple></s-drop-zone>
import {DropZone} from '@shopify/polaris';

export function ProductImageUpload({uploadImages, error}) {
return (
<DropZone
label="Upload images"
accept="image/*"
allowMultiple
variableHeight
error={Boolean(error)}
onDrop={(_files, acceptedFiles) => uploadImages(acceptedFiles)}
>
<DropZone.FileUpload
actionTitle="Add files"
actionHint="Accepts image files"
/>
</DropZone>
);
}

Preview


Anchor to Map file-selection propertiesMap file-selection properties

Polaris ReactPolaris web componentsMigration notes
labellabelKeep the upload purpose visible.
labelHiddenlabelAccessibilityVisibility="exclusive"Keep an accessible field label.
acceptacceptKeep file extensions or MIME types aligned with server validation.
allowMultiplemultipleOmit it when exactly one file is allowed.
disableddisabledDisable new selection while an upload is being committed when concurrent changes aren't safe.
error boolean and custom child messageerror stringPut the recovery message on the field.
onDrop(files, accepted, rejected)onChange(event) and onDropRejected(event)Read selected files from event.currentTarget.files. Handle type rejection separately.
customValidatorApp validation in the selection handlerValidate size, count, dimensions, and domain rules before upload. Repeat validation on the server.
dropOnPageRemoveKeep the drop target local to the upload task so unrelated page drops aren't intercepted.
openFileDialogRemoveLet the merchant activate the field rather than controlling the browser file dialog from render state.

accept doesn't validate file size, image dimensions, content safety, or whether a file matches its extension. Treat browser validation as early feedback and enforce every requirement again on the server.


Anchor to Rebuild the upload lifecycleRebuild the upload lifecycle

Keep each selected file in app state with a stable client ID and explicit status:

  1. Validate the selected files and show per-file or field-level rejection messages.
  2. Start the upload and prevent accidental duplicate submission.
  3. Display progress when the upload transport reports measurable progress; otherwise show an indeterminate pending state.
  4. On success, store the server resource ID and render the uploaded-file state.
  5. On failure, preserve the file name and a retry or remove action.
  6. When a merchant removes an uploaded file, update both backend state and the rendered list.

Don't clear the selected files before the server confirms success. A failed upload with no visible file or retry path forces the merchant to repeat selection.


  • Select files through browse and drag-and-drop interactions.
  • Test one and multiple files, accepted and rejected types, size limits, and count limits.
  • Run upload success, failure, cancellation, retry, duplicate submission, and removal paths.
  • Confirm server validation rejects files that bypass browser checks.
  • Verify disabled and pending states don't strand keyboard focus.
  • Verify labels, rejection messages, file names, and retry actions are announced.

Anchor to Remove Polaris ReactRemove Polaris React

After every call site is migrated, remove DropZone, DropZone.FileUpload, Polaris drag-state helpers, and callback adapters used only by them. Remove @shopify/polaris only after no other route in scope imports it.



Was this page helpful?