Skip to main content

Interactive.create()v4.0.536

Wraps a React component with timing props and editable controls in the Remotion Studio.

Circle.tsx
import type React from 'react'; import {Interactive, type InteractivitySchema} from 'remotion'; type CircleProps = { readonly radius?: number; readonly color?: string; readonly style?: React.CSSProperties; }; const circleSchema = { radius: { type: 'number', min: 1, step: 1, default: 80, description: 'Radius', hiddenFromList: false, }, color: { type: 'color', default: '#0b84ff', description: 'Color', }, } as const satisfies InteractivitySchema; const CircleInner: React.FC<CircleProps> = ({radius = 80, color = '#0b84ff', style}) => { return ( <div style={{ width: radius * 2, height: radius * 2, borderRadius: '50%', backgroundColor: color, ...style, }} /> ); }; export const Circle = Interactive.create({ Component: CircleInner, schema: circleSchema, });

The exported Circle component accepts CircleProps, timing props, premount props and cropping props.

API​

Importing
import {Interactive} from 'remotion';

The options for Interactive.create() are:

Component​

The component to wrap.

With the default layout: 'none', it must accept a style?: React.CSSProperties prop and apply it to its visual root. With layout: 'absolute-fill', the wrapper applies styles to a full-size container instead. Component must not declare style, width, or height props; these belong to the wrapper.

componentName?​

The component name used by Studio and in validation messages.

schema?​

An InteractivitySchema that describes which custom props are editable in Remotion Studio. Defaults to {}.

Timing, premounting, cropping, and transform controls are included automatically.

See: Make a component interactive

layout?​

Defaults to 'none', which forwards styles to Component without adding a container.

Set to 'absolute-fill' to give the component a full-size, absolutely positioned container with overflow: 'hidden' by default. Styles, transforms, cropping, and premount styles apply to this container.

The inner component can return a fragment and does not need to forward styles:

Scene.tsx
import React from 'react'; import {Video} from '@remotion/media'; import {Interactive, useVideoConfig} from 'remotion'; const SceneInner: React.FC = () => { const {fps} = useVideoConfig(); return ( <> <Video src="https://remotion.media/jonnys-videos/roller-skis-new/footage/IMG_0466.mp4" premountFor={fps} objectFit="cover" style={{width: '100%', height: '100%'}} /> <Interactive.Div name="Title" style={{position: 'absolute', left: 80, bottom: 80, color: 'white', fontSize: 80}} > Under the trees </Interactive.Div> </> ); }; export const Scene = Interactive.create({ Component: SceneInner, layout: 'absolute-fill', }); const Example = () => ( <Scene from={30} durationInFrames={90} premountFor={30} style={{opacity: 0.5}} /> );

Keep 'none' when styles need to apply directly to an element with its own size or layout, such as a text box, SVG, or button.

Return value​

Returns a React component with the original component's props and timing, premounting, and cropping props.

Ref forwarding​

With layout: 'none', if Component accepts a ref, the returned component preserves its ref type and forwards the ref directly to Component.

With layout: 'absolute-fill', the ref points to the wrapper's HTMLDivElement.

Migrating from Interactive.withSchema()​

For calls with wrapInSequence: true, replace Interactive.withSchema() with Interactive.create() and remove wrapInSequence. You can also remove an empty schema and a componentName that matches the inferred name. Keep explicit names when they should remain unchanged.

Compatibility​

BrowsersEnvironments
Chrome
Firefox
Safari

Rendering support depends on Component. Editing timeline controls requires an editable Remotion Studio session.

See also​