Rendering Outside the Editor
Use the useRender hook to trigger video rendering from any React component without mounting the full editor
Rendering Outside the Editor
The useRender hook lets you trigger video rendering from any React component — without mounting the full <ReactVideoEditor>. This is useful when you want to render from a dashboard, batch queue, custom UI, or anywhere outside the editor.
It supports both cloud rendering (via your VideoRenderer) and browser rendering (via WebCodecs), and returns a promise-based API with full state tracking.
import { useRender } from '@reactvideoeditor/react-video-editor/hooks/use-render';Quick Example
import { useRender } from '@reactvideoeditor/react-video-editor/hooks/use-render';
function RenderButton({ tracks, renderer }) {
const { render, state, cancel } = useRender('my-composition', {
tracks,
width: 1920,
height: 1080,
fps: 30,
renderer, // cloud rendering
});
const handleRender = async () => {
try {
const result = await render('1080p');
console.log('Video ready:', result.url, result.size);
} catch (err) {
console.error('Render failed:', err);
}
};
return (
<div>
<button onClick={handleRender} disabled={state.status === 'rendering'}>
{state.status === 'rendering'
? `Rendering ${Math.round(state.progress * 100)}%`
: 'Render Video'}
</button>
{state.status === 'rendering' && (
<button onClick={cancel}>Cancel</button>
)}
{state.status === 'done' && (
<a href={state.url} download>Download</a>
)}
</div>
);
}Browser Rendering
To render entirely in the browser without a server, use webRender: true instead of providing a renderer:
const { render, state } = useRender('my-composition', {
tracks,
width: 1920,
height: 1080,
fps: 30,
webRender: true,
});
const result = await render('1080p');
// result.url — blob URL to the rendered MP4Browser requirements
Browser rendering requires WebCodecs support (Chrome 94+ or Edge 94+). See Client-Side Rendering for browser compatibility details.
Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
tracks | Track[] | Yes | — | The tracks to render |
width | number | Yes | — | Composition width in pixels |
height | number | Yes | — | Composition height in pixels |
fps | number | Yes | — | Frames per second |
renderer | VideoRenderer | — | — | Cloud renderer instance (e.g. HttpRenderer). Either renderer or webRender must be provided |
webRender | boolean | — | false | Enable browser-side rendering via WebCodecs |
backgroundColor | string | — | 'white' | Background color for the composition |
baseUrl | string | — | — | Optional base URL for asset resolution |
pollingInterval | number | — | 1000 | Cloud render progress polling interval (ms) |
initialDelay | number | — | 0 | Delay before first progress poll (ms) |
onExportStart | function | — | — | Called when rendering begins |
onExportComplete | function | — | — | Called when rendering succeeds |
onExportFail | function | — | — | Called when rendering fails |
Return Value
The hook returns an object with four properties:
| Property | Type | Description |
|---|---|---|
render | (resolution?: ExportResolution) => Promise<RenderResult> | Start a render. Resolves with { url, size } on success. Defaults to '1080p' |
state | RenderState | Current render state (see below) |
cancel | () => void | Cancel an in-progress render and reset to init |
reset | () => void | Reset state back to init, cancelling any in-progress render |
RenderState
The state is a discriminated union — TypeScript narrows the available fields based on status:
type RenderState =
| { status: 'init' }
| { status: 'invoking' }
| { status: 'rendering'; renderId: string; progress: number }
| { status: 'error'; renderId: string | null; error: Error }
| { status: 'done'; url: string; size: number };RenderResult
type RenderResult = { url: string; size: number };Lifecycle Callbacks
The hook fires the same lifecycle callbacks as the editor's built-in rendering:
const { render } = useRender('my-composition', {
tracks,
width: 1920,
height: 1080,
fps: 30,
renderer,
onExportStart: ({ compositionId, durationInSeconds, renderType }) => {
console.log('Render started', compositionId);
},
onExportComplete: ({ compositionId, url, sizeInBytes, durationInSeconds, renderType }) => {
console.log('Render complete', url);
},
onExportFail: ({ compositionId, error, durationInSeconds, renderType }) => {
console.error('Render failed', error);
},
});Cancellation and Cleanup
cancel()aborts any in-flight render and resets state toinitreset()does the same — cancels and resets- Unmounting the component automatically cancels any in-progress render and cleans up resources (blob URLs, OPFS assets)
const { render, cancel } = useRender('my-composition', { /* ... */ });
// Start a render
const promise = render('1080p');
// Cancel it mid-way
cancel();
// The promise will reject with an AbortErrorResolution
The render() function accepts an optional ExportResolution parameter:
| Resolution | Short Edge |
|---|---|
'720p' | 720px |
'1080p' | 1080px (default) |
'4k' | 2160px |
The actual pixel dimensions are calculated from the width and height you provide, scaled to match the target resolution.
Types
Both RenderState and RenderResult are exported from the hook and from the main types entrypoint:
import type { RenderState, RenderResult } from '@reactvideoeditor/react-video-editor/hooks/use-render';
// or
import type { RenderState, RenderResult } from '@reactvideoeditor/react-video-editor/types';