Tag: Developer Guide

  • AVIF, WebP, or JPEG: choose formats by asset

    AVIF, WebP, or JPEG: choose formats by asset

    A format decision based on content, compatibility, and operational cost.

    Start with the content

    Photographs usually tolerate lossy compression; diagrams and interface screenshots expose ringing around sharp edges. WebP and AVIF can reduce transfer size, but visual quality, encoding time, and decode behavior matter. Keep a widely supported fallback when the audience includes older clients or embedded browsers.

    Measure at equal visual quality

    Compare outputs at the same displayed dimensions and similar perceived quality, not at the same numerical quality setting. Include transparency, animation, color profile, and metadata needs. Save a small representative corpus of photos, text-heavy screenshots, and graphics for repeatable tests.

    Negotiate without multiplying chaos

    A picture element or a well-defined CDN content negotiation strategy can serve modern formats and a fallback. Ensure the CDN cache key distinguishes format variants. Do not allow arbitrary format and quality combinations to create an unbounded derivative library.

    A concrete acceptance test

    Encode one photo, one UI screenshot, and one transparent graphic in each candidate format. Compare the downloaded bytes and visible edges at the exact size users will see. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Compare formats at matched visual quality.
    • Include text-heavy screenshots and transparent graphics in tests.
    • Cache each negotiated format under a distinct key.

    Related guides

    Primary reference: Official documentation.

  • Responsive images: get srcset and sizes working together

    Responsive images: get srcset and sizes working together

    Give browsers the right candidates and a truthful display size.

    Describe the actual slot

    A width-descriptor srcset lists candidate image widths; sizes tells the browser how wide the image will render at each breakpoint. If sizes claims a full viewport while CSS shows a half-width card, the browser can choose an unnecessarily large file. Write sizes from the layout, not from the source dimensions.

    Separate crop from resolution

    Use srcset for the same composition at several resolutions. Use picture with media conditions when mobile needs a different crop or framing. Keep a fallback img with intrinsic width and height so layout space is reserved before the image loads.

    Inspect the browser’s choice

    Test a real mobile viewport and a high-density desktop display. Look at currentSrc in DevTools and compare the delivered pixels to the rendered slot. A candidate set is useful only if the transformation service produces those widths and the CDN caches them predictably.

    A concrete acceptance test

    Render the same card at narrow and wide widths, then inspect currentSrc and transferred bytes. The chosen resource should have enough pixels for the slot without sending a desktop hero to mobile. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Match sizes to the actual CSS slot width.
    • Use picture when the crop changes across layouts.
    • Inspect currentSrc on mobile and high-density screens.

    Related guides

    Primary reference: Official documentation.

  • Signed media URLs: access control at delivery time

    Signed media URLs: access control at delivery time

    Use expiring delivery links without making private assets public.

    Decide what is private

    Private originals, paid downloads, and temporary review files need a delivery authorization step. The application checks the viewer’s rights and issues a short-lived URL for the exact object or transformation. The URL is a bearer capability: anyone holding it can use it until it expires.

    Keep caches aligned with permissions

    Choose an expiration long enough for a download but short enough for the access policy. If authorization can be revoked instantly, a plain presigned URL may not meet the requirement. A CDN token, proxy, or session-bound approach may be needed, with explicit cache-key and purge behavior.

    Do not log the secret link

    Avoid putting signed query strings in analytics, error reports, or third-party referrers. Test clock skew and range requests for large video files. Make the application able to refresh a link without asking users to restart an otherwise valid download.

    A concrete acceptance test

    Open a private URL before authorization, during its valid window, and after expiry. Repeat with a byte-range request and inspect logs to ensure the signed query string was not captured. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Authorize the exact asset before signing a delivery URL.
    • Test expiration and byte-range requests.
    • Remove signed query strings from routine telemetry.

    Related guides

    Primary reference: Official documentation.

    Related field note

    Continue with A decision matrix for delivery URL signing.

  • Design object storage keys for a growing media library

    Design object storage keys for a growing media library

    A naming scheme that supports ownership, versions, cleanup, and migration.

    Use opaque identities

    An object key is an address, not a database record or a trustworthy filename. Use an asset ID and a stable prefix such as originals/{asset-id}/source. Keep the user’s filename, title, and owner in application metadata. This avoids collisions and makes renaming an asset independent of moving bytes.

    Separate source from derivatives

    Put generated files under a versioned recipe prefix, for example derivatives/{asset-id}/{recipe-version}/. A new crop rule or encoder can then coexist with the old output during rollout. Record each derivative’s key, dimensions, format, and status so the application never guesses what exists.

    Plan deletion as a workflow

    Removing an asset requires more than deleting one URL. Mark it unavailable, revoke public references, enqueue deletion of source and derivative keys, and confirm completion. Inventory and lifecycle rules help find abandoned uploads, but do not replace an application-level deletion record.

    A concrete acceptance test

    Rename an asset, regenerate one derivative, and delete the asset. Confirm that the opaque source key remains stable through renaming and that deletion removes every recorded derivative. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Use an opaque asset ID instead of the original filename.
    • Version derivative prefixes separately from source keys.
    • Track every key that deletion must remove.

    Related guides

    Primary reference: Official documentation.

  • When to use resumable uploads for media

    When to use resumable uploads for media

    Decide when a one-request upload is enough and when recovery matters.

    Match the protocol to the file

    For small images on stable connections, a direct single-request upload is simple. For long videos or mobile networks, a failed request should not force the user to resend the entire file. A resumable protocol tracks an upload identifier and the committed byte offset so the client can continue from a known point.

    Persist state on both sides

    The server must bind the upload session to a user, expected size, expiration, and destination. The client should save the upload ID and query the server’s current offset after reconnecting instead of trusting its local counter. Progress means bytes accepted by the server, not just bytes sent by the browser.

    Finish exactly once

    After the final chunk, verify length and checksum, then create or finalize one asset record. Expire incomplete uploads and reclaim their storage. Test interrupted requests, duplicate chunks, browser refreshes, and two tabs resuming the same session before relying on the happy path.

    A concrete acceptance test

    Interrupt a large upload halfway, restart the browser, and resume from the server-reported offset. Repeat the last chunk and confirm that the final checksum and asset count remain correct. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Resume from the server offset after reconnecting.
    • Bind each session to an owner, size, and expiration.
    • Check the completed length and checksum before publication.

    Related guides

    Primary reference: Official documentation.

    Related field note

    Continue with The maintenance burden behind resumable upload protocols.

  • A secure validation path for image and video uploads

    A secure validation path for image and video uploads

    Validate uploads in stages before turning untrusted bytes into public assets.

    Check more than an extension

    An extension and browser-supplied Content-Type are hints, not proof. Restrict allowed formats, limit byte size, inspect the file signature, and decode or probe the content with maintained libraries. Apply authorization and quota checks before accepting the upload. Store the original outside a directly executable web path.

    Quarantine before publication

    A useful state sequence is pending, uploaded, validating, processing, ready, and rejected. Keep an untrusted upload private until validation and any required scanning complete. Re-encode images or transcode video into formats you serve rather than passing arbitrary uploaded bytes through to visitors.

    Keep failure messages useful

    Return a clear reason such as unsupported format, corrupt file, or size limit, without leaking internal storage paths. Log the asset ID and validation stage for operators. An upload that passes type checks may still fail dimension, duration, or decoder limits; model those as expected product outcomes.

    A concrete acceptance test

    Rename a text file to .jpg, spoof its MIME header, and send a corrupt image with a valid signature. Each should receive a distinct, safe rejection before becoming publicly readable. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Inspect actual bytes and decode the claimed format.
    • Keep untrusted files private until checks finish.
    • Give users a safe rejection reason for expected failures.

    Related guides

    Primary reference: Official documentation.

  • Direct browser uploads without exposing storage credentials

    Direct browser uploads without exposing storage credentials

    How to let browsers upload large media while the application keeps control.

    Issue a narrow upload grant

    The browser asks your application for permission, then uploads to object storage using a short-lived presigned URL. The application should choose the destination key and enforce the user’s quota before signing. A presigned URL inherits the signer’s permissions, so scope the signing identity and expiration carefully.

    Confirm the object after upload

    A successful browser request does not finish the workflow. Have the client call a completion endpoint, or consume a trusted storage event, then verify the object exists and its measured size and type are acceptable. Only then move the asset from pending to processing. Record a request ID so retries cannot create duplicate asset records.

    Avoid predictable overwrite paths

    An upload to an existing object key can replace that object. Generate opaque keys instead of using the original filename as the storage key. Keep the human filename as metadata after validation. Expire unused upload grants and clean up abandoned pending objects with a lifecycle policy.

    A concrete acceptance test

    Request an upload grant as one user, try it with an oversized file, and attempt a second upload to the same key. Confirm that the grant cannot overwrite an already published asset. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Sign only a generated key for an authorized user.
    • Verify size and type after storage confirms the upload.
    • Expire abandoned grants and clean up pending objects.

    Related guides

    Primary reference: Official documentation.

    Related field note

    Continue with A migration plan for direct browser uploads.

  • A developer’s guide to media pipelines

    A developer’s guide to media pipelines

    A practical map from browser upload to reliable image and video delivery.

    Map the lifecycle

    A media pipeline starts before the file reaches storage. The client needs a safe way to send bytes, the server needs an identity for the asset, workers need repeatable jobs, and delivery needs URLs with predictable behavior. Treat the original as an immutable input. Derivatives are outputs that can be recreated when requirements change.

    Choose boundaries that survive change

    Separate upload authorization, object storage, processing, metadata, and delivery. A product that only accepts small profile photos may process synchronously. Large video uploads, multiple renditions, or moderation usually justify a queue and an explicit processing state. Store the asset ID, owner, source key, checksum, status, dimensions, and derivative references in a database; keep binary bytes in object storage.

    Design for retries

    Give every processing job an idempotency key tied to the asset and recipe version. A retry should find the existing output or safely replace it. Publish an asset only after required derivatives exist, then make the delivery URL visible to the application. Keep failure states observable so a missing thumbnail does not silently become a broken page.

    A concrete acceptance test

    Upload a source image, force one worker failure, and confirm that a retry produces one ready asset with no duplicate derivative. Then change the recipe version and verify that the original remains unchanged. Run this test with a realistic asset and record the observed state, output URL, and failure reason.

    Implementation check

    • Keep the source immutable and give each derivative a recipe version.
    • Move the asset to ready only after required outputs pass validation.
    • Correlate upload, processing, and delivery logs with one asset ID.

    Related guides

    Primary reference: Official documentation.

    Related field note

    Continue with Designing queue backpressure for human and agent operators.