Skip to main content

Update your app to use the new files model

In early 2024, Shopify introduced a new way to handle files. Instead of creating duplicate file objects for each product, theme, or other resource, the new system uses a single file that can be referenced across a shop. This makes file management more efficient and consistent across a store, reducing the number of duplicates and simplifying the process of updating files.

For example, if you have a product image used across multiple themes, product pages, and marketing materials, you only need to upload and manage one instance of that file. If you need to update the image, you only need to replace it once, and the change will automatically reflect everywhere the file is used.

This change affects how you create and manage files in your app. The following sections provide examples of how to update your app to use the new model.


Previously, apps would create a Product Image for each product using the REST Admin API. With the new files model, apps should use the fileCreate and fileUpdate mutations to create or update file. The fileUpdate mutation can be used to either updated the contents of a file, or associate it to a product. When working directly with products, apps should use the productCreate, productUpdate, or productSet mutations to associate files with corresponding products.

This change reflects our move towards a more streamlined approach where file information and associations are managed through the File APIs rather than through product-specific endpoints.

For example, if an app wanted to add an image to a product, it would previously use the following REST API call:

PUT /admin/api/2024-07/products/{product_id}/images.json

JSON

{
"image": {
"src": "https://example.com/image.jpg",
"alt": "A beautiful product image",
"position": 1,
"variant_ids": [
1234567890
],
}
}
}

Now, the same operation can be achieved asynchronously using the following GraphQL Admin API calls:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
fileCreate(file: {originalSource: "https://example.com/image.jpg"}) {
file {
id
fileStatus
alt
}
}
}

You can then poll the file fileStatus using this query until it's ready:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query {
node(id: "gid://shopify/MediaImage/25823372804185") {
... on File {
fileStatus
preview {
image {
url
}
}
}
}
}

The status field will be one of: UPLOADED, PROCESSING, READY, or FAILED. Once the status is READY, you can proceed with using the file.

Next, you can associate the file with the product using the productSet mutation:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
productSet(input: {
id: "gid://shopify/Product/7882412064857"
files: [
{
id: "gid://shopify/MediaImage/25823372804185"
}
]
}) {
product {
id
}
}
}

Anchor to Alternative approach using ,[object Object]Alternative approach using fileUpdate

You can also update an existing file's references using the fileUpdate mutation:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
fileUpdate(files: [{
id: "gid://Shopify/{filetype}/1234567890",
referencesToRemove: ["gid://shopify/Product/1234567890"],
referencesToAdd: ["gid://shopify/Product/9876543210"]
}]) {
files {
id
}
}
}
Note

The fileType parameter in the file GID is the type of file object that you are updating. This is either MediaImage, Video, GenericFile, ExternalVideo, or Model3d.

Anchor to REST API changes to support migrationREST API changes to support migration

Note

As of version 2025-01, the REST Admin API for the product image resource will return a files image GID instead of a product image GID.

This change helps simplify migration from REST to GraphQL when working with product images created before the unified files ID system.

VersionGID FormatExample
PreviousProductImage GID"gid://shopify/ProductImage/43701248884792"
New (2025-01)mediaImage GID"gid://shopify/MediaImage/12379812379123"

  • Direct use of returned files image GID in GraphQL queries and mutations
  • No ID translation or lookup needed
  • Ability to re-ruse existing files across different products

Anchor to Version CompatibilityVersion Compatibility

  • Only affects the 2025-01 API version and newer
  • Older versions will continue returning ProductImage GID

The following product-centric files APIs are being retired:

Deprecated (2024-10)Replacement
productAppendImagesfileCreate then productCreate or productSet
productDeleteImagesfileDelete
productImageUpdatefileUpdate

Anchor to Upcoming API ChangesUpcoming API Changes

We are transitioning from product-centric files APIs to file-centric APIs. Here's how the current APIs will map to the new system:

Current Product-Centric APIFuture File-Centric API
productCreateMediafileCreate then productCreate or productSet
productDeleteMediafileDelete

When working with collections, the process is slightly different from products. Because collections are not yet fully migrated to use files references, you need to pass files to collection mutations directly.

Anchor to Creating Collections with filesCreating Collections with files

To add files to a new collection, follow these steps:

Note

Note: If you're using an external image URL and don't need to store the file in Shopify's CDN, you can skip directly to step 3 and use your external URL in the src field.

  1. Create or obtain the file's GID using fileCreate:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
fileCreate(files: [{
originalSource: "https://example.com/image.jpg"
}]) {
files {
id
}
}
}
  1. Query the file to get the CDN URL:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query {
node(id: "gid://shopify/MediaImage/25823372836953") {
id
... on MediaImage {
preview {
status
image {
url
}
}
}
}
}
  1. Create the collection using the image URL:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
collectionCreate(input: {
title: "My Collection"
image: {
src: "https://cdn.shopify.com/s/files/1/0574/7248/3417/files/myfilename.jpg"
}
}) {
collection {
id
}
}
}

Anchor to Updating Collections with filesUpdating Collections with files

The process for updating a collection's files follows the same steps:

  1. Create or obtain the mediaImage GID using fileCreate or querying the file object
  2. Query the file to get its corresponding CDN URL
  3. Update the collection using the image URL:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
collectionUpdate(input: {
id: "gid://shopify/Collection/1234567890"
image: {
src: "https://cdn.shopify.com/s/files/1/0574/7248/3417/files/myfilename.jpg"
}
}) {
collection {
id
}
}
}

Anchor to Asynchronous file processingAsynchronous file processing

A key change to the files system is the shift from immediate to asynchronous processing. Updates now take effect after the mutation completes, improving efficiency and reducing the risk of concurrent update conflicts.

It's important to optimize your approach to avoid unnecessary polling when working with multiple images. Rather than polling each file individually, use a single GraphQL query to check the status of all files at once.


Was this page helpful?