SuperAPI AI Directory

remotion-new-markup

Coding & development

View repository

Updated 10-16 07:58

About this skill

New Remotion Markup

Put timing on the content component

Discourage direct use of <Sequence> in new markup. It provides timing primitives that other components should inherit, rather than requiring an additional wrapper around the content.

Use built-in interactive components, media components that support timing, or custom components created with Interactive.withSchema({wrapInSequence: true}). Pass from, durationInFrames, trimBefore, playbackRate, and name directly to the component that supports them.

Avoid wrapping one timing-aware component in a <Sequence> just to schedule or name it. For custom components, prefer adding timing through Interactive.withSchema() instead of introducing another sequence at each call site. Keep a direct <Sequence> only when a necessary timing boundary cannot be expressed by the content components. Specialized containers such as <TransitionSeries.Sequence> still serve their own sequencing behavior.

When removing an existing wrapper, preserve its timing, dimensions, and premount behavior. Account for any timing already on the child; do not overwrite it or apply offsets twice. Preserve the distinction between the component's local frame and animation expressions evaluated in its parent.

Use a managed full-size layout

Discourage <AbsoluteFill> as a scene or component wrapper. It often creates an additional timeline layer that does not represent useful content. Prefer Interactive.withSchema() with wrapInSequence: true and layout: 'absolute-fill': the full-size container shares the component's timeline item.

The inner component can return a fragment. Put instance styles, timing, width, and height on the exported interactive component. Do not declare style, width, or height props on the inner component when using this layout; the wrapper owns them.

import {Interactive, useVideoConfig} from 'remotion';

const SceneInner = ({title}: {readonly title: string}) => (
  <>
    <Interactive.H1 name="Title" style={{color: 'white', fontSize: 80}}>
      {title}
    </Interactive.H1>
  </>
);

export const Scene = Interactive.withSchema({
  Component: SceneInner,
  componentName: 'Scene',
  schema: {
    title: {type: 'string', default: '', description: 'Title'},
    ...Interactive.backgroundSchema,
  },
  wrapInSequence: true,
  layout: 'absolute-fill',
});

export const MyVideo = () => {
  const {fps} = useVideoConfig();

  return <Scene name="Opening scene" from={fps} durationInFrames={3 * fps} title="A new perspective" style={{backgroundColor: '#111111'}} />;
};

The managed container clips overflow by default. Use style={{overflow: 'visible'}} on the exported component when needed. Keep additional layout containers only when they provide useful alignment, clipping, or grouping that the managed root does not supply. Components with their own bounds, such as text boxes or SVGs, can use the default layout: 'none' and forward style to their visual root.

For further guidance, see Remotion Interactivity and the Interactive.withSchema() API.