remotion-dev/remotion · error · Error
Tried to call an API that only works in the browser from out
Error message
Tried to call an API that only works in the browser from outside the browser
What it means
portalNode() lazily creates a DOM <div> (positioned absolutely to fill the frame) used to host portaled content during rendering. It checks `typeof document === 'undefined'` and throws because the portal mechanism fundamentally requires a real DOM. Calling it in Node/SSR/serverless contexts without a DOM fails fast instead of crashing deeper in React.
Source
Thrown at packages/core/src/portal-node.ts:31
);
};
};
export const setPortalNodeCurrentScale = (scale: number) => {
if (portalNodeCurrentScale === scale) {
return;
}
portalNodeCurrentScale = scale;
for (const listener of portalNodeCurrentScaleListeners) {
listener();
}
};
export const portalNode = () => {
if (!_portalNode) {
if (typeof document === 'undefined') {
throw new Error(
'Tried to call an API that only works in the browser from outside the browser',
);
}
_portalNode = document.createElement('div');
_portalNode.style.position = 'absolute';
_portalNode.style.top = '0px';
_portalNode.style.left = '0px';
_portalNode.style.right = '0px';
_portalNode.style.bottom = '0px';
_portalNode.style.width = '100%';
_portalNode.style.height = '100%';
_portalNode.style.display = 'flex';
_portalNode.style.flexDirection = 'column';
const containerNode = document.createElement('div');
containerNode.style.position = 'fixed';
containerNode.style.top = -999999 + 'px';View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Only call browser-only APIs inside components that render in the browser or Remotion Studio.
- In jsdom-based tests, ensure the test environment exposes `document`.
- Gate the call: if (typeof document !== 'undefined') { ... }.
Example fix
// before
const node = portalNode();
// after
if (typeof document !== 'undefined') {
const node = portalNode();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof document !== 'undefined') {
const node = portalNode();
} Type guard
const hasDOM = (): boolean => typeof document !== 'undefined';
Prevention
- Keep browser-only calls inside components that render in the browser/Studio.
- Avoid calling browser APIs at module top-level in isomorphic bundles.
- Configure jsdom in Node test environments that exercise DOM code.
When it happens
Trigger: Importing or invoking portalNode() during SSR, inside a React server component, in a Node script, or in a headless render environment where no DOM is attached.
Common situations: Using Remotion browser-only APIs inside a Next.js server component; running composition code in a Node test without jsdom; calling the API at module top-level in an isomorphic bundle.
Related errors
- measureText() can only be called in a browser.
- getAudioData() is only available in the browser.
- getAudioDuration() is only available in the browser.
- getImageDimensions() is only available in the browser.
- getVideoMetadata() is only available in the browser.
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/250738b144540cf3.
Report an issue: GitHub.