E-commerce
Implementing File Attachments with the DropZone Component
Implementing File Attachments with the DropZone Component
Implementing File Attachments with the DropZone Component
December 23, 2025
December 23, 2025
This article will guide you through the process of implementing file attachment functionality within Shopify’s Customer Account and Checkout UI extensions using the new DropZone UI component.
Author: Narayan Ramachandran
Estimated Read Time: 7 min
On this page
Getting Started
Solution
Step 1: Build the User Interface
Step 2: Create and Store the Attachment
Step 3: Store File References in Shopify Metafields
Limitations
Reference Links
Getting Started
Merchants may require customers to attach files for checkout and account workflows (e.g., customization, document verification, etc.), a feature previously unsupported within Shopify’s extensions. The new DropZone component now makes it feasible for developers to easily add this functionality to UI extensions, allowing customers to attach various file types in both extension contexts. This is particularly useful for enabling customers to upload content such as artwork, specification sheets, and documents.
Solution
Now let’s go over how to use the DropZone component to enable file attachments within Customer Account Extensions, specifically on the Order Status Page. The same principles apply to other supported extension points in both Checkout UI and Customer Account UI Extensions.
The solution involves these key steps:
User Interface: The DropZone component provides customers with a drag-and-drop area or a button to upload files.
File Storage: The attached file is uploaded and stored using the Shopify File API (which utilizes S3). Alternatively, any other hosting provider can be leveraged for this.
File Reference Storage: A reference to the uploaded file (e.g., the file URL) is stored in a customer metafield.
Before You Start
Ensure you have the following:
A partner account.
A new development store, where you’ve enabled the checkout UI extensions developer preview and customer account UI extensions developer preview.
Prior knowledge of creating UI extensions in Shopify. Refer to the tutorials for Checkout UI extensions and Customer Account UI extensions.
Step 1: Build the User Interface
The DropZone UI component provides customers with a drag-and-drop area or a button to upload files.
import { DropZone, reactExtension } from '@shopify/ui-extensions-react/customer-account'; import React from 'react'; export default reactExtension('customer-account.page.render', () => ); function App() { return ; }
The DropZone component includes an accept parameter, which is a string that specifies the types of files the component will accept. This string is a comma-separated list of unique file type specifiers, which can be one of the following:
A file extension starting with a period (e.g., .jpg, .pdf, .doc)
A valid MIME type string (e.g., image/png, application/pdf)
If the accept property is left empty, the DropZone will accept all file types. The onInput property provides a callback function that is executed when files are dropped or selected. The multiple property is a boolean type that defines if the user can select or drop multiple files at once.
Further details on all supported properties for this component can be found in the developer documentation.
Step 2: Create and Store the Attachment
While the component supports uploading files, the storage for uploads must be implemented separately. For this example, we use Shopify’s File API to store the attachments. Shopify sets up temporary file targets in AWS S3 buckets to host file data (images, videos, etc.). As mentioned previously, any other hosting provider can be used to store files.
The file storage process in Shopify involves three main steps:
Create a Staged Upload Target: First, create a staged upload target using Shopify’s GraphQL API. This prepares a location for the file upload.
Upload to Staged Target: Once you have the staged target, upload the file using the provided URL and parameters.
Create the File in Shopify: After a successful upload, create the file in Shopify’s Files section using the resource URL from the staged target.
Create a Staged Upload Target
First, you’ll create a staged upload target using Shopify’s GraphQL API. This prepares a location for the file upload.
const stagedUploadQuery = ` mutation stagedUploadsCreate($input: [StagedUploadInput!]!) { stagedUploadsCreate(input: $input) { stagedTargets { url resourceUrl parameters { name value } } userErrors { field message } } } `; const stagedUploadVariables = { input: [{ filename: file.name, mimeType: file.type, resource: "FILE", httpMethod: "POST" }] };
Upload to Staged Target
Once you have the staged target, upload the file using the provided URL and parameters.
const formData = new FormData(); formData.append('file', file); const uploadResponse = await fetch(stagedTarget.url, { method: 'POST', body: formData });
Create the File in Shopify
After successful upload, create the file in Shopify’s Files section using the resource URL from the staged target.
const createFileQuery = ` mutation fileCreate($files: [FileCreateInput!]!) { fileCreate(files: $files) { files { id alt url originalSource } userErrors { field message } } } `; const createFileVariables = { files: [{ alt: file.name, contentType: "FILE", originalSource: stagedTarget.resourceUrl }] };
Error Handling
Make sure to include error handling at each step:
Staged upload creation errors
File upload errors
File creation errors
Network errors
Important Callouts for File Creation/Storage
The file must be properly formatted and within Shopify’s size limits.
The staged upload URL is temporary and expires.
The process requires proper authentication with Shopify Admin API.
File types must be supported by Shopify (images, PDFs, etc.).
Response Structure
The final response includes:
File ID
Alt text
File URL
Original source URL
Implementation Architecture
The architecture consists of:
Frontend: Shopify Extension handles file selection and UI.
Backend: Node.js server handles secure API calls to Shopify’s GraphQL API.
Callouts
API Token Protection: Store Shopify Admin API tokens in the backend .env file, never expose them to the frontend.
CORS Security: Explicitly allow origins (Shopify extension domain), restrict HTTP methods, and control headers.
Data Flow: Frontend → Backend: File data and customer ID; Backend → Shopify: Secure API calls with tokens; Backend → Frontend: Processed response or error.
Step 3: Store File References in Shopify Metafields
After successfully uploading a file (e.g., via the Shopify File API) to store it, you’ll store a reference to that file in a metafield. This enables you to associate the uploaded file with a specific resource for later retrieval. While this example focuses on customer metafields, the file reference (e.g., the file URL) can also be stored in other resource metafields, such as order metafields, to link the file to a specific order.
const metafieldsSetQuery = ` mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) { metafieldsSet(metafields: $metafields) { metafields { key namespace value createdAt updatedAt } userErrors { field message code } } } `; const metafieldsSetVariables = { metafields: [{ key: "metafied_key", namespace: "metafield_namespace", ownerId: req.body.customerId, // Customer ID from the request type: "single_line_text_field", value: fileData.url // Store the file URL }] };
Limitations
The DropZone component for Checkout UI extensions is currently in an unstable version (as of April 4, 2025). However, the same component for Customer Account UI extensions is available in the stable version.
At present, the component does not offer image upload preview capabilities. The use of object URLs directly in an image component is not possible due to the extension and host operating on separate domains. The component’s appearance is controlled by Shopify’s design system, and custom styling options are limited to the provided props.
Reference Links
Go further
This article will guide you through the process of implementing file attachment functionality within Shopify’s Customer Account and Checkout UI extensions using the new DropZone UI component.
Author: Narayan Ramachandran
Estimated Read Time: 7 min
On this page
Getting Started
Solution
Step 1: Build the User Interface
Step 2: Create and Store the Attachment
Step 3: Store File References in Shopify Metafields
Limitations
Reference Links
Getting Started
Merchants may require customers to attach files for checkout and account workflows (e.g., customization, document verification, etc.), a feature previously unsupported within Shopify’s extensions. The new DropZone component now makes it feasible for developers to easily add this functionality to UI extensions, allowing customers to attach various file types in both extension contexts. This is particularly useful for enabling customers to upload content such as artwork, specification sheets, and documents.
Solution
Now let’s go over how to use the DropZone component to enable file attachments within Customer Account Extensions, specifically on the Order Status Page. The same principles apply to other supported extension points in both Checkout UI and Customer Account UI Extensions.
The solution involves these key steps:
User Interface: The DropZone component provides customers with a drag-and-drop area or a button to upload files.
File Storage: The attached file is uploaded and stored using the Shopify File API (which utilizes S3). Alternatively, any other hosting provider can be leveraged for this.
File Reference Storage: A reference to the uploaded file (e.g., the file URL) is stored in a customer metafield.
Before You Start
Ensure you have the following:
A partner account.
A new development store, where you’ve enabled the checkout UI extensions developer preview and customer account UI extensions developer preview.
Prior knowledge of creating UI extensions in Shopify. Refer to the tutorials for Checkout UI extensions and Customer Account UI extensions.
Step 1: Build the User Interface
The DropZone UI component provides customers with a drag-and-drop area or a button to upload files.
import { DropZone, reactExtension } from '@shopify/ui-extensions-react/customer-account'; import React from 'react'; export default reactExtension('customer-account.page.render', () => ); function App() { return ; }
The DropZone component includes an accept parameter, which is a string that specifies the types of files the component will accept. This string is a comma-separated list of unique file type specifiers, which can be one of the following:
A file extension starting with a period (e.g., .jpg, .pdf, .doc)
A valid MIME type string (e.g., image/png, application/pdf)
If the accept property is left empty, the DropZone will accept all file types. The onInput property provides a callback function that is executed when files are dropped or selected. The multiple property is a boolean type that defines if the user can select or drop multiple files at once.
Further details on all supported properties for this component can be found in the developer documentation.
Step 2: Create and Store the Attachment
While the component supports uploading files, the storage for uploads must be implemented separately. For this example, we use Shopify’s File API to store the attachments. Shopify sets up temporary file targets in AWS S3 buckets to host file data (images, videos, etc.). As mentioned previously, any other hosting provider can be used to store files.
The file storage process in Shopify involves three main steps:
Create a Staged Upload Target: First, create a staged upload target using Shopify’s GraphQL API. This prepares a location for the file upload.
Upload to Staged Target: Once you have the staged target, upload the file using the provided URL and parameters.
Create the File in Shopify: After a successful upload, create the file in Shopify’s Files section using the resource URL from the staged target.
Create a Staged Upload Target
First, you’ll create a staged upload target using Shopify’s GraphQL API. This prepares a location for the file upload.
const stagedUploadQuery = ` mutation stagedUploadsCreate($input: [StagedUploadInput!]!) { stagedUploadsCreate(input: $input) { stagedTargets { url resourceUrl parameters { name value } } userErrors { field message } } } `; const stagedUploadVariables = { input: [{ filename: file.name, mimeType: file.type, resource: "FILE", httpMethod: "POST" }] };
Upload to Staged Target
Once you have the staged target, upload the file using the provided URL and parameters.
const formData = new FormData(); formData.append('file', file); const uploadResponse = await fetch(stagedTarget.url, { method: 'POST', body: formData });
Create the File in Shopify
After successful upload, create the file in Shopify’s Files section using the resource URL from the staged target.
const createFileQuery = ` mutation fileCreate($files: [FileCreateInput!]!) { fileCreate(files: $files) { files { id alt url originalSource } userErrors { field message } } } `; const createFileVariables = { files: [{ alt: file.name, contentType: "FILE", originalSource: stagedTarget.resourceUrl }] };
Error Handling
Make sure to include error handling at each step:
Staged upload creation errors
File upload errors
File creation errors
Network errors
Important Callouts for File Creation/Storage
The file must be properly formatted and within Shopify’s size limits.
The staged upload URL is temporary and expires.
The process requires proper authentication with Shopify Admin API.
File types must be supported by Shopify (images, PDFs, etc.).
Response Structure
The final response includes:
File ID
Alt text
File URL
Original source URL
Implementation Architecture
The architecture consists of:
Frontend: Shopify Extension handles file selection and UI.
Backend: Node.js server handles secure API calls to Shopify’s GraphQL API.
Callouts
API Token Protection: Store Shopify Admin API tokens in the backend .env file, never expose them to the frontend.
CORS Security: Explicitly allow origins (Shopify extension domain), restrict HTTP methods, and control headers.
Data Flow: Frontend → Backend: File data and customer ID; Backend → Shopify: Secure API calls with tokens; Backend → Frontend: Processed response or error.
Step 3: Store File References in Shopify Metafields
After successfully uploading a file (e.g., via the Shopify File API) to store it, you’ll store a reference to that file in a metafield. This enables you to associate the uploaded file with a specific resource for later retrieval. While this example focuses on customer metafields, the file reference (e.g., the file URL) can also be stored in other resource metafields, such as order metafields, to link the file to a specific order.
const metafieldsSetQuery = ` mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) { metafieldsSet(metafields: $metafields) { metafields { key namespace value createdAt updatedAt } userErrors { field message code } } } `; const metafieldsSetVariables = { metafields: [{ key: "metafied_key", namespace: "metafield_namespace", ownerId: req.body.customerId, // Customer ID from the request type: "single_line_text_field", value: fileData.url // Store the file URL }] };
Limitations
The DropZone component for Checkout UI extensions is currently in an unstable version (as of April 4, 2025). However, the same component for Customer Account UI extensions is available in the stable version.
At present, the component does not offer image upload preview capabilities. The use of object URLs directly in an image component is not possible due to the extension and host operating on separate domains. The component’s appearance is controlled by Shopify’s design system, and custom styling options are limited to the provided props.
Reference Links
Go further

Subscribe to the newsletter and get a personalized e-book!
No-code solution, no technical knowledge required. AI trained on your e-shop and non-intrusive.
*Unsubscribe anytime. We don't spam.

Subscribe to the newsletter and get a personalized e-book!
No-code solution, no technical knowledge required. AI trained on your e-shop and non-intrusive.
*Unsubscribe anytime. We don't spam.

Subscribe to the newsletter and get a personalized e-book!
No-code solution, no technical knowledge required. AI trained on your e-shop and non-intrusive.
*Unsubscribe anytime. We don't spam.