Skip to content

Media: Where should EXIF rotation belong — server, client, or hybrid? #77582

@adamsilverstein

Description

@adamsilverstein

Background

In the discussion on #75793 (comment), the question came up of whether EXIF rotation detection is best done client-side rather than relying on the server. We agreed to continue the discussion in a follow-up — this is that follow-up.

Current state

EXIF orientation is currently detected server-side and rotation is applied client-side:

  • Server (PHP): wp_read_image_metadata() reads the EXIF orientation during upload and stores it in attachment metadata. Gutenberg_REST_Attachments_Controller::prepare_item_for_response() exposes it as exif_orientation on the REST response (lib/media/class-gutenberg-rest-attachments-controller.php:262).
  • Server (PHP): wp_image_maybe_exif_rotate is filtered to __return_false during the client-side upload flow so the server does not rotate the original (lib/media/class-gutenberg-rest-attachments-controller.php:382).
  • Client (JS): generateThumbnails() reads attachment.exif_orientation from the response and dispatches a rotation operation when it isn't 1 (packages/upload-media/src/store/private-actions.ts:1096).

So today, detection lives in PHP (wp_read_image_metadata) and rotation lives in JS (vips). The orientation value round-trips through the upload response.

Three approaches

1. Server-side detection (current)

The browser uploads the original; the server reads EXIF and returns the orientation in the response; the client rotates and sideloads sub-sizes.

Pros

  • Single source of truth — reuses wp_read_image_metadata(), which all of WordPress already trusts.
  • Backwards compatible with any existing PHP filters/plugins that hook into the metadata reader.
  • Works for any MIME type the server can parse (HEIC, TIFF, etc.) — no need to ship a JS EXIF parser per format.
  • Consistent results across browsers (no JS EXIF library quirks).

Cons

  • Detection is delayed until after the original upload completes — rotation can't begin until the response arrives.
  • Adds an unavoidable PHP step even when the client already has the file in memory.
  • Couples the client-side processing pipeline to a server round-trip for a piece of information the client could compute locally.

2. Client-side detection

Read EXIF orientation in JS (e.g. via exifr, a small custom parser, or createImageBitmap with imageOrientation: 'from-image') before/during upload and rotate locally without waiting for the server.

Pros

  • No server round-trip needed before rotation — pipeline can run end-to-end in the browser.
  • Lets us rotate the original before upload, so the server stores an already-correct file (matches iOS/Android camera behavior).
  • Simpler data flow — no exif_orientation field on the REST response.

Cons

  • Need to parse EXIF in JS for every supported format. HEIC/HEIF EXIF parsing in particular is non-trivial and varies by browser.
  • Bypasses any PHP filter that plugins use to override orientation handling (loss of wp_image_maybe_exif_rotate-style extensibility).
  • Potential cross-browser inconsistency. createImageBitmap({ imageOrientation: 'from-image' }) is well-supported but doesn't give us the raw orientation value, only the rotated bitmap.
  • Not all browsers support client side media so the server would still be a fallback meaning we need to maintain both paths

3. Hybrid

Detect client-side when possible (fast path), fall back to server-side detection (already in the response) when the client can't read EXIF for that format. Or: detect client-side and verify server-side.

Pros

  • Best of both: fast path for common cases, safety net for edge cases.
  • Lets us migrate incrementally — keep the server path, add the client path opportunistically.

Cons

  • Two implementations to keep in sync.
  • More complex contract: when does the client trust its own reading vs. the server's? Conflict resolution rules need to be specified.
  • The "best of both" can become "worst of both" if the fast path is rarely a win in practice.

Questions for the discussion

  1. Do we have data on how often EXIF rotation is actually needed? (i.e. is the fast path worth optimizing?)
  2. How important is the ability for plugins to filter orientation handling in PHP? Howe many popular plugins use filters that would be lost?
  3. Are there formats (HEIC, TIFF) where client-side EXIF parsing is too costly to ship? (we already do this for HEIC when the server lacks support)
  4. Is there a path to have the server not read EXIF at all when client-side processing is active, so we save the PHP work entirely?

Related: #75793, the broader client-side media processing initiative ([Feature] Client Side Media).

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Feature] Client Side MediaMedia processing in the browser with WASM[Type] DiscussionFor issues that are high-level and not yet ready to implement.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions