remotion-dev/remotion · error · Error
getImageDimensions() is only available in the browser.
Error message
getImageDimensions() is only available in the browser.
What it means
Thrown by getImageDimensions() when `document` is undefined (line 14). The function constructs a DOM `Image()` and waits for onload to read width/height, so it requires a browser environment.
Source
Thrown at packages/media-utils/src/get-image-dimensions.ts:14
import {pLimit} from './p-limit';
import type {ImageDimensions} from './types';
const imageDimensionsCache: {[key: string]: ImageDimensions} = {};
const limit = pLimit(3);
const fn = async (src: string): Promise<ImageDimensions> => {
if (imageDimensionsCache[src]) {
return imageDimensionsCache[src];
}
if (typeof document === 'undefined') {
throw new Error('getImageDimensions() is only available in the browser.');
}
const imageDimensions = await new Promise<ImageDimensions>(
(resolved, reject) => {
const image = new Image();
image.onload = () => {
const {width, height} = image;
resolved({width, height});
};
image.onerror = reject;
image.src = src;
},
);
imageDimensionsCache[src] = imageDimensions;View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Call getImageDimensions() only inside Remotion components or other client code that runs in a browser.
- For server-side dimension reads, use a Node image library (e.g. sharp, image-size, probe-image-size) instead of this DOM-based helper.
- In tests, set the environment to jsdom/happy-dom or load a real image asset the polyfill can decode.
- Guard the call site with typeof document !== 'undefined' to skip it during SSR.
Example fix
// before (throws in Node SSR)
import {getImageDimensions} from '@remotion/media-utils';
export async function getStaticProps() {
const dims = await getImageDimensions('/hero.png');
return {props: {dims}};
}
// after (server uses sharp; client keeps the hook)
// server
import sharp from 'sharp';
const {width, height} = await sharp(file).metadata();
// client (Remotion)
const dims = await getImageDimensions(staticFile('hero.png')); Defensive patterns
Strategy: validation
Validate before calling
import {getImageDimensions} from '@remotion/media-utils';
async function safeGetImageDimensions(src: string) {
if (typeof document === 'undefined') {
// server-side: prefer sharp/probe-image-size here
return null;
}
return getImageDimensions(src);
} Type guard
const canUseDomImage = (): boolean => typeof document !== 'undefined' && typeof Image !== 'undefined';
Try / catch
try {
const dims = await getImageDimensions(src);
} catch (err) {
if ((err as Error).message.includes('only available in the browser')) {
// server path: use sharp/probe-image-size instead
} else {
throw err;
}
} Prevention
- Keep this helper inside Remotion components; use sharp or image-size for server-side dimension reads.
- Guard isomorphic code with typeof document !== 'undefined'.
- In Node tests, run under jsdom/happy-dom or stub the Image constructor.
- Do not invoke this helper during build-time data fetching.
When it happens
Trigger: Calling getImageDimensions() during SSR, in a Node build step, in Node-based tests, or in any non-browser runtime; calling it at module top level so it runs at import time on the server.
Common situations: Computing layout dimensions for images at build time; Next.js getStaticProps trying to size remote images; server-side rendered galleries; CI scripts that try to inspect image dimensions for validation.
Related errors
- getAudioData() is only available in the browser.
- getAudioDuration() is only available in the browser.
- getVideoMetadata() is only available in the browser.
- Tried to call an API that only works in the browser from out
- measureText() can only be called in a browser.
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/59f066db7044734e.
Report an issue: GitHub.