Skip to navigation

Interaction schema

Every field and value that webflow.interactions accepts. For a complete create call for each trigger type, see Interaction examples.

Read the interaction back after every write

The API drops some misplaced fields without an error. After each create or set, call get and compare the result with what you sent.

Shape

create(params)
{
pageId: string;
name: string;
scope?: Scope; // default {type: 'site'}
triggers: Trigger[]; // up to 20
timelines: Timeline[]; // up to 5
conditionalPlayback?: ConditionalPlayback[];
}
Scope
{type: 'site'} // every page
{type: 'pages'; value: string[]} // page ids
{type: 'component'; componentId: string; variants?: string[]} // omit variants for all variants
Trigger
{
extensionKey: string; // see Triggers
config: {
control?: 'play' | 'restart' | 'reverse' | 'reverseFlipEase' | 'pause' | 'resume'
| 'togglePlayReverse' | 'togglePlayReverseFlipEase' | 'stop' | 'none';
delay?: number | string; // seconds or '500ms'
jump?: number | string; // seconds or '500ms'
speed?: number; // 0 to 10
pluginConfig?: object; // see Triggers
scrollTriggerConfig?: object; // wf:scroll only
assignedGroupId?: string; // matches Timeline.groupId
};
target?: Target;
}
Timeline
{
id?: string; // omit on create; keep on set
name?: string;
groupId?: string;
triggerMetadata?: {role: string}; // hover and mouse move only
canvasDuration?: 1; // scroll scrub, mouseX, and mouseY only
settings?: {
control?: string;
delay?: number | string;
jump?: number | string;
speed?: number; // 0 to 10
repeat?: number; // -1 or 0 and up
yoyo?: boolean;
};
actions: Action[]; // up to 200
}
Action
{
id: string; // unique
name: string; // not empty
tt?: 0 | 1 | 2 | 3; // to, from, from-to, set
timing: Timing;
properties: {[actionType: string]: {[property: string]: Value}};
targets: Target[]; // up to 20
splitText?: {type: 'chars' | 'words' | 'lines'; mask?: 'chars' | 'words' | 'lines'};
hidden?: boolean; // left out of Preview and the published page
}
Target
{
extensionKey: string; // see Targets
value: string | string[];
filterContext?: {
relationship: string; // see Filters
filterBy: [string, unknown]; // [extensionKey, value]
firstMatchOnly?: boolean;
};
}

Triggers

TriggerextensionKeyTargetpluginConfigTimeline rolescontrolOther triggers
Clickwf:clickRequiredclick: each, first, second, odd, even, or custom. custom: a number, 1 or more.NoneAll except noneAllowed
Hoverwf:hoverRequiredmultiTimeline: boolean. eventMode: both, enter, or leave, next to multiTimeline.mouseEnter, mouseLeave when multiTimeline is trueAllAllowed
Page loadwf:loadNot allowedNot allowedNoneplay, noneAllowed. One page load trigger at most.
Scrollwf:scrollRequiredNoneNoneNot allowedNot allowed
Mouse movewf:mouse-movewf:viewport or an elementsmoothness: 0 to 2000 ms, default 50. restingState: {x, y}, 0 to 100 each, default 50.mouseX, mouseY, interval. One timeline per role.Not allowedNot allowed
Custom eventwf:customwf:body onlyeventName: a non-empty stringNoneAllAllowed
  • Scroll and mouse move triggers reject control, delay, jump, and speed.
  • jump is not allowed with control none, restart, resume, togglePlayReverse, or togglePlayReverseFlipEase.
  • speed is not allowed with control pause, stop, or none.
  • Click with click other than each rejects togglePlayReverse and togglePlayReverseFlipEase.
  • Two or more timelines with a groupId require control: 'play' on each trigger.

Scroll trigger config

scrollTriggerConfig fieldValue
startRequired. '<element position> <viewport position>', such as 'top 85%'
endRequired. Same format as start
scrubOptional. Seconds, such as 0.3. Ties the animation to the scroll position.
enter, leave, enterBack, leaveBackplay, pause, resume, reverse, restart, reset, complete, or none
pinOptional boolean

A position is top, center, bottom, left, right, a length such as '50%' or '-20px', or a keyword with an offset such as 'top+=50'.

Action properties

Write each value as one of these:

  • A single value, which plays as a To tween, such as '50%'
  • [from], [from, to], or [null, to]
  • A value wrapper

A bare number uses the property’s default unit. Opacity and Alpha are the exception: write them as percent strings, because a bare number is read on a 0 to 1 scale.

Length units: px, %, em, rem, ch, vw, vh, dvw, dvh, svw, svh, lvw, and lvh.

wf:transform

PropertyPanel labelValueExampleRangeRandomRelative
opacityOpacityPercent string'50%'0% to 100%✓✓
autoAlphaAlphaPercent string'0%'0% to 100%✓✓
displayDisplayblock, inline, inline-block, inline-flex, inline-grid, flex, grid, or none. Set only.'none'✗✗
xMove XLength string'40px'Any✓✓
yMove YLength string'-20px'Any✓✓
xPercentX %Percent string'-40%'Any✓✓
yPercentY %Percent string'10%'Any✓✓
scaleScaleNumber1.20 or more✓✓
scaleXScale XNumber0.50 or more✓✓
scaleYScale YNumber20 or more✓✓
zScale ZNumber10 or more✓✓
skewXSkew XDegree string'10deg'Any✓✓
skewYSkew YDegree string'-10deg'Any✓✓
rotationRotateDegree string'45deg'Any✓✓
rotationXRotate XDegree string'180deg'Any✓✓
rotationYRotate YDegree string'90deg'Any✓✓
transformPerspectivePerspectiveNumber8000 or more✓✓
transformOriginOriginTwo lengths, x then y. One value for the whole tween.'50% 50%'✗✗
widthWidthLength string, or 'auto''200px'0 or more✓✓
heightHeightLength string, or 'auto''50vh'0 or more✓✓

transformOrigin accepts px, %, em, vw, vh, dvw, dvh, svw, svh, lvw, and lvh.

wf:style

PropertyPanel labelValueExampleRangeRandomRelative
backgroundColorBackgroundHex color string'#1a1a2e'Picks only✗
borderColorBorderHex color string'#7a4de8'Picks only✗
colorTextHex color string'#ffffff'Picks only✗
zIndexZ-IndexInteger. Set only.100 to 2147483647✗✗
positionPositionstatic, relative, absolute, fixed, or sticky. Set only.'absolute'✗✗
overflowOverflowvisible, hidden, scroll, auto, or clip. Set only.'hidden'✗✗
pointerEventsEventsauto or none. Set only.'none'✗✗

Animate opacity under wf:transform, not wf:style. Set-only properties require tt: 3.

wf:class

PropertyPanel labelValue
classClass{operation, selectors}. operation is addClass, removeClass, or toggleClass. selectors is an array of style block ids. Set only.

Other action types

Action typePropertyValue
wf:lottielottie{from, to}. Each is a number or a variable.
wf:lottiemanualDurationBoolean
wf:splineobjectIdString
wf:splineanimatingStateBoolean
wf:splinesplineAn object of channels, each {from?, to?}. Channels: positionX, positionY, positionZ, rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ, intensity, opacity, zoom, color, stateName.
wf:mouse-followfollowModefull, x-only, or y-only. Default full.
wf:mouse-followonEnteranimate or snap. Default animate.
wf:mouse-followleaveBehaviorreturn or stay. Default return.
wf:mouse-followanchorTwo lengths, x then y, such as '50% 50%'. Default is the center.
wf:mouse-followaxisx or y. The timeline role sets it.
wf:variablevariable{variables: [{variableId, value}]}. See Variable values.
wf:riverive{animationSource, addedProperties}. See Rive values.
wf:animate-riveriveSame as wf:rive. propertyType is number or color only.

wf:mouse-follow is valid only on a mouseX or mouseY timeline of a mouse move interaction, one per timeline. y-only conflicts with mouseX, and x-only conflicts with mouseY.

Variable values

value.typevalue.valueExample
length{value: number, unit: string}{type: 'length', value: {value: 16, unit: 'px'}}
percentage{value: number, unit: '%'}{type: 'percentage', value: {value: 50, unit: '%'}}
number{value: number, unit: '-'}{type: 'number', value: {value: 2, unit: '-'}}
colorColor string{type: 'color', value: '#1a1a2e'}
ref{variableId}{type: 'ref', value: {variableId: 'variable-id'}}

value: null leaves the variable unset.

Rive values

FieldValue
animationSourcenull or {name, instanceName?}. Required when addedProperties has entries.
addedPropertiesAn object of {propertyName, propertyType, value?} entries. Each key ends with : and the property name.
propertyTypestring, number, boolean, color, enum, trigger, or artboard

Value wrappers

WrapperShapeWorks on
Random range{type: 'ix3-random', min: number, max: number, step?: number, unit?: string}Properties marked ✓ under Random
Random pick{type: 'ix3-random-array', values: [...], unit?: string}Properties marked ✓ or “Picks only”. 2 to 12 values. Colors use hex strings.
Relative{type: 'ix3-additive', value: number, unit?: string}Properties marked ✓ under Relative. value can also be a random range.
Variable{type: 'ref', value: {variableId: string}}Number, length, percent, degree, and color properties

Put the unit in unit, not in the number.

Wrapper examples
x: {type: 'ix3-random', min: -100, max: 100, unit: 'px'},
rotation: {type: 'ix3-additive', value: 90, unit: 'deg'},
backgroundColor: {type: 'ix3-random-array', values: ['#1a1a2e', '#7a4de8']},

Tween types

ttNameValue formExample
0ToA single value, or [null, to]'50%'
1From[from] or [from, null]['0%']
2From-to[from, to]['0%', '100%']
3SetA single value'none'
  • If you omit tt, the API stores 2 for [from, to] and 1 for all-from values. Single values play as To.
  • [from, to] with tt 0, 1, or 3 is rejected. So is mixing from-only and to-only values without tt.
  • A {from, to} object is rejected, except on Lottie and Spline.

Timing

FieldValue
durationSeconds, or a string such as '400ms'. 400 means 400 seconds.
positionSeconds, or a string such as '500ms'. +=, <, and > are rejected.
easeAn index from 0 to 30, or an advanced ease object. Strings are rejected.
staggerAn object. See Stagger.
repeatA number. -1 repeats without end.
repeatDelaySeconds, or a string such as '200ms'
yoyoBoolean

An action’s timing rejects delay and autoReverse.

Stagger

FieldValue
eachSeconds between targets, or a string such as '50ms'
amountTotal seconds split across targets, or a string such as '300ms'
axisx or y
fromstart, center, end, edges, random, or a number
easeSame values as timing.ease
grid'auto' or [columns, rows]

Ease

IndexEaseIndexEase
0none16bounce.in
1power1.in17bounce.out
2power1.out18bounce.inOut
3power1.inOut19circ.in
4power2.in20circ.out
5power2.out21circ.inOut
6power2.inOut22elastic.in
7power3.in23elastic.out
8power3.out24elastic.inOut
9power3.inOut25expo.in
10power4.in26expo.out
11power4.out27expo.inOut
12power4.inOut28sine.in
13back.in29sine.out
14back.out30sine.inOut
15back.inOut
Advanced typeFields
backcurve, power
elasticcurve, amplitude, period
stepsstepCount
roughtemplateCurve, points, strength, taper, randomizePoints, clampPoints
slowMolinearRatio, power, yoyoMode
expoScalestartingScale, endingScale, templateCurve
customWigglewiggles, wiggleType
customBouncestrength, squash, endAtStart
customEasebezierCurve

curve is in, out, or inOut. taper is none, in, out, or both. wiggleType is easeOut, easeInOut, anticipate, uniform, or random. Extra fields are rejected.

Ease examples
timing: {duration: 0.4, ease: 2},
timing: {duration: 0.4, ease: {type: 'back', curve: 'out', power: 1.7}},

Targets

TargetvalueOn a triggerOn an action
wf:classA class slug, or an array of style block ids✓✓
wf:selectorA CSS selector✓✓
wf:attribute'[name]' or '[name="value"]'✓✓
wf:inst[ownerId, elementId]✓✓
wf:body''Scroll and custom event only✗
wf:viewport''Mouse move only✗
wf:trigger-only'', the element that fired the trigger✗✓
wf:trigger-only-parent'', the parent of that element✗✓
wf:any-element'*', with a filter relationship other than none✗✓
  • A class slug must match exactly one class. Otherwise, pass style block ids from webflow.getStyleByName or webflow.getAllStyles.
  • For wf:inst, ownerId is the page id on a site or pages scope, and the component id on a component scope.
  • wf:id is rejected. Use wf:selector, wf:class, or wf:inst.

Filters

FieldValue
relationshipnone, within, direct-child-of, contains, direct-parent-of, next-to, next-sibling-of, or prev-sibling-of
filterBy[extensionKey, value] using wf:class, wf:selector, wf:attribute, wf:inst, wf:trigger-only, or wf:trigger-only-parent
firstMatchOnlyBoolean. true needs a relationship other than none.

Conditional playback

ConditionalPlayback
{type: 'prefers-reduced-motion'; behavior: 'dont-animate' | 'skip-to-end'}
{type: 'breakpoint'; breakpoints: ('main' | 'medium' | 'small' | 'tiny')[]; behavior: 'dont-animate' | 'skip-to-end'}

One row per type. Mouse move interactions accept dont-animate only.

Limits

ItemMaximum
Triggers per interaction20
Timelines per interaction5
Actions per timeline200
Targets per action20
Random pick values12

Not accepted

Field or valueUse instead
wf:navbar, wf:dropdown, wf:focus, wf:blur, and wf:change triggersNone
config.conditionalLogicconditionalPlayback
config.assignedTimelineRole on a new triggerassignedGroupId
wf:id targetwf:selector, wf:class, or wf:inst
timing.delay on an actiontiming.position, or delay on the trigger or timeline settings
timing.autoReverserepeat with yoyo
timelineDefaults on createOmit it
Timeline actionPresetIds, previewSpeed, playInReverse, and immediateOmit them
scrub: trueSeconds, such as 0.3
Ease names, such as 'power2.out'An index from the ease table

Stored differently

You sendget returns
An unknown field on config, timing, or staggerNothing. The field is dropped.
A class slugStyle block ids. Combo classes include parent ids.
'data-state' on wf:attribute'[data-state]'
'500ms'0.5
delay: null0.25
No scope{type: 'site'}
No scroll enter, leave, enterBack, or leaveBackplay, none, none, none
No tt1 or 2, when the values imply it
No filterContext{relationship: 'none', filterBy: ['wf:class', []], firstMatchOnly: false}
An ease index above 30The index. The action plays with no easing.