///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
type AppModeName = 'design' | 'build' | 'preview' | 'edit' | 'comment';
interface AppModeChangeEvent {
mode: AppModeName | null;
appModes: {[key in AppMode]: boolean};
}
type AppearanceSettings =
| 'darkDefault'
| 'darkDarker'
| 'darkBrighter'
| 'light';
type ThemeStyles = {
colors: Record;
boxShadows: Record;
controls: Record;
opacities: Record;
};
/**
* A media query (breakpoint) configured on the current site.
*
* Webflow supports up to 7 media queries: `tiny`, `small`, `medium`, `main`,
* `large`, `xl`, `xxl`. Sites start with 4 (`main`, `medium`, `small`, `tiny`)
* and users can add up to 3 more (`large`, `xl`, `xxl`) via the Designer.
* Additions are permanent.
*/
interface MediaQuery {
/** The media query identifier — one of `'tiny' | 'small' | 'medium' | 'main' | 'large' | 'xl' | 'xxl'`. */
id: BreakpointId;
/** User-facing label, e.g. `"Desktop"`, `"Tablet"`, `"Mobile"`, or `"1280px and up"`. */
name: string;
/** Minimum width in pixels for the media query, or `null` when unbounded below. */
minWidth: number | null;
/** Maximum width in pixels for the media query, or `null` when unbounded above. */
maxWidth: number | null;
/** True when this media query is the cascade base for the site (today: `main`). */
isBase: boolean;
}
interface SharedApi {
/**
* Get metadata about the current Site.
* @returns A Promise that resolves to a record containing information about the site that is open in the
* Designer, with the following properties:
* - siteId: the unique ID of the current Webflow site.
* - siteName: the name of the current Webflow site.
* - shortName: a shortened reference to the name of the current Webflow site.
* - kind: the type of site ('site' for standard Webflow sites).
* - isPasswordProtected: whether the site is password protected.
* - isPrivateStaging: whether the site has private staging turned on or not.
* - domains: an array of objects representing the domains associated with the site, each containing the following properties:
* - url: the URL of the domain.
* - lastPublished: the timestamp of the last time the domain was published.
* - default: a boolean indicating whether the domain is the default domain for the site.
* - stage: the target of the publish
* @example
* ```ts
* const siteInfo = await webflow.getSiteInfo();
* console.log('Site ID:', siteInfo.siteId);
* console.log('Site Name:', siteInfo.siteName);
* console.log('Shortened Site Name:', siteInfo.shortName);
* console.log('Site Kind:', siteInfo.kind);
* console.log('Domains:', siteInfo.domains);
* console.log('Workspace ID:', siteInfo.workspaceId);
* console.log('Workspace Slug:', siteInfo.workspaceSlug);
* ```
*/
getSiteInfo(): Promise<{
siteId: string;
siteName: string;
shortName: string;
kind: 'site';
isPasswordProtected: boolean;
isPrivateStaging: boolean;
workspaceId: string;
workspaceSlug: string;
domains: Array<{
url: string;
lastPublished: string | null;
default: boolean;
stage: 'staging' | 'production';
}>;
}>;
/**
* Get the list of media queries (breakpoints) configured for the current site.
*
* Ordered by **cascade specificity** — the same order Webflow's style cascade
* walks: the base (`main`) first, then ascending min-widths (`large`, `xl`,
* `xxl`), then descending max-widths (`medium`, `small`, `tiny`). This is the
* order partners want when reasoning about which styles apply at a given
* breakpoint; it is NOT a strict descending sort by viewport width.
*
* Sites start with 4 (`main`, `medium`, `small`, `tiny`). Users can add up to
* 3 more (`large`, `xl`, `xxl`) via the Designer; additions are permanent.
* @returns A Promise that resolves to an array of `MediaQuery` objects.
* @example
* ```ts
* const all = await webflow.getAllMediaQueries();
* for (const mq of all) {
* console.log(mq.id, mq.name, mq.isBase);
* }
* ```
*/
getAllMediaQueries(): Promise;
/**
* Renders the specified element to WHTML format.
* @param element - The element to render
* @returns A promise that resolves to an object containing the WHTML string and shortIdMap, or null
* @example
* ```ts
* const selectedElement = await webflow.getSelectedElement();
* if (selectedElement) {
* const result = await webflow.getWHTML(selectedElement);
* if (result) {
* console.log('WHTML:', result.whtml);
* console.log('Short ID Map:', result.shortIdMap);
* }
* }
* ```
*/
getWHTML?(
element: AnyElement
): Promise}>;
elementBuilder(elementPreset: ElementPreset): BuilderElement;
/**
* Parse a WHTML string and insert the resulting element as a child of the anchor element.
* The newly created element will be appended to the end of the anchor's children.
* @param whtml - The WHTML string to parse into an element
* @param anchor - The parent element to append the parsed WHTML element to
* @param position - The position relative to the anchor element where the new element will be inserted.
* - 'before': Insert as a sibling before the anchor element
* - 'after': Insert as a sibling after the anchor element
* - 'append': Insert as the last child of the anchor element (default)
* - 'prepend': Insert as the first child of the anchor element
* - 'replace': Replace the anchor element with the new element
* @returns A Promise that resolves to the newly inserted AnyElement
* @example
* ```ts
* const whtml = '';
* const body = await allElements.find((el) => el.type === 'Body');
* // Append as last child (default)
* const element = await webflow.insertElementFromWHTML(whtml, body);
* // Or insert before an existing element
* const existingElement = await webflow.getSelectedElement();
* const newElement = await webflow.insertElementFromWHTML(whtml, existingElement, 'before');
* // Or replace an existing element
* const replacedElement = await webflow.insertElementFromWHTML(whtml, existingElement, 'replace');
* ```
*/
insertElementFromWHTML?(
whtml: string,
anchor: AnyElement,
position?: 'before' | 'after' | 'append' | 'prepend' | 'replace'
): Promise;
/**
* Create a component by promoting a Root Element.
* @param name - The name of the component.
* @param root - An Element that will become the Root Element of the Component.
* @returns A Promise resolving to an object containing the newly created Component - with the id property.
* @deprecated Use `registerComponent(options, root)` instead to provide richer metadata.
* @example
* ```ts
* const element = webflow.createDOM('div')
* await webflow.registerComponent('Hero-Component', element)
*
* // Example Response
* {id: '204d04de-bf48-5b5b-0ca8-6ec4c5364fd2'}
* ```
*/
registerComponent(
name: string,
root: AnyElement | ElementPreset | AnyComponent
): Promise;
/**
* Create a blank component.
* @param options - Options for creating the blank component.
* @returns A Promise resolving to an object containing the newly created Component - with the id property.
* @example
* ```ts
* const component = await webflow.registerComponent({name: 'Hero Section'})
*
* // With optional group and description
* const grouped = await webflow.registerComponent({
* name: 'Hero Section',
* group: 'Sections',
* description: 'A hero section component',
* })
* ```
*/
registerComponent(options: ComponentOptions): Promise;
/**
* Duplicate an existing component.
* @param options - Options for the new component, including a required name.
* @param source - The existing Component to duplicate.
* @returns A Promise resolving to the newly created Component.
* @example
* ```ts
* const [original] = await webflow.getAllComponents()
* const copy = await webflow.registerComponent({name: 'Hero Copy'}, original)
* ```
*/
registerComponent(
options: ComponentOptions,
source: AnyComponent
): Promise;
/**
* Duplicate an existing component by ID.
* @param options - Options for the new component, including a required name.
* @param source - The ID of the existing Component to duplicate.
* @returns A Promise resolving to the newly created Component.
* @example
* ```ts
* const copy = await webflow.registerComponent({name: 'Hero Copy'}, '204d04de-bf48-5b5b-0ca8-6ec4c5364fd2')
* ```
*/
registerComponent(
options: ComponentOptions,
source: string
): Promise;
/**
* Convert an element or element preset into a component. Equivalent to the
* "Convert selection" action in the Designer's "New component" menu.
* Elements do not need to be on the page. You can build the tree with
* `createDOM` first and pass it directly.
*
* When `root` is a canvas `AnyElement`, the source element is replaced
* in-place by a new component instance by default. Pass `replace: false`
* in `options` to skip this substitution and keep the original element.
* @param options - Options for the new component. `name` is required;
* `group`, `description`, and `replace` are optional.
* @param root - The element, element preset, or builder element that becomes the component root.
* @returns A Promise resolving to the newly created Component.
* @example
* ```ts
* // Convert a canvas element and replace it with a component instance (default)
* const el = await webflow.getSelectedElement()
* const card = await webflow.registerComponent({name: 'Card', group: 'UI'}, el)
*
* // Convert without replacing the original element in the canvas
* const card2 = await webflow.registerComponent(
* {name: 'Card 2', replace: false},
* el
* )
*/
registerComponent(
options: ComponentOptions,
root: AnyElement | ElementPreset | BuilderElement
): Promise;
/**
* Delete a component from the Designer. If there are any instances of the Component within the site, they will
* be converted to regular Elements.
* @param component - The component object you wish to delete.
* @returns A Promise resolving that resolves when the Component is deleted.
* @example
* ```ts
* const element = webflow.createDOM('div')
* const heroComponent = await webflow.registerComponent('Hero-Component', element)
* await webflow.unregisterComponent(heroComponent)
* ```
*/
unregisterComponent(component: AnyComponent): Promise;
/**
* Fetch all Site-scoped components definitions. In order to edit a component, you’ll need to get a specific
* Component instance.
* @returns A Promise resolving to an array containing all Components from the currently open site in the
* Designer - with the id property.
* @example
* ```ts
* const fetchedComponents = await webflow.getAllComponents();
*
* // Example Response
* [
* {id: "4a669354-353a-97eb-795c-4471b406e043"}
* {id: 'd6e076e2-19a2-c4ae-9da3-ce3b0493b503'}
* ]
* ```
*/
getAllComponents(): Promise>;
/**
* Search site components with optional fuzzy filtering.
* Returns a flat array of {@link ComponentSearchResult} objects in the same order as the
* Components panel (insertion order). When `options.q` is provided, results are filtered
* using FlexSearch (`tokenize: 'full'`) — the same algorithm used by the Components panel.
*
* @param options - Optional search options.
* @param options.q - Search query string. Omit or leave empty to return all components.
* @returns A Promise resolving to an array of {@link ComponentSearchResult} objects.
*
* @example
* ```ts
* // Get all components
* const all = await webflow.searchComponents();
*
* // Filter by name
* const heroes = await webflow.searchComponents({ q: 'Hero' });
* heroes.forEach(c => {
* console.log(c.name, c.instances, c.canEdit, c.library);
* });
* ```
*/
searchComponents(
options?: SearchComponentsOptions
): Promise;
/**
* Returns a component reference when the user is editing in-context or on the component canvas, or null if no component is being edited.
* @returns A Promise that resolves to a Component reference or null.
* @example
* ```ts
* const component = await webflow.getCurrentComponent();
* if (component) {
* const name = await component.getName();
* console.log(`Currently editing: ${name}`);
* }
* ```
*/
getCurrentComponent(): Promise;
/**
* Get a Component by its unique identifier.
* @param id - The unique identifier of the component.
* @returns A Promise that resolves to the Component with the given id.
* @example
* ```ts
* const componentId = '4a669354-353a-97eb-795c-4471b406e043';
* const component = await webflow.getComponent(componentId);
* ```
*/
getComponent(id: ComponentId): Promise;
/**
* Get a Component by its display name.
* Throws when the matched component is a non-code library component.
* Use a library-scoped overload to retrieve direct library components.
* @param name - The display name of the component.
* @example
* ```ts
* const component = await webflow.getComponentByName('Hero');
* ```
*/
getComponentByName(name: string): Promise;
/**
* Get a Component by its group and display name.
* If the first argument matches an installed library ID, the lookup is
* library-scoped. Otherwise, it is treated as a site component group lookup.
* Throws when a site component group lookup matches a non-code library component.
* @param groupOrLibraryId - The group name the site component belongs to, or an installed library ID.
* @param name - The display name of the component.
* @example
* ```ts
* const component = await webflow.getComponentByName('Marketing', 'Hero');
* const libraryComponent = await webflow.getComponentByName(libraryId, 'Hero');
* ```
*/
getComponentByName(
groupOrLibraryId: string,
name: string
): Promise;
/**
* Get a library Component by its library ID, group, and display name.
* @param libraryId - The installed library ID.
* @param group - The group name the library component belongs to.
* @param name - The display name of the component.
* @example
* ```ts
* const component = await webflow.getComponentByName(libraryId, 'Marketing', 'Hero');
* ```
*/
getComponentByName(
libraryId: string,
group: string,
name: string
): Promise;
/**
* Focus the designer on a Component. When a component is in focus, all Globals pertain specifically to that
* Component, not the entire Site.
* @param instance - A Component Instance that is present on the page. If there’s no current instance, you’ll
* need to create one first.
* @returns A Promise that resolves when the page switch is successful.
* @example
* ```ts
* await webflow.enterComponent(heroComponentInstance);
* ```
*/
enterComponent(instance: ComponentElement): Promise;
/**
* Return to the broader context of the entire site or page.
* @returns A Promise that resolves when the page switch is successful.
* @example
* ```ts
* await webflow.exitComponent();
* ```
*/
exitComponent(): Promise;
/**
* Navigate the Designer to a component canvas or page.
* @param options - An object with either pageId or componentId.
* @returns A Promise that resolves when the navigation is complete.
* @example
* ```ts
* // Open a component canvas by component id
* await webflow.openCanvas({componentId: '4a669354-353a-97eb-795c-4471b406e043'});
*
* // Open a component canvas by page id
* await webflow.openCanvas({pageId: '123'});
* ```
*/
openCanvas(
options: OpenCanvasByComponentId | OpenCanvasByPageId
): Promise;
/**
* Navigate the Designer to a component canvas or page using a reference.
* @param reference - A Component, ComponentElement, or Page reference.
* @returns A Promise that resolves when the navigation is complete.
* @example
* ```ts
* // Open a component canvas by component
* const heroComponent = await webflow.getComponent('4a669354-353a-97eb-795c-4471b406e043');
* await webflow.openCanvas(heroComponent);
*
* // Open a component canvas by component instance (ComponentElement)
* const selectedElement = await webflow.getSelectedElement();
* if (selectedElement?.type === 'ComponentInstance') {
* await webflow.openCanvas(selectedElement);
* }
*
* // Open a page canvas by page
* const myPage = await webflow.getPage('123');
* await webflow.openCanvas(myPage);
* ```
*/
openCanvas(reference: AnyComponent | ComponentElement | Page): Promise;
/**
* Get Root element. When the designer is focused or "entered" into a Component, this method will get the
* outermost element in the Component.
* @returns The outermost element of the Page or Component.
* @example
* ```ts
* // 🎉 Enter into Component 🎉
* await webflow.enterComponent(heroComponentInstance)
* const root = await webflow.getRootElement()
*
* // Example Response
* {id: '204d04de-bf48-5b5b-0ca8-6ec4c5364fd2'}
* ```
*/
getRootElement(): Promise;
/**
* Fetch an array of all elements present on the current page of the Designer. If the Designer is editing a
* component, the elements returned are those present in that Component.
* @returns A Promise that resolves to an array of AnyElement objects. AnyElement represents various element
* types available in a Webflow project. Each element type corresponds to different types of HTML elements or
* components that can be used within the designer. You can see a full list of supported elements in our
* designer extensions typing file.
* @example
* ```ts
* const allElements = await webflow.getAllElements()
* const paragraphs = allElements.flatMap(el => el.type === 'Paragraph' ? [el] : [])
* paragraphs.forEach(el => {
* el.setTextContent('Hello')
* el.save()
* })
* ```
*/
getAllElements(): Promise>;
/**
* Creates a new style with the provided name.
* @param name - The name for the new style
* @param options - Options for the new style. An object containing the following properties:
* - parent: A Style object representing the parent style block. Used for creating a combo class.
* @returns a Promise that resolves to the Style object representing the newly created style.
* @example
* ```ts
* const newStyle = await webflow.createStyle('myNewStyle');
* console.log('New style created:', newStyle.id);
*
* const comboClass = await webflow.createStyle('myNewStyle', {parent: newStyle});
* console.log('New combo class created: ', comboClass.id);
* ```
*/
createStyle(name: string, options?: {parent?: Style}): Promise