Key takeaways
- Create signed upload parameters on the backend and scope them to an approved Template.
- Keep Uppy lifecycle ownership explicit so route changes do not leak subscriptions or duplicate uploads.
- Represent upload and processing as separate progress states.
Commerce applications often need merchant, supplier, or customer media uploads. The frontend should provide accessible selection and progress while secrets, validation policy, processing, and storage remain server-controlled.
What matters most
- Persist the Assembly ID so the UI can recover after navigation or refresh.
Define the upload boundary before choosing components
An Angular commerce application may accept images from merchants, suppliers, reviewers, or customers, but each workflow has different permissions and publication consequences. Define who may upload, which catalog object they may change, accepted media, limits, required derivatives, approval rules, and final storage before building the picker. The browser should collect files and display state. A trusted backend should authorize the action, sign processing parameters, and decide whether completed media becomes part of the catalog.
Direct browser-to-upload-service transfer keeps large file bodies away from the Angular application server, reducing application bandwidth and request duration. It does not remove the backend from the security model. The backend still associates the request with an authenticated user and product, issues short-lived approved parameters, receives trusted completion information, and updates the commerce record. Transloadit handles file intake and processing in this design, not Angular rendering, catalog logic, carts, checkout, or inventory.
Browser
Selects files, provides local feedback, transfers bytes, and presents upload and processing states.
Application backend
Authenticates users, authorizes products, signs requests, verifies completion, and writes catalog state.
Processing service
Validates and transforms accepted media according to the approved workflow.
Persistent storage
Holds publishable outputs that the storefront or a separate delivery layer can serve.
Model upload work as a recoverable state machine
Use explicit states such as idle, selecting, validating, awaiting authorization, uploading, paused, processing, complete, failed, and canceled. Store a stable local operation identifier and, once created, the Assembly ID. Network transfer progress and server-side processing progress are different signals and should not share one misleading percentage. A file can be fully uploaded while resizing or video encoding is still running.
Decide which layer owns an active upload when the component is destroyed. A route-specific component may cancel and dispose of it on navigation, while a longer-lived upload service may intentionally preserve work across routes. Either choice can be valid, but accidental ownership causes leaked subscriptions, duplicate event handlers, or uploads that continue without visible controls. Expose immutable view state through Angular signals or RxJS streams and centralize transitions instead of letting several event callbacks mutate unrelated flags.
Transfer state
Represents bytes sent, pause, resume, cancellation, and network errors.
Processing state
Represents asynchronous server work after enough input has arrived.
Publication state
Represents application approval and catalog association, which may occur after processing succeeds.
Issue signed and constrained Assembly parameters
Never place the Transloadit Auth Secret in Angular source, runtime configuration delivered to the browser, or a generated bundle. The backend should verify the user's session and permission for the target product, construct approved Assembly parameters with a near-future expiration and unique nonce, sign the exact serialized payload, and return the parameters plus signature. The browser can submit them, but it cannot change a protected field without invalidating the signature.
Use a saved Template for the structural workflow and set allow_steps_override to false when browser users must not alter its Steps. The signed request can still carry bounded fields such as a product identifier or approved variant choice. Validate those values before signing and again before using results. Keep storage credentials in Template Credentials with minimum necessary permissions rather than sending them to the client. An Auth Key identifies the workspace, but it is the secret and signing process that protect request integrity.
Authenticate
Require a valid application identity before generating upload authorization.
Authorize
Confirm that the identity may add media to the requested merchant, product, or order.
Constrain
Choose the Template, file policy, limits, destination scope, expiration, and approved fields server-side.
Audit
Record the user, product, nonce, and resulting Assembly ID without logging secrets or full signed payloads.
Integrate Uppy through an Angular-owned lifecycle
Uppy can provide selection, progress, and resumable upload behavior while its Transloadit plugin creates and follows an Assembly. Create the Uppy instance only in a browser environment because Angular server rendering does not provide window, File, or Blob. Avoid constructing it during module evaluation or a server-rendered component path. Mount its UI after the target exists and translate its events into application state rather than treating the uploader's internal DOM as the source of truth.
Instantiate one uploader for the intended ownership scope, register each listener once, and remove listeners and UI mounts during deliberate teardown. If a singleton service owns active uploads, expose a narrow interface to components and preserve per-operation state. If the component owns the instance, destroy it when the route ends and tell the user that navigation cancels work. Do not create a new instance on every change-detection pass or subscription, because duplicate instances can submit the same files and report conflicting progress.
Browser guard
Initialize upload code only after confirming that the component is running in the browser.
Single owner
Give one component or service responsibility for instance creation, event registration, and teardown.
State adapter
Convert uploader events into typed application states that templates can render and test.
Use resumability without promising impossible recovery
The tus protocol creates an upload resource, sends file bytes with offset-aware requests, and can query the server for the last accepted offset after an interruption. This avoids restarting a large upload merely because a connection dropped. Resumability is not the same as automatic recovery from every browser or route event. The application must retain the upload URL and enough local file context, and browser privacy or storage policies can still prevent restoration.
Define retry and cancellation behavior for each failure class. A temporary network error can wait and resume, an expired signature may require fresh backend authorization, and a server-side validation rejection requires a corrected file. Apply backoff and an attempt limit instead of retrying an invalid payload indefinitely. When several files share an operation, decide whether one rejection fails the whole product submission or whether valid files may continue. Reflect that policy in both the Template and UI.
Pause
Retain the current operation and show that no bytes are moving.
Resume
Verify the accepted offset and continue the remaining transfer when authorization is still valid.
Retry
Create a controlled new attempt only for errors the application classifies as recoverable.
Cancel
Stop work intentionally and make the resulting catalog and temporary-file behavior clear.
Build an accessible upload experience
Drag and drop should supplement a labeled file input or button, not replace it. Every action needs a keyboard-operable control and a visible focus state. Explain accepted formats, quantity, and size limits before selection. Associate errors with the relevant file, provide an error summary for multi-file submissions, and avoid communicating failure through color alone. A preview needs useful alternative text or a clear decorative treatment based on its purpose.
Announce important state changes through an appropriate live region without narrating every byte. Users usually need to know that upload began, paused, failed, resumed, entered processing, and completed. Keep the percentage visible as text and expose an accessible progress value. Cancellation should request confirmation when it discards substantial work. If processing continues after navigation, provide a persistent status destination so the user does not have to keep the original component open.
Before selection
State allowed media, limits, expected processing, and whether publication requires review.
During transfer
Provide file-specific progress, pause or cancel controls, and actionable network errors.
After transfer
Distinguish processing and approval from upload completion and provide a way to return to status.
Complete work through a trusted asynchronous path
For short image operations, the browser may wait for encoding and use the completed Assembly status. Longer commerce workflows usually benefit from setting the client not to wait and configuring a notify_url. Transloadit sends the final Assembly status to that backend endpoint after processing ends. The handler should verify the webhook signature with the secret associated with the Assembly's Auth Key, reject invalid payloads, and acknowledge valid notifications promptly. Non-success responses can cause notification retries, so the handler must be idempotent.
Persist the Assembly ID when the operation starts and correlate it with the user and product. On completion, match results to uploads through identifiers such as original_id, not array position, because result ordering is not a relationship contract. Record persistent exported URLs and required metadata, then transition the product-media record. Do not publish temporary processing URLs to customers. If the browser misses the completion event, it should recover status from the application's database rather than becoming the sole authority.
Verify
Authenticate the completion payload before accepting its status or URLs.
Deduplicate
Treat repeated notifications for the same Assembly and terminal state as the same operation.
Correlate
Resolve the stored Assembly ID to an authorized application record before writing results.
Publish
Update the catalog only after required outputs and any approval checks have succeeded.
Test policy, lifecycle, and operations
Unit-test the state adapter with event sequences for success, pause, retry, rejection, cancellation, component destruction, and duplicate completion. Test the signing endpoint for unauthenticated users, unauthorized products, invalid fields, expired parameters, and replayed nonces. Browser tests should use accessible controls to select fixtures and should cover slow transfer, navigation, refresh, server rendering, and a webhook that arrives after the user leaves.
In staging, upload mislabeled files, oversized batches, undersized images, corrupt containers, and media that triggers long processing. Confirm that client validation offers quick guidance while server validation remains authoritative. Monitor authorization failures, abandoned transfers, processing duration, webhook retries, destination errors, and cost by workflow. Alert on sustained queues or failures, not every user cancellation. Retain sanitized identifiers and error classes long enough to investigate without storing unnecessary personal data.
Contract tests
Verify the backend response shape expected by the Uppy integration and webhook handler.
Lifecycle tests
Prove that route changes neither leak an uploader nor cancel a service-owned operation unexpectedly.
Failure drills
Exercise storage outages, duplicate notifications, and expired authorization before production traffic does.
Technical details worth knowing
- Direct browser-to-upload-service transfer keeps file bytes away from Angular application servers, but request signing and permission decisions must remain on a trusted backend.
- RxJS can model progress, cancellation, retry, and component teardown, while the resumable-upload protocol must retain enough state to continue after navigation or interruption.
- Angular server rendering has no File, Blob, or window objects. Upload initialization belongs behind browser-only boundaries rather than executing during server rendering.
- Resumability divides a file into recoverable transfers, but application progress should distinguish local preprocessing, network upload, and server-side media processing.
- Route changes and component destruction should not silently orphan active uploads unless the product deliberately transfers ownership to a longer-lived service.
- File inputs need visible labels, keyboard access, error summaries, and progress announcements in addition to drag-and-drop interaction.
A practical approach
- 1
Define the media fields, limits, derivatives, and storage paths for one product workflow.
- 2
Expose a backend endpoint that returns short-lived signed Assembly parameters.
- 3
Mount one Uppy instance, translate its events into application state, and clean it up deliberately.
- 4
Consume the completion webhook server-side and refresh product state from a trusted record.
When Transloadit is useful
Embed Uppy in an Angular component or framework-neutral boundary, obtain signed Assembly parameters from the backend, and display progress while Transloadit creates product derivatives and exports them.
Architecture boundary
Angular provides storefront components and state management. Transloadit handles file intake and processing, not the cart, catalog, checkout, rendering framework, or commerce backend.
Frequently asked questions
Can an Angular application generate the Transloadit signature in the browser?
No. Signature generation requires the Auth Secret, which must remain on a trusted backend. Angular should request short-lived signed parameters after the backend authenticates and authorizes the user.
Is a completed upload the same as completed media processing?
No. Upload completion means the file bytes reached the service. Resizing, encoding, analysis, export, application approval, and catalog publication may still be pending and should have separate states.
Should an upload continue when the Angular route changes?
That is a product decision. A component-owned uploader can cancel during teardown, while a longer-lived service can retain the operation across routes. Define one owner and communicate the behavior to the user.
How can the UI recover after a refresh?
Persist the application's operation ID and Transloadit Assembly ID on the backend. After refresh, load the trusted operation state from the application database and reconnect it to any resumable transfer information still available locally.
Why use a webhook if Uppy can wait for encoding?
A webhook lets processing continue after the browser closes or navigates away. It also gives the backend a trusted, retryable place to verify completion and update catalog records for longer-running operations.