Key takeaways
- Treat the original product asset as the source of truth and derive channel variants from an explicit policy.
- Separate listing, detail, zoom, and swatch outputs because each has different pixel and loading needs.
- Use stable product and asset identifiers in output paths instead of filenames supplied by a browser.
Product media becomes expensive when each channel invents its own crop, format, and naming rules. A useful pipeline starts from the product record and produces a small, deliberate derivative set whose paths, metadata, and lifecycle the commerce system can own.
What matters most
- Keep approval and catalogue state in the commerce application while Transloadit reports processing and export state.
- Measure bytes, processing time, failure rate, and visual quality by channel before adding more variants.
Define the product-media contract
Start with placements rather than operations. A listing card, product detail page, zoom viewer, swatch, email, marketplace feed, and product video each have a different display size, crop policy, format requirement, and performance budget. Write those requirements down before choosing Steps so the Template expresses a product rule rather than a pile of transformations.
Keep the product catalogue as the authority for SKU, locale, approval, and publication. The processing pipeline should receive a stable asset identity and return verified derivatives. That division lets the commerce system decide whether a product is ready while Transloadit concentrates on repeatable file work.
Name every placement
Record dimensions, aspect ratio, crop policy, format, quality, and maximum bytes for each channel.
Version the source
Use an application-owned asset version so a new shoot cannot overwrite a published derivative unexpectedly.
Set a budget
Measure bytes and processing cost before adding another breakpoint or marketplace variant.
Create bounded derivatives
A common workflow accepts the source, validates it, creates listing and detail images, prepares a larger zoom derivative when one is justified, and encodes product video separately. Keep the original export available for reprocessing, but do not make every page load the original. In the sample, zoom: false prevents upscaling beyond the requested dimensions. Use the smallest derivative that preserves the intended product detail at its placement.
Cropping needs an explicit policy. A center crop is predictable but can cut off a product; attention or entropy gravity can help in some images; use /image/facedetect when face coordinates are required, and still review for high-value catalogues. Store the crop policy and source version with the derivative record so a visual difference is explainable later.
{
"allow_steps_override": false,
"auth": {
"max_number_of_files": 1,
"max_size": 104857600
},
"steps": {
":original": {
"robot": "/upload/handle"
},
"accepted_image": {
"use": ":original",
"robot": "/file/filter",
"accepts": [["${file.mime}", "regex", "^image/(jpeg|png|webp)$"]],
"error_on_decline": true
},
"listing": {
"use": "accepted_image",
"robot": "/image/resize",
"width": 640,
"height": 640,
"resize_strategy": "fit",
"zoom": false,
"format": "webp",
"quality": 82,
"result": true
},
"detail": {
"use": "accepted_image",
"robot": "/image/resize",
"width": 1600,
"height": 1600,
"resize_strategy": "fit",
"zoom": false,
"format": "webp",
"quality": 86,
"result": true
},
"original_export": {
"use": "accepted_image",
"robot": "/s3/store",
"credentials": "catalogue-media",
"path": "catalog/${fields.product_id}/${fields.asset_version}/original-${unique_prefix}.${file.ext}",
"acl": "bucket-default",
"result": true
},
"listing_export": {
"use": "listing",
"robot": "/s3/store",
"credentials": "catalogue-media",
"path": "catalog/${fields.product_id}/${fields.asset_version}/listing.webp",
"acl": "bucket-default",
"result": true
},
"detail_export": {
"use": "detail",
"robot": "/s3/store",
"credentials": "catalogue-media",
"path": "catalog/${fields.product_id}/${fields.asset_version}/detail.webp",
"acl": "bucket-default",
"result": true
}
}
}Listing
Small, fast images for grids and search results, with dimensions that match the card layout.
Detail
The primary product view, with enough resolution for the page but no unnecessary original-sized payload.
Zoom and video
Generate only when the experience needs them, and give them their own loading and storage policy.
Keep routing and paths trustworthy
Output paths are part of the catalog contract. Build them from product identifiers and a validated asset version that your application authorizes, then write result metadata back to the commerce system. Do not let a browser-provided filename or field decide where another tenant’s derivative is stored or which SKU it belongs to.
Signing params.fields on the server does not protect these paths when a browser submits the request. Multipart form fields also become Assembly fields and are not covered by the signature, and a field sent after params replaces the signed value with the same name. The browser controls that order. Because the sample writes fixed listing.webp and detail.webp names under ${fields.product_id} and ${fields.asset_version}, a browser-submitted request could overwrite another product’s derivatives. Have the application server construct and submit the entire Assembly request, including the upload and non-empty, authorized, path-safe product_id and asset_version values, and do not forward arbitrary client fields.
Apply the same rule to other dynamic fields. Keep dimensions fixed in the Template or use one Template per approved variant set; request fields override Template-level fields, so only the server should supply them. Saving allow_steps_override: false in the Template is a separate boundary: it prevents runtime Step overrides when using template_id, but it does not authorize field values. Checking returned storage keys against the expected prefix is still worthwhile before catalog publication, but it cannot undo an overwrite at the wrong key, so protect the write itself.
Use stable paths
Include a product identifier and asset version, and replace the catalogue pointer only after export verification.
Bound choices
Allow known dimensions and variants rather than arbitrary transformation parameters from the browser.
Protect credentials
Keep storage credentials in Template Credentials and your Transloadit Auth Secret on the server that submits the Assembly.
Publish from verified events
A webhook tells the application that an Assembly changed state; it does not make a product publishable by itself. Verify the webhook, retrieve the trusted Assembly result, check that every required derivative exists with the expected dimensions and MIME type, and only then update the catalogue record.
Notifications may be duplicated, delayed, or missing. The handler should be safe to run twice, tolerate events arriving out of order, and reconcile a missing event by polling or running a periodic status check. This is what keeps a failed export from leaving a product that points at a half-built image set.
Verify
Check signatures, Assembly identity, output paths, dimensions, MIME types, and expected variant count.
Idempotently update
Use product ID and asset version as the write key so a retry cannot duplicate or regress a catalogue record.
Reconcile
Use status polling or a repair job for events that are delayed, duplicated, or never observed.
Measure before expanding the variant set
Record derivative dimensions, byte size, processing time, failures, and visual review results by placement. Compare those measurements with page performance and conversion goals before adding another breakpoint, format, or marketplace branch.
A small contract that matches real placements is easier to cache, migrate, and repair than a catalogue-wide matrix generated speculatively. Keep the source and asset version so a later policy change can be reproduced from the same input.
Measure bytes
Compare representative derivative sizes with the network and decode budgets of each placement.
Review quality
Inspect crops and compression on representative products before making a derivative part of publication.
Launch with a tested Transloadit Template
The example in this guide accepts at most one image, creates two deliberately bounded derivatives, and exports the accepted original and each derivative under a distinct versioned key. Its filter routes only the JPEG, PNG, and WebP MIME types onward and fails the Assembly for anything else, and every export is downstream of that filter, so a declined upload is not exported to S3. MIME routing is not strict content verification; validate the stored bytes in your application if your contract requires it. Test representative product images, then tune dimensions, crop policy, quality, and retention from measured channel requirements before adding zoom or video branches.
Create a Transloadit account and save the Assembly Instructions as a Template. Create an S3 Template Credential named catalogue-media with key, secret, bucket, and bucket_region; see Template Credentials for setup. Keep the bucket private with Block Public Access enabled; acl: "bucket-default" omits an object ACL and relies on the bucket’s access policy, so it does not make objects private by itself. Have your commerce server submit the Assembly with authorized values for both the product ID and asset version, verify that every expected derivative exists under the expected versioned path, record the result idempotently, and update the catalog only after the export is complete. See Transloadit pricing when you are ready to estimate processing and storage for your catalog.
Save the sample configuration
Keep the processing graph and storage credentials in a saved Template rather than rebuilding Steps in the browser.
Publish after verification
Use the verified Assembly results and your catalogue approval state as the release gate for each asset version.
Technical details worth knowing
- A larger image is not automatically a better zoom asset; output dimensions should follow the actual display and crop requirements.
- Format conversion, resizing, and cropping can be separate steps with different quality and failure considerations.
- Notifications may be duplicated and are retried only a few times, so the commerce application needs signature verification, idempotent result handling, and reconciliation for missing events.
- Customer-owned storage remains the system of record for exported files when a workflow uses an /s3/store or other storage Robot.
- Variant generation can multiply quickly across locales, channels, breakpoints, and campaigns; bounded policies prevent accidental combinatorial growth.
- The source and each derivative should have a stable version so replacing a product image cannot mix old and new outputs.
- A listing thumbnail normally needs less data than a detail or zoom asset; sending the original to every placement wastes transfer and decode work.
- Output paths should be generated from trusted product identifiers and a validated asset version, not interpolated from arbitrary client input.
- A completed Assembly is not the same as a published product. Catalogue updates should wait for verified exports and the application’s own approval state.
- When a channel adds a new derivative, update the contract and tests instead of silently changing every existing output.
A practical approach
- 1
Define the derivative contract for each channel before writing the Template.
- 2
Have the commerce server submit the source with authorized product_id and asset_version fields, and preserve the accepted original.
- 3
Generate the minimum listing, detail, zoom, and video outputs needed by current channels.
- 4
Publish only after the application receives and idempotently records a complete export event.
When Transloadit is useful
Have your commerce server create and submit an Assembly from a Template that validates, normalizes, branches, and exports bounded derivatives to your customer-owned storage. If people upload through Uppy or another browser client, treat that as a separate intake stage your application validates before its server submits this sample export configuration. Keep SKU, locale, approval, and publication state in the commerce application.
Architecture boundary
Transloadit prepares product media and exports derivatives; it does not provide a product catalogue, PIM, DAM, storefront, approval UI, or marketplace listing service.
Frequently asked questions
Does Transloadit replace a product information management (PIM) or digital asset management (DAM)?
No. It processes files and exports derivatives. Keep product attributes, approvals, rights, catalogue state, and asset discovery in the system that owns them.
How many variants should a product image have?
Start with the placements you can measure: usually listing, detail, and only the zoom or channel outputs that have a real consumer. Add variants when device, layout, or marketplace evidence justifies their processing and storage cost.
Should the original be public?
Usually no. Keep the original in controlled storage and publish only the derivatives and paths needed by the product experience.
What happens when a product image is replaced?
Create a new asset version, process it, verify all required outputs, then switch the catalogue pointer. Retain or retire the previous version according to your application policy.