Skip to main content

Make a component interactivev4.0.530

Remotion's default components are already interactive, meaning they can be selected and edited in the Studio.

To make your component interactive too, wrap it with Interactive.withSchema().

Create the component​

For a scene that fills its parent, use layout: 'absolute-fill' when wrapping it with Interactive.withSchema(). Its inner component can return a fragment; the wrapper handles styles, transforms, premounting, and cropping.

A component with its own size, like the badge below, keeps the default layout and forwards style to its visual root.

Badge.tsx
import type React from 'react'; type BadgeProps = { readonly children?: React.ReactNode; readonly color?: string; readonly padding?: number; readonly style?: React.CSSProperties; }; export const BadgeInner: React.FC<BadgeProps> = ({children, color = '#0b84ff', padding = 16, style}) => { return ( <div style={{ ...style, display: 'inline-flex', borderRadius: 999, backgroundColor: color, color: 'white', fontWeight: 700, padding, }} > {children} </div> ); };

Create a schema​

Define an InteractivitySchema to declare the props that may be interactively edited.

Badge.tsx
import type {InteractivitySchema} from 'remotion'; const badgeSchema = { color: { type: 'color', default: '#0b84ff', description: 'Color', }, padding: { type: 'number', min: 0, step: 1, default: 16, description: 'Padding', hiddenFromList: false, }, } as const satisfies InteractivitySchema;

Interactive.withSchema() includes these schemas:

Caption fieldsv4.0.500​

Include Interactive.captionsSchema when the component accepts captions: Caption[] data:

Captions.tsx
import {Interactive, type InteractivitySchema} from 'remotion'; const captionsSchema = { ...Interactive.captionsSchema, } as const satisfies InteractivitySchema;

Captions will become editable in the Studio.

Turn on interactivity​

Call Interactive.withSchema() to link the schema to the component.

Badge.tsx
import type React from 'react'; import {Interactive, type InteractivitySchema} from 'remotion'; type BadgeProps = { readonly children?: React.ReactNode; readonly color?: string; readonly padding?: number; readonly style?: React.CSSProperties; }; const BadgeInner: React.FC<BadgeProps> = ({children, color = '#0b84ff', padding = 16, style}) => { return ( <div style={{ ...style, display: 'inline-flex', borderRadius: 999, backgroundColor: color, color: 'white', fontWeight: 700, padding, }} > {children} </div> ); }; const badgeSchema = { color: { type: 'color', default: '#0b84ff', description: 'Color', }, padding: { type: 'number', min: 0, step: 1, default: 16, description: 'Padding', hiddenFromList: false, }, } as const satisfies InteractivitySchema; export const Badge = Interactive.withSchema({ Component: BadgeInner, componentName: 'Badge', schema: badgeSchema, wrapInSequence: true, });

Use the component​

You can now use the component regularly.

In the Studio, it will render an outline and its props become editable.

MyComp.tsx
import {Badge} from './Badge'; export const MyComp = () => { return ( <Badge from={30} durationInFrames={90} premountFor={30} color="#ff5c7a" cropLeft={0.2} style={{translate: '120px 80px'}}> Sale </Badge> ); };

See also​