## File: README.md

# [GrapesJS](http://grapesjs.com)

[](https://github.com/GrapesJS/grapesjs/actions)
[](https://discord.gg/QAbgGXq)
[](https://cdnjs.com/libraries/grapesjs)
[](https://www.npmjs.com/package/grapesjs)

> If you looking to embed the [Studio](https://app.grapesjs.com/studio) editor in your application, we now offer the [Studio SDK](https://app.grapesjs.com/dashboard/sdk/licenses?ref=repo-readme), a ready-to-use visual builder that's easy to embed in external applications, with GrapesJS team support included.



GrapesJS is a free and open source Web Builder Framework which helps building HTML templates, faster and easily, to be delivered in sites, newsletters or mobile apps. Mainly, GrapesJS was designed to be used inside a [CMS] to speed up the creation of dynamic templates. To better understand this concept check the image below





Generally any 'template system', that you'd find in various applications like CMS, is composed by the **structure** (HTML), **style** (CSS) and **variables**, which are then replaced with other templates and contents on server-side and rendered on client.

This demos show examples of what is possible to achieve:
Webpage Demo - http://grapesjs.com/demo.html
Newsletter Demo - http://grapesjs.com/demo-newsletter-editor.html

## Table of contents

- [Features](#features)
- [Download](#download)
- [Usage](#usage)
- [Development](#development)
- [Documentation](#documentation)
- [API](#api)
- [Testing](#testing)
- [Plugins](#plugins)
- [Support](#support)
- [Changelog](https://github.com/GrapesJS/grapesjs/releases)
- [Contributing](https://github.com/GrapesJS/grapesjs/blob/dev/CONTRIBUTING.md)
- [License](#license)

## Features

| Blocks                                                                                                                                   | Style Manager                                                                                                                         | Layer Manager                                                                                                                          |
| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|  |  |  |

| Code Viewer                                                                                                                      | Asset Manager                                                                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|  |  |

- Local and remote storage

- Default built-in commands (basically for creating and managing different components)

## Download

- CDNs
  - UNPKG (resolves to the latest version)
    - `https://unpkg.com/grapesjs`
    - `https://unpkg.com/grapesjs/dist/css/grapes.min.css`
  - CDNJS (replace `X.X.X` with the current version)
    - `https://cdnjs.cloudflare.com/ajax/libs/grapesjs/X.X.X/grapes.min.js`
    - `https://cdnjs.cloudflare.com/ajax/libs/grapesjs/X.X.X/css/grapes.min.css`
- NPM
  - `npm i grapesjs`
- GIT
  - `git clone https://github.com/GrapesJS/grapesjs.git`

For the development purpose you should follow instructions below.

## Usage

```html
<link rel="stylesheet" href="path/to/grapes.min.css" />
<script src="path/to/grapes.min.js"></script>



<script type="text/javascript">
  var editor = grapesjs.init({
    container: '#gjs',
    components: 'Hello world!',
    style: '.txt-red{color: red}',
  });
</script>
```

For a more practical example I'd suggest looking up the code inside this demo: http://grapesjs.com/demo.html

## Development

Follow the [Contributing Guide](https://github.com/GrapesJS/grapesjs/blob/dev/CONTRIBUTING.md).

## Documentation

Check the getting started guide here: [Documentation]

## API

API References could be found here: [API-Reference]

## Testing

```sh
$ pnpm test
```

## Plugins

[Official Plugins](https://github.com/orgs/GrapesJS/repositories?q=-repo%3Agrapesjs%2Fgrapesjs&type=source) | [Community Plugins](https://github.com/topics/grapesjs-plugin)

### Wrappers

- [@grapesjs/react](https://github.com/GrapesJS/react) - GrapesJS wrapper for React that allows you to build custom and declarative UI for your editor.

### Extensions

- [grapesjs-plugin-export](https://github.com/GrapesJS/export) - Export GrapesJS templates in a zip archive
- [grapesjs-plugin-filestack](https://github.com/GrapesJS/filestack) - Add Filestack uploader in Asset Manager
- [grapesjs-plugin-ckeditor](https://github.com/GrapesJS/ckeditor) - Replaces the built-in RTE with CKEditor
- [grapesjs-tui-image-editor](https://github.com/GrapesJS/tui-image-editor) - GrapesJS TOAST UI Image Editor
- [grapesjs-blocks-basic](https://github.com/GrapesJS/blocks-basic) - Basic set of blocks
- [grapesjs-plugin-forms](https://github.com/GrapesJS/components-forms) - Set of form components and blocks
- [grapesjs-navbar](https://github.com/GrapesJS/components-navbar) - Simple navbar component
- [grapesjs-component-countdown](https://github.com/GrapesJS/components-countdown) - Simple countdown component
- [grapesjs-style-gradient](https://github.com/GrapesJS/style-gradient) - Add `gradient` type input to the Style Manager
- [grapesjs-style-filter](https://github.com/GrapesJS/style-filter) - Add `filter` type input to the Style Manager
- [grapesjs-style-bg](https://github.com/GrapesJS/style-bg) - Full-stack background style property type, with the possibility to add images, colors, and gradients
- [grapesjs-blocks-flexbox](https://github.com/GrapesJS/blocks-flexbox) - Add the flexbox block
- [grapesjs-lory-slider](https://github.com/GrapesJS/components-lory) - Slider component by using [lory](https://github.com/meandmax/lory)
- [grapesjs-tabs](https://github.com/GrapesJS/components-tabs) - Simple tabs component
- [grapesjs-tooltip](https://github.com/GrapesJS/components-tooltip) - Simple, CSS only, tooltip component for GrapesJS
- [grapesjs-custom-code](https://github.com/GrapesJS/components-custom-code) - Embed custom code
- [grapesjs-touch](https://github.com/GrapesJS/touch) - Enable touch support
- [grapesjs-indexeddb](https://github.com/GrapesJS/storage-indexeddb) - Storage wrapper for IndexedDB
- [grapesjs-firestore](https://github.com/GrapesJS/storage-firestore) - Storage wrapper for [Cloud Firestore](https://firebase.google.com/docs/firestore)
- [grapesjs-parser-postcss](https://github.com/GrapesJS/parser-postcss) - Custom CSS parser for GrapesJS by using [PostCSS](https://github.com/postcss/postcss)
- [grapesjs-typed](https://github.com/GrapesJS/components-typed) - Typed component made by wrapping Typed.js library
- [grapesjs-ui-suggest-classes](https://github.com/silexlabs/grapesjs-ui-suggest-classes) - Enable auto-complete of classes in the SelectorManager UI
- [grapesjs-fonts](https://github.com/silexlabs/grapesjs-fonts) - Custom Fonts plugin, adds a UI to manage fonts in websites
- [grapesjs-symbols](https://github.com/silexlabs/grapesjs-symbols) - Symbols plugin to reuse elements in a website and accross pages
- [grapesjs-click](https://github.com/bgrand-ch/grapesjs-click) - Grab and drop blocks and components with click (no more drag-and-drop)
- [grapesjs-float](https://github.com/bgrand-ch/grapesjs-float) - Anchor a floating element next to another element (selected component, ...)

### Presets

- [grapesjs-preset-webpage](https://github.com/GrapesJS/preset-webpage) - Webpage Builder
- [grapesjs-preset-newsletter](https://github.com/GrapesJS/preset-newsletter) - Newsletter Builder
- [grapesjs-mjml](https://github.com/GrapesJS/mjml) - Newsletter Builder with MJML components

Find out more about plugins here: [Creating plugins](https://grapesjs.com/docs/modules/Plugins.html)

## Support

If you like the project and you wish to see it grow, please consider supporting us with a donation of your choice or become a backer/sponsor via [Open Collective](https://opencollective.com/grapesjs)

[](https://paypal.me/grapesjs)
[](https://commerce.coinbase.com/checkout/fc90b940-558d-408b-a166-28a823c98173)

[](https://opencollective.com/grapesjs)
[](https://opencollective.com/grapesjs)



[](https://www.browserstack.com)
Thanks to [BrowserStack](https://www.browserstack.com) for providing us browser testing services

## License

BSD 3-clause

[Documentation]: https://grapesjs.com/docs/
[API-Reference]: https://grapesjs.com/docs/api/
[CMS]: https://en.wikipedia.org/wiki/Content_management_system

---

## File: docs/api/asset.md

## Asset

### Properties

*   `type` **[String][1]** Asset type, eg. `'image'`.
*   `src` **[String][1]** Asset URL, eg. `'https://.../image.png'`.

## getType

Get asset type.

### Examples

```javascript
// Asset: { src: 'https://.../image.png', type: 'image' }
asset.getType(); // -> 'image'
```

Returns **[String][1]**&#x20;

## getSrc

Get asset URL.

### Examples

```javascript
// Asset: { src: 'https://.../image.png'  }
asset.getSrc(); // -> 'https://.../image.png'
```

Returns **[String][1]**&#x20;

## getFilename

Get filename of the asset (based on `src`).

### Examples

```javascript
// Asset: { src: 'https://.../image.png' }
asset.getFilename(); // -> 'image.png'
// Asset: { src: 'https://.../image' }
asset.getFilename(); // -> 'image'
```

Returns **[String][1]**&#x20;

## getExtension

Get extension of the asset (based on `src`).

### Examples

```javascript
// Asset: { src: 'https://.../image.png' }
asset.getExtension(); // -> 'png'
// Asset: { src: 'https://.../image' }
asset.getExtension(); // -> ''
```

Returns **[String][1]**&#x20;

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

---

## File: docs/api/assets.md

## Assets

You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object][1]

```js
const editor = grapesjs.init({
 assetManager: {
   // options
 }
})
```

Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance

```js
const assetManager = editor.AssetManager;
```

## Available Events
* `asset:add` New asset added to the collection. The [Asset] is passed as an argument to the callback.

```javascript
editor.on('asset:add', (asset) => { ... });
```

* `asset:remove` Asset removed from the collection. The [Asset] is passed as an argument to the callback.

```javascript
editor.on('asset:remove', (asset) => { ... });
```

* `asset:update` Asset updated. The [Asset] and the object containing changes are passed as arguments to the callback.

```javascript
editor.on('asset:update', (asset, updatedProps) => { ... });
```

* `asset:open` Asset Manager opened.

```javascript
editor.on('asset:open', () => { ... });
```

* `asset:close` Asset Manager closed.

```javascript
editor.on('asset:close', () => { ... });
```

* `asset:upload:start` Asset upload start.

```javascript
editor.on('asset:upload:start', () => { ... });
```

* `asset:upload:end` Asset upload end.

```javascript
editor.on('asset:upload:end', (result) => { ... });
```

* `asset:upload:error` Asset upload error.

```javascript
editor.on('asset:upload:error', (error) => { ... });
```

* `asset:upload:response` Asset upload response.

```javascript
editor.on('asset:upload:response', (res) => { ... });
```

* `asset:custom` Event to use in case of [custom Asset Manager UI](https://grapesjs.com/docs/modules/Assets.html#customization).

```javascript
editor.on('asset:custom', ({ container, assets, ... }) => { ... });
```

* `asset` Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.

```javascript
editor.on('asset', ({ event, model, ... }) => { ... });
```

## Methods

*   [open][2]
*   [close][3]
*   [isOpen][4]
*   [add][5]
*   [get][6]
*   [getAll][7]
*   [getAllVisible][8]
*   [remove][9]
*   [getContainer][10]

[Asset]: asset.html

## open

Open the asset manager.

### Parameters

*   `options` **[Object][11]?** Options for the asset manager. (optional, default `{}`)

    *   `options.types` **[Array][12]<[String][13]>** Types of assets to show. (optional, default `['image']`)
    *   `options.select` **[Function][14]?** Type of operation to perform on asset selection. If not specified, nothing will happen.

### Examples

```javascript
assetManager.open({
 select(asset, complete) {
   const selected = editor.getSelected();
   if (selected && selected.is('image')) {
     selected.addAttributes({ src: asset.getSrc() });
     // The default AssetManager UI will trigger `select(asset, false)` on asset click
     // and `select(asset, true)` on double-click
     complete && assetManager.close();
   }
 }
});
// with your custom types (you should have assets with those types declared)
assetManager.open({ types: ['doc'], ... });
```

## close

Close the asset manager.

### Examples

```javascript
assetManager.close();
```

## isOpen

Checks if the asset manager is open

### Examples

```javascript
assetManager.isOpen(); // true | false
```

Returns **[Boolean][15]** 

## add

Add new asset/s to the collection. URLs are supposed to be unique

### Parameters

*   `asset` **([String][13] | [Object][11] | [Array][12]<[String][13]> | [Array][12]<[Object][11]>)** URL strings or an objects representing the resource.
*   `opts` **[Object][11]?** Options (optional, default `{}`)

### Examples

```javascript
// As strings
assetManager.add('http://img.jpg');
assetManager.add(['http://img.jpg', './path/to/img.png']);

// Using objects you can indicate the type and other meta informations
assetManager.add({
 // type: 'image',	// image is default
	src: 'http://img.jpg',
	height: 300,
width: 200,
});
assetManager.add([{ src: 'img2.jpg' }, { src: 'img2.png' }]);
```

Returns **[Asset]** 

## get

Return asset by URL

### Parameters

*   `src` **[String][13]** URL of the asset

### Examples

```javascript
const asset = assetManager.get('http://img.jpg');
```

Returns **([Asset] | null)** 

## getAll

Return the global collection, containing all the assets

Returns **Collection<[Asset]>** 

## getAllVisible

Return the visible collection, which contains assets actually rendered

Returns **Collection<[Asset]>** 

## remove

Remove asset

### Parameters

*   `asset` **([String][13] | [Asset])** Asset or asset URL
*   `opts` **RemoveOptions?** 

### Examples

```javascript
const removed = assetManager.remove('http://img.jpg');
// or by passing the Asset
const asset = assetManager.get('http://img.jpg');
assetManager.remove(asset);
```

Returns **[Asset]** Removed asset

## getContainer

Return the Asset Manager Container

Returns **[HTMLElement][16]** 

[1]: https://github.com/GrapesJS/grapesjs/blob/master/src/asset_manager/config/config.ts

[2]: #open

[3]: #close

[4]: #isopen

[5]: #add

[6]: #get

[7]: #getall

[8]: #getallvisible

[9]: #remove

[10]: #getcontainer

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[14]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[15]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[16]: https://developer.mozilla.org/docs/Web/HTML/Element

---

## File: docs/api/block.md

## Block

### Properties

*   `label` **[String][1]** Block label, eg. `My block`
*   `content` **([String][1] | [Object][2])** The content of the block. Might be an HTML string or a [Component Definition][3]
*   `media` **[String][1]?** HTML string for the media/icon of the block, eg. `<svg ...`, ` editor.getWrapper().append(block.get('content'))`
*   `attributes` **[Object][2]?** Block attributes to apply in the view element

## getId

Get block id

Returns **[String][1]**&#x20;

## getLabel

Get block label

Returns **[String][1]**&#x20;

## getMedia

Get block media

Returns **[String][1]**&#x20;

## getContent

Get block content

Returns **([Object][2] | [String][1] | [Array][6]<([Object][2] | [String][1])>)**&#x20;

## getDragDef

Get block component dragDef

Returns **ComponentDefinition**&#x20;

## getCategoryLabel

Get block category label

Returns **[String][1]**&#x20;

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[3]: /modules/Components.html#component-definition

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

---

## File: docs/api/block_manager.md

## Blocks

You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object][1]

```js
const editor = grapesjs.init({
 blockManager: {
   // options
 }
})
```

Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.

```js
// Listen to events
editor.on('block:add', (block) => { ... });

// Use the API
const blockManager = editor.Blocks;
blockManager.add(...);
```

## Available Events
* `block:add` New block added to the collection. The [Block] is passed as an argument to the callback.

```javascript
editor.on('block:add', (block) => { ... });
```

* `block:remove` Block removed from the collection. The [Block] is passed as an argument to the callback.

```javascript
editor.on('block:remove', (block) => { ... });
```

* `block:remove:before` Event triggered before Block remove.

```javascript
editor.on('block:remove:before', (block, remove, opts) => { ... });
```

* `block:update` Block updated. The [Block] and the object containing changes are passed as arguments to the callback.

```javascript
editor.on('block:update', (block, updatedProps) => { ... });
```

* `block:drag:start` Started dragging block. The [Block] is passed as an argument.

```javascript
editor.on('block:drag:start', (block) => { ... });
```

* `block:drag` The block is dragging. The [Block] is passed as an argument.

```javascript
editor.on('block:drag', (block) => { ... });
```

* `block:drag:stop` Dragging of the block is stopped. The dropped [Component] (if dropped successfully) and the [Block] are passed as arguments.

```javascript
editor.on('block:drag:stop', (component, block) => { ... });
```

* `block:category:update` Block category updated.

```javascript
editor.on('block:category:update', ({ category, changes }) => { ... });
```

* `block:custom` Event to use in case of [custom Block Manager UI](https\://grapesjs.com/docs/modules/Blocks.html#customization).

```javascript
editor.on('block:custom', ({ container, blocks, ... }) => { ... });
```

* `block` Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.

```javascript
editor.on('block', ({ event, model, ... }) => { ... });
```

* BlocksEventCallback

[Block]: block.html

[Component]: component.html

## getConfig

Get configuration object

Returns **[Object][2]**&#x20;

## add

Add new block.

### Parameters

*   `id` **[String][3]** Block ID
*   `props` **[Block]** Block properties
*   `opts`   (optional, default `{}`)

### Examples

```javascript
blockManager.add('h1-block', {
  label: 'Heading',
  content: '<h1>Put your title here</h1>',
  category: 'Basic',
  attributes: {
    title: 'Insert h1 block'
  }
});
```

Returns **[Block]** Added block

## get

Get the block by id.

### Parameters

*   `id` **[String][3]** Block id

### Examples

```javascript
const block = blockManager.get('h1-block');
console.log(JSON.stringify(block));
// {label: 'Heading', content: '<h1>Put your ...', ...}
```

Returns **[Block]**&#x20;

## getAll

Return all blocks.

### Examples

```javascript
const blocks = blockManager.getAll();
console.log(JSON.stringify(blocks));
// [{label: 'Heading', content: '<h1>Put your ...'}, ...]
```

Returns **Collection<[Block]>**&#x20;

## getAllVisible

Return the visible collection, which containes blocks actually rendered

Returns **Collection<[Block]>**&#x20;

## remove

Remove block.

### Parameters

*   `block` **([String][3] | [Block])** Block or block ID
*   `opts`   (optional, default `{}`)

### Examples

```javascript
const removed = blockManager.remove('BLOCK_ID');
// or by passing the Block
const block = blockManager.get('BLOCK_ID');
blockManager.remove(block);
```

Returns **[Block]** Removed block

## getCategories

Get all available categories.
It's possible to add categories only within blocks via 'add()' method

Returns **([Array][4] | Collection)**&#x20;

## getContainer

Return the Blocks container element

Returns **[HTMLElement][5]**&#x20;

## getDragBlock

Returns currently dragging block.
Updated when the drag starts and cleared once it's done.

Returns **([Block] | [undefined][6])**&#x20;

## getBlocksByCategory

Get blocks by category.

### Parameters

*   `blocks` **[Array][4]\?**&#x20;

### Examples

```javascript
blockManager.getBlocksByCategory();
// Returns an array of items of this type
// > { category?: Category; items: Block[] }

// NOTE: The item without category is the one containing blocks without category.

// You can also get the same output format by passing your own array of Blocks
const myFilteredBlocks: Block[] = [...];
blockManager.getBlocksByCategorymyFilteredBlocks
```

Returns **[Array][4]\**&#x20;

## render

Render blocks

### Parameters

*   `blocks` **[Array][4]** Blocks to render, without the argument will render all global blocks
*   `opts` **[Object][2]** Options (optional, default `{}`)

    *   `opts.external` **[Boolean][7]?** Render blocks in a new container (HTMLElement will be returned)
    *   `opts.ignoreCategories` **[Boolean][7]?** Render blocks without categories

### Examples

```javascript
// Render all blocks (inside the global collection)
blockManager.render();

// Render new set of blocks
const blocks = blockManager.getAll();
const filtered = blocks.filter(block => block.get('category') == 'sections')

blockManager.render(filtered);
// Or a new set from an array
blockManager.render([
 {label: 'Label text', content: 'Content'}
]);

// Back to blocks from the global collection
blockManager.render();

// You can also render your blocks outside of the main block container
const newBlocksEl = blockManager.render(filtered, { external: true });
document.getElementById('some-id').appendChild(newBlocksEl);
```

Returns **[HTMLElement][5]** Rendered element

[1]: https://github.com/GrapesJS/grapesjs/blob/master/src/block_manager/config/config.ts

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[5]: https://developer.mozilla.org/docs/Web/HTML/Element

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined

[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

---

## File: docs/api/canvas.md

## Canvas

You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object][1]

```js
const editor = grapesjs.init({
 canvas: {
   // options
 }
})
```

Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.

```js
// Listen to events
editor.on('canvas:drop', () => { ... });

// Use the API
const canvas = editor.Canvas;
canvas.setCoords(...);
```

## Available Events
* `canvas:dragenter` Something is dragged inside the canvas. `DataTransfer` instance and dragged content are passed as arguments.

* `canvas:dragover` Something is dragging on the canvas. Triggering event is passed as an argument.

* `canvas:dragend` When a drag operation is ended, triggering event is passed as an argument.

* `canvas:dragdata` On any dataTransfer parse, `DataTransfer` instance and the `result` are passed as arguments. By changing `result.content` you're able to customize what is dropped.

* `canvas:drop` Something is dropped in canvas, `DataTransfer` instance and the dropped model are passed as arguments.

* `canvas:spot` Spots updated.

```javascript
editor.on('canvas:spot', () => {
 console.log('Spots', editor.Canvas.getSpots());
});
```

* `canvas:spot:add` New canvas spot added.

```javascript
editor.on('canvas:spot:add', ({ spot }) => {
 console.log('Spot added', spot);
});
```

* `canvas:spot:update` Canvas spot updated.

```javascript
editor.on('canvas:spot:update', ({ spot }) => {
 console.log('Spot updated', spot);
});
```

* `canvas:spot:remove` Canvas spot removed.

```javascript
editor.on('canvas:spot:remove', ({ spot }) => {
 console.log('Spot removed', spot);
});
```

* `canvas:coords` Canvas coordinates updated.

```javascript
editor.on('canvas:coords', () => {
 console.log('Canvas coordinates updated:', editor.Canvas.getCoords());
});
```

* `canvas:zoom` Canvas zoom updated.

```javascript
editor.on('canvas:zoom', () => {
 console.log('Canvas zoom updated:', editor.Canvas.getZoom());
});
```

* `canvas:pointer` Canvas pointer updated.

```javascript
editor.on('canvas:pointer', () => {
 console.log('Canvas pointer updated:', editor.Canvas.getPointer());
});
```

* `canvas:refresh` Canvas was refreshed to update elements on top, like spots/tools (eg. via `editor.Canvas.refresh()` or on frame resize).

```javascript
editor.on('canvas:refresh', (canvasRefreshOptions) => {
 console.log('Canvas refreshed with options:', canvasRefreshOptions);
});
```

* `canvas:update` Canvas was updated.

* `canvas:tools:update` Canvas tools were updated.

* `canvas:move:start` Canvas move started.

* `canvas:move` Canvas is moving.

* `canvas:move:end` Canvas move ended.

* `canvas:frame:load` Frame loaded in canvas. The event is triggered right after iframe's `onload`.

```javascript
editor.on('canvas:frame:load', ({ window }) => {
 console.log('Frame loaded', window);
});
```

* `canvas:frame:load:head` Frame head loaded in canvas. The event is triggered right after iframe's finished to load the head elements (eg. scripts)

```javascript
editor.on('canvas:frame:load:head', ({ window }) => {
 console.log('Frame head loaded', window);
});
```

* `canvas:frame:load:body` Frame body loaded in canvas. The event is triggered when the body is rendered with components.

```javascript
editor.on('canvas:frame:load:body', ({ window }) => {
 console.log('Frame completed the body render', window);
});
```

* `canvas:frame:unload` Frame is unloading from the canvas.

```javascript
editor.on('canvas:frame:unload', ({ frame }) => {
 console.log('Unloading frame', frame);
});
```

[Component]: component.html

[Frame]: frame.html

[CanvasSpot]: canvas_spot.html

## getConfig

Get configuration object

Returns **[Object][2]**&#x20;

## getElement

Get the canvas element

Returns **[HTMLElement][3]**&#x20;

## getFrameEl

Get the main frame element of the canvas

Returns **[HTMLIFrameElement][4]**&#x20;

## getWindow

Get the main frame window instance

Returns **[Window][5]**&#x20;

## getDocument

Get the main frame document element

Returns **HTMLDocument**&#x20;

## getBody

Get the main frame body element

Returns **[HTMLBodyElement][6]**&#x20;

## setCustomBadgeLabel

Set custom badge naming strategy

### Parameters

*   `f` **[Function][7]**&#x20;

### Examples

```javascript
canvas.setCustomBadgeLabel(function(component){
 return component.getName();
});
```

## getRect

Get canvas rectangular data

Returns **[Object][2]**&#x20;

## startDrag

Start custom drag-and-drop process.

### Parameters

*   `dragSource` **DragSource\<Component>** The source object for the drag operation, containing the component being dragged.

### Examples

```javascript
// as component definition
canvas.startDrag({
 content: { type: 'my-component' }
});
// as HTML
canvas.startDrag({
 content: '...'
});
```

## endDrag

Ends the drag-and-drop process, resetting the drag source and clearing any drag results.
This method can be used to finalize custom drag-and-drop content operations.

### Examples

```javascript
canvas.startDrag({...});
// ... drag finished ...
canvas.endDrag();
```

## hasFocus

Check if the canvas is focused

Returns **[Boolean][8]**&#x20;

## scrollTo

Scroll canvas to the element if it's not visible. The scrolling is
executed via `scrollIntoView` API and options of this method are
passed to it. For instance, you can scroll smoothly by using
`{ behavior: 'smooth' }`.

### Parameters

*   `el` **([HTMLElement][3] | [Component])**&#x20;
*   `opts` **[Object][2]** Options, same as options for `scrollIntoView` (optional, default `{}`)

    *   `opts.force` **[Boolean][8]** Force the scroll, even if the element is already visible (optional, default `false`)

### Examples

```javascript
const selected = editor.getSelected();
// Scroll smoothly (this behavior can be polyfilled)
canvas.scrollTo(selected, { behavior: 'smooth' });
// Force the scroll, even if the element is already visible
canvas.scrollTo(selected, { force: true });
```

## setZoom

Set canvas zoom value

### Parameters

*   `value` **[Number][9]** The zoom value, from 0 to 100
*   `opts` **SetZoomOptions**  (optional, default `{}`)

### Examples

```javascript
canvas.setZoom(50); // set zoom to 50%
```

Returns **this**&#x20;

## getZoom

Get canvas zoom value

### Examples

```javascript
canvas.setZoom(50); // set zoom to 50%
const zoom = canvas.getZoom(); // 50
```

Returns **[Number][9]**&#x20;

## setCoords

Set canvas position coordinates

### Parameters

*   `x` **[Number][9]** Horizontal position
*   `y` **[Number][9]** Vertical position
*   `opts` **ToWorldOption**  (optional, default `{}`)

### Examples

```javascript
canvas.setCoords(100, 100);
```

Returns **this**&#x20;

## getCoords

Get canvas position coordinates

### Examples

```javascript
canvas.setCoords(100, 100);
const coords = canvas.getCoords();
// { x: 100, y: 100 }
```

Returns **[Object][2]** Object containing coordinates

## getLastDragResult

Get the last created Component from a drag & drop to the canvas.

Returns **([Component] | [undefined][10])**&#x20;

## addSpot

Add or update canvas spot.

### Parameters

*   `props` **[Object][2]** Canvas spot properties.
*   `opts` **AddOptions**  (optional, default `{}`)

### Examples

```javascript
// Add new canvas spot
const spot = canvas.addSpot({
 type: 'select', // 'select' is one of the built-in spots
 component: editor.getSelected(),
});

// Add custom canvas spot
const spot = canvas.addSpot({
 type: 'my-custom-spot',
 component: editor.getSelected(),
});
// Update the same spot by reusing its ID
canvas.addSpot({
 id: spot.id,
 component: anotherComponent,
});
```

Returns **[CanvasSpot]**&#x20;

## getSpots

Get canvas spots.

### Parameters

*   `spotProps` **[Object][2]?** Canvas spot properties for filtering the result. With no properties, all available spots will be returned. (optional, default `{}`)

### Examples

```javascript
canvas.addSpot({ type: 'select', component: cmp1 });
canvas.addSpot({ type: 'select', component: cmp2 });
canvas.addSpot({ type: 'target', component: cmp3 });

// Get all spots
const allSpots = canvas.getSpots();
allSpots.length; // 3

// Get all 'select' spots
const allSelectSpots = canvas.getSpots({ type: 'select' });
allSelectSpots.length; // 2
```

Returns **[Array][11]<[CanvasSpot]>**&#x20;

## removeSpots

Remove canvas spots.

### Parameters

*   `spotProps` **([Object][2] | [Array][11]<[CanvasSpot]>)?** Canvas spot properties for filtering spots to remove or an array of spots to remove. With no properties, all available spots will be removed. (optional, default `{}`)

### Examples

```javascript
canvas.addSpot({ type: 'select', component: cmp1 });
canvas.addSpot({ type: 'select', component: cmp2 });
canvas.addSpot({ type: 'target', component: cmp3 });

// Remove all 'select' spots
canvas.removeSpots({ type: 'select' });

// Remove spots by an array of canvas spots
const filteredSpots = canvas.getSpots().filter(spot => myCustomCondition);
canvas.removeSpots(filteredSpots);

// Remove all spots
canvas.removeSpots();
```

Returns **[Array][11]<[CanvasSpot]>**&#x20;

## hasCustomSpot

Check if the built-in canvas spot has a declared custom rendering.

### Parameters

*   `type` **[String][12]** Built-in canvas spot type

### Examples

```javascript
grapesjs.init({
 // ...
 canvas: {
   // avoid rendering the built-in 'target' canvas spot
   customSpots: { target: true }
 }
});
// ...
canvas.hasCustomSpot('select'); // false
canvas.hasCustomSpot('target'); // true
```

Returns **[Boolean][8]**&#x20;

## getWorldRectToScreen

Transform a box rect from the world coordinate system to the screen one.

### Parameters

*   `boxRect` **[Object][2]**&#x20;

Returns **[Object][2]**&#x20;

## refresh

Update canvas for spots/tools positioning.

### Parameters

*   `opts` **[Object][2]?** Options. (optional, default `{}`)

    *   `opts.spots` **[Object][2]** Update the position of spots. (optional, default `false`)

[1]: https://github.com/GrapesJS/grapesjs/blob/master/src/canvas/config/config.ts

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[3]: https://developer.mozilla.org/docs/Web/HTML/Element

[4]: https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement

[5]: https://developer.mozilla.org/docs/Web/API/Window

[6]: https://developer.mozilla.org/docs/Web/HTML/Element/body

[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

---

## File: docs/api/canvas_spot.md

## CanvasSpot



Canvas spots are elements drawn on top of the canvas. They can be used to represent anything you
might need but the most common use case of canvas spots is rendering information and managing
components rendered in the canvas.
Read here for more information about [Canvas Spots][1]

[Component]: component.html

### Properties

*   `id` **[String][2]** Spot ID.
*   `type` **[String][2]** Spot type.
*   `component` **[Component]?** Component to which the spot will be attached.
*   `componentView` **ComponentView?** ComponentView to which the spot will be attached.
*   `boxRect` **[Object][3]?** Fixed box rect of the spot, eg. `{ width: 100, height: 100, x: 0, y: 0 }`.

### getBoxRect

Get the box rect of the spot.

#### Parameters

*   `opts` **[Object][3]**  (optional, default `{}`)

#### Examples

```javascript
canvasSpot.getBoxRect();
// { width: 100, height: 50, x: 0, y: 0 }
```

Returns **[Object][3]** The box rect object

### getStyle

Get the style object of the spot.

#### Parameters

*   `opts` **[Object][3]**  (optional, default `{}`)

#### Examples

```javascript
canvasSpot.getStyle();
// { width: '100px', height: '...', ... }
```

Returns **CSSStyleDeclaration** \[opts]

### isType

Check the spot type.

#### Parameters

*   `type` **[String][2]**&#x20;

#### Examples

```javascript
canvasSpot.isType('select');
```

Returns **[Boolean][4]**&#x20;

[1]: https://grapesjs.com/docs/modules/Canvas.html#canvas-spots

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

---

## File: docs/api/commands.md

## Commands

You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object][1]

```js
const editor = grapesjs.init({
 commands: {
   // options
 }
})
```

Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.

```js
// Listen to events
editor.on('run', () => { ... });

// Use the API
const commands = editor.Commands;
commands.add(...);
```

## Available Events
* `command:run` Triggered on run of any command.

```javascript
editor.on('command:run', ({ id, result, options }) => {
 console.log('Command id', id, 'command result', result);
});
```

* `command:run:COMMAND_ID` Triggered on run of a specific command.

```javascript
editor.on('command:run:my-command', ({ result, options }) => { ... });
```

* `command:run:before:COMMAND_ID` Triggered before the command is called.

```javascript
editor.on('command:run:before:my-command', ({ options }) => { ... });
```

* `command:abort:COMMAND_ID` Triggered when the command execution is aborted.

```javascript
editor.on('command:abort:my-command', ({ options }) => { ... });

// The command could be aborted during the before event
editor.on('command:run:before:my-command', ({ options }) => {
 if (someCondition) {
   options.abort = true;
 }
});
```

* `command:stop` Triggered on stop of any command.

```javascript
editor.on('command:stop', ({ id, result, options }) => {
 console.log('Command id', id, 'command result', result);
});
```

* `command:stop:COMMAND_ID` Triggered on stop of a specific command.

```javascript
editor.on('command:run:my-command', ({ result, options }) => { ... });
```

* `command:stop:before:COMMAND_ID` Triggered before the command is called to stop.

```javascript
editor.on('command:stop:before:my-command', ({ options }) => { ... });
```

## Methods

*   [add][2]
*   [get][3]
*   [getAll][4]
*   [extend][5]
*   [has][6]
*   [run][7]
*   [stop][8]
*   [isActive][9]
*   [getActive][10]

## add

Add new command to the collection

### Parameters

*   `id` **[string][11]** Command's ID
*   `command` **([Object][12] | [Function][13])** Object representing your command,
    By passing just a function it's intended as a stateless command
    (just like passing an object with only `run` method).

### Examples

```javascript
commands.add('myCommand', {
	run(editor, sender) {
		alert('Hello world!');
	},
	stop(editor, sender) {
	},
});
// As a function
commands.add('myCommand2', editor => { ... });
```

Returns **this** 

## get

Get command by ID

### Parameters

*   `id` **[string][11]** Command's ID

### Examples

```javascript
var myCommand = commands.get('myCommand');
myCommand.run();
```

Returns **[Object][12]** Object representing the command

## extend

Extend the command. The command to extend should be defined as an object

### Parameters

*   `id` **[string][11]** Command's ID
*   `cmd` **CommandObject**  (optional, default `{}`)
*   `Object` **[Object][12]** with the new command functions

### Examples

```javascript
commands.extend('old-command', {
 someInnerFunction() {
 // ...
 }
});
```

Returns **this** 

## has

Check if command exists

### Parameters

*   `id` **[string][11]** Command's ID

Returns **[Boolean][14]** 

## getAll

Get an object containing all the commands

Returns **[Object][12]** 

## run

Execute the command

### Parameters

*   `id` **[String][11]** Command ID
*   `options` **[Object][12]** Options (optional, default `{}`)

### Examples

```javascript
commands.run('myCommand', { someOption: 1 });
```

Returns **any** The return is defined by the command

## stop

Stop the command

### Parameters

*   `id` **[String][11]** Command ID
*   `options` **[Object][12]** Options (optional, default `{}`)

### Examples

```javascript
commands.stop('myCommand', { someOption: 1 });
```

Returns **any** The return is defined by the command

## isActive

Check if the command is active. You activate commands with `run`
and disable them with `stop`. If the command was created without `stop`
method it can't be registered as active

### Parameters

*   `id` **[String][11]** Command id

### Examples

```javascript
const cId = 'some-command';
commands.run(cId);
commands.isActive(cId);
// -> true
commands.stop(cId);
commands.isActive(cId);
// -> false
```

Returns **[Boolean][14]** 

## getActive

Get all active commands

### Examples

```javascript
console.log(commands.getActive());
// -> { someCommand: itsLastReturn, anotherOne: ... };
```

Returns **[Object][12]** 

[1]: https://github.com/GrapesJS/grapesjs/blob/master/src/commands/config/config.ts

[2]: #add

[3]: #get

[4]: #getall

[5]: #extend

[6]: #has

[7]: #run

[8]: #stop

[9]: #isactive

[10]: #getactive

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[14]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

---

## File: docs/api/component.md

## Component

The Component object represents a single node of our template structure, so when you update its properties the changes are
immediately reflected on the canvas and in the code to export (indeed, when you ask to export the code we just go through all
the tree of nodes).
An example on how to update properties:

```js
component.set({
 tagName: 'span',
 attributes: { ... },
 removable: false,
});
component.get('tagName');
// -> 'span'
```

[Component]: component.html

### Properties

*   `type` **[String][1]?** Component type, eg. `text`, `image`, `video`, etc.
*   `tagName` **[String][1]?** HTML tag of the component, eg. `span`. Default: `div`
*   `attributes` **[Object][2]?** Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}`
*   `name` **[String][1]?** Name of the component. Will be used, for example, in Layers and badges
*   `removable` **[Boolean][3]?** When `true` the component is removable from the canvas, default: `true`
*   `draggable` **([Boolean][3] | [String][1] | [Function][4])?** Indicates if it's possible to drag the component inside others.
    You can also specify a query string to identify elements,
    eg. `'.some-class[title=Hello], [data-gjs-type=column]'` means you can drag the component only inside elements
    containing `some-class` class and `Hello` title, and `column` components. In the case of a function, target and destination components are passed as arguments, return a Boolean to indicate if the drag is possible. Default: `true`
*   `droppable` **([Boolean][3] | [String][1] | [Function][4])?** Indicates if it's possible to drop other components inside. You can use
    a query string as with `draggable`. In the case of a function, target and destination components are passed as arguments, return a Boolean to indicate if the drop is possible. Default: `true`
*   `badgable` **[Boolean][3]?** Set to false if you don't want to see the badge (with the name) over the component. Default: `true`
*   `stylable` **([Boolean][3] | [Array][5]<[String][1]>)?** True if it's possible to style the component.
    You can also indicate an array of CSS properties which is possible to style, eg. `['color', 'width']`, all other properties
    will be hidden from the style manager. Default: `true`
*   `stylable-require` **[Array][5]<[String][1]>?** Indicate an array of style properties to show up which has been marked as `toRequire`. Default: `[]`
*   `unstylable` **[Array][5]<[String][1]>?** Indicate an array of style properties which should be hidden from the style manager. Default: `[]`
*   `highlightable` **[Boolean][3]?** It can be highlighted with 'dotted' borders if true. Default: `true`
*   `copyable` **[Boolean][3]?** True if it's possible to clone the component. Default: `true`
*   `resizable` **[Boolean][3]?** Indicates if it's possible to resize the component. It's also possible to pass an object as [options for the Resizer][6]. Default: `false`
*   `editable` **[Boolean][3]?** Allow to edit the content of the component (used on Text components). Default: `false`
*   `layerable` **[Boolean][3]?** Set to `false` if you need to hide the component inside Layers. Default: `true`
*   `selectable` **[Boolean][3]?** Allow component to be selected when clicked. Default: `true`
*   `hoverable` **[Boolean][3]?** Shows a highlight outline when hovering on the element if `true`. Default: `true`
*   `locked` **[Boolean][3]?** Disable the selection of the component and its children in the canvas. You can unlock a children by setting its locked property to `false`. Default: `undefined`
*   `void` **[Boolean][3]?** This property is used by the HTML exporter as void elements don't have closing tags, eg. ``, `<hr/>`, etc. Default: `false`
*   `style` **[Object][2]?** Component default style, eg. `{ width: '100px', height: '100px', 'background-color': 'red' }`
*   `styles` **[String][1]?** Component related styles, eg. `.my-component-class { color: red }`
*   `content` **[String][1]?** Content of the component (not escaped) which will be appended before children rendering. Default: `''`
*   `icon` **[String][1]?** Component's icon, this string will be inserted before the name (in Layers and badge), eg. it can be an HTML string ''. Default: `''`
*   `script` **([String][1] | [Function][4])?** Component's javascript. More about it [here][7]. Default: `''`
*   `script-export` **([String][1] | [Function][4])?** You can specify javascript available only in export functions (eg. when you get the HTML).
    If this property is defined it will overwrite the `script` one (in export functions). Default: `''`
*   `traits` **[Array][5]<([Object][2] | [String][1])>?** Component's traits. More about it [here][8]. Default: `['id', 'title']`
*   `propagate` **[Array][5]<[String][1]>?** Indicates an array of properties which will be inhereted by all NEW appended children.
    For example if you create a component likes this: `{ removable: false, draggable: false, propagate: ['removable', 'draggable'] }`
    and append some new component inside, the new added component will get the exact same properties indicated in the `propagate` array (and the `propagate` property itself). Default: `[]`
*   `toolbar` **[Array][5]<[Object][2]>?** Set an array of items to show up inside the toolbar when the component is selected (move, clone, delete).
    Eg. `toolbar: [ { attributes: {class: 'fa fa-arrows'}, command: 'tlb-move' }, ... ]`.
    By default, when `toolbar` property is falsy the editor will add automatically commands `core:component-exit` (select parent component, added if there is one), `tlb-move` (added if `draggable`) , `tlb-clone` (added if `copyable`), `tlb-delete` (added if `removable`).
*   `components` **Collection\<Component>?** Children components. Default: `null`
*   `delegate` **[Object][2]?** Delegate commands to other components. Available commands `remove` | `move` | `copy` | `select`. eg. `{ remove: (cmp) => cmp.closestType('other-type') }`

## init

Hook method, called once the model is created

## updated

Hook method, called when the model has been updated (eg. updated some model's property)

### Parameters

*   `property` **[String][1]** Property name, if triggered after some property update
*   `value` **any** Property value, if triggered after some property update
*   `previous` **any** Property previous value, if triggered after some property update

## removed

Hook method, called once the model has been removed

## is

Check component's type

### Parameters

*   `type` **[string][1]** Component type

### Examples

```javascript
component.is('image')
// -> false
```

Returns **[Boolean][3]**&#x20;

## props

Return all the propeties

Returns **[Object][2]**&#x20;

## index

Get the index of the component in the parent collection.

Returns **[Number][9]**&#x20;

## setDragMode

Change the drag mode of the component.
To get more about this feature read: [https://github.com/GrapesJS/grapesjs/issues/1936][10]

### Parameters

*   `value` **[String][1]** Drag mode, options: `'absolute'` | `'translate'` | `''`

Returns **this**&#x20;

## getDragMode

Get the drag mode of the component.

Returns **[String][1]** Drag mode value, options: `'absolute'` | `'translate'` | `''`

## setSymbolOverride

Set symbol override.
By setting override to `true`, none of its property changes will be propagated to relative symbols.
By setting override to specific properties, changes of those properties will be skipped from propagation.

### Parameters

*   `value` **([Boolean][3] | [String][1] | [Array][5]<[String][1]>)**&#x20;
*   `options` **DataWatchersOptions**  (optional, default `{}`)

### Examples

```javascript
component.setSymbolOverride(['children', 'classes']);
```

## getSymbolOverride

Get symbol override value.

Returns **([Boolean][3] | [Array][5]<[String][1]>)**&#x20;

## find

Find inner components by query string.
**ATTENTION**: this method works only with already rendered component

### Parameters

*   `query` **[String][1]** Query string

### Examples

```javascript
component.find('div > .class');
// -> [Component, Component, ...]
```

Returns **[Array][5]** Array of components

## findType

Find all inner components by component type.
The advantage of this method over `find` is that you can use it
also before rendering the component

### Parameters

*   `query` **([String][1] | Function)** Component type or matcher function
*   `opts` **[Object][2]?** Search options
*   `opts.max` **[Number][12]?** Maximum number of matches before exiting

### Examples

```javascript
const allImages = component.findType('image');
console.log(allImages[0]) // prints the first found component

const someComponents = component.findType((cmp) => cmp.getType() === 'something', { max: 2 });
```

Returns **[Array][5]\<Component>**&#x20;

## findFirstType

Find the first inner component by component type.
If no component is found, it returns `undefined`.

### Parameters

*   `query` **([String][1] | Function)** Component type or matcher function

### Examples

```javascript
const image = component.findFirstType('image');
if (image) {
 console.log(image);
}

const firstImage = component.findFirstType((cmp) => cmp.is('image'));
```

Returns **(Component | [undefined][11])**&#x20;

## closest

Find the closest parent component by query string.
**ATTENTION**: this method works only with already rendered component

### Parameters

*   `query` **[string][1]** Query string

### Examples

```javascript
component.closest('div.some-class');
// -> Component
```

Returns **Component**&#x20;

## closestType

Find the closest parent component by its type.
The advantage of this method over `closest` is that you can use it
also before rendering the component

### Parameters

*   `query` **([String][1] | Function)** Component type or matcher function

### Examples

```javascript
const Section = component.closestType('section');
console.log(Section);

const namedSection = component.closestType((cmp) => cmp.getName() === 'Section');
```

Returns **Component** Found component, otherwise `undefined`

## contains

The method returns a Boolean value indicating whether the passed
component is a descendant of a given component

### Parameters

*   `component` **Component** Component to check

Returns **[Boolean][3]**&#x20;

## replaceWith

Replace a component with another one

### Parameters

*   `el` **([String][1] | Component)** Component or HTML string
*   `opts` **[Object][2]** Options for the append action (optional, default `{}`)

### Examples

```javascript
const result = component.replaceWith('Some new content');
// result -> [Component]
```

Returns **[Array][5]\<Component>** New replaced components

## setAttributes

Update attributes of the component

### Parameters

*   `attrs` **[Object][2]** Key value attributes
*   `opts` **SetAttrOptions**  (optional, default `{skipWatcherUpdates:false,fromDataSource:false}`)
*   `options` **[Object][2]** Options for the model update

### Examples

```javascript
component.setAttributes({ id: 'test', 'data-key': 'value' });
```

Returns **this**&#x20;

## addAttributes

Add attributes to the component

### Parameters

*   `attrs` **[Object][2]** Key value attributes
*   `opts` **SetAttrOptions**  (optional, default `{}`)
*   `options` **[Object][2]** Options for the model update

### Examples

```javascript
component.addAttributes({ 'data-key': 'value' });
```

Returns **this**&#x20;

## removeAttributes

Remove attributes from the component

### Parameters

*   `attrs` **([String][1] | [Array][5]<[String][1]>)** Array of attributes to remove (optional, default `[]`)
*   `opts` **SetOptions**  (optional, default `{}`)
*   `options` **[Object][2]** Options for the model update

### Examples

```javascript
component.removeAttributes('some-attr');
component.removeAttributes(['some-attr1', 'some-attr2']);
```

Returns **this**&#x20;

## getStyle

Get the style of the component

### Parameters

*   `opts` **GetComponentStyleOpts?**&#x20;

Returns **[Object][2]**&#x20;

## setStyle

Set the style on the component

### Parameters

*   `prop` **[Object][2]** Key value style object (optional, default `{}`)
*   `opts` **UpdateStyleOptions**  (optional, default `{}`)

### Examples

```javascript
component.setStyle({ color: 'red' });
```

Returns **[Object][2]**&#x20;

## getAttributes

Return all component's attributes

### Parameters

*   `opts` **{noClass: [boolean][3]?, noStyle: [boolean][3]?, skipResolve: [boolean][3]?}**  (optional, default `{}`)

Returns **[Object][2]**&#x20;

## addClass

Add classes

### Parameters

*   `classes` **([Array][5]<[String][1]> | [String][1])** Array or string of classes

### Examples

```javascript
model.addClass('class1');
model.addClass('class1 class2');
model.addClass(['class1', 'class2']);
// -> [SelectorObject, ...]
```

Returns **[Array][5]** Array of added selectors

## setClass

Set classes (resets current collection)

### Parameters

*   `classes` **([Array][5]<[String][1]> | [String][1])** Array or string of classes

### Examples

```javascript
model.setClass('class1');
model.setClass('class1 class2');
model.setClass(['class1', 'class2']);
// -> [SelectorObject, ...]
```

Returns **[Array][5]** Array of added selectors

## removeClass

Remove classes

### Parameters

*   `classes` **([Array][5]<[String][1]> | [String][1])** Array or string of classes

### Examples

```javascript
model.removeClass('class1');
model.removeClass('class1 class2');
model.removeClass(['class1', 'class2']);
// -> [SelectorObject, ...]
```

Returns **[Array][5]** Array of removed selectors

## getClasses

Returns component's classes as an array of strings

Returns **[Array][5]**&#x20;

## append

Add new component children

### Parameters

*   `components` **(Component | [String][1])** Component to add
*   `opts` **[Object][2]** Options for the append action (optional, default `{}`)

### Examples

```javascript
someComponent.get('components').length // -> 0
const videoComponent = someComponent.append('<video></video>')[0];
// This will add 2 components (`video` and `div`) to your `someComponent`
someComponent.get('components').length // -> 2
// You can pass components directly
otherComponent.append(otherComponent2);
otherComponent.append([otherComponent3, otherComponent4]);
// append at specific index (eg. at the beginning)
someComponent.append(otherComponent, { at: 0 });
```

Returns **[Array][5]** Array of appended components

## components

Set new collection if `components` are provided, otherwise the
current collection is returned

### Parameters

*   `components` **(Component | [Array][5]\<Component> | [String][1])?** Component Definitions or HTML string
*   `opts` **[Object][2]** Options, same as in `Component.append()` (optional, default `{}`)

### Examples

```javascript
// Set new collection
component.components('');
// Get current collection
const collection = component.components();
console.log(collection.length);
// -> 2
```

Returns **(Collection | [Array][5]<[Component]>)**&#x20;

## getChildAt

If exists, returns the child component at specific index.

### Parameters

*   `index` **[Number][9]** Index of the component to return

### Examples

```javascript
// Return first child
component.getChildAt(0);
// Return second child
component.getChildAt(1);
```

Returns **([Component] | null)**&#x20;

## getLastChild

If exists, returns the last child component.

### Examples

```javascript
const lastChild = component.getLastChild();
```

Returns **([Component] | null)**&#x20;

## empty

Remove all inner components

*   @return {this}

### Parameters

*   `opts`   (optional, default `{}`)

## parent

Get the parent component, if exists

### Parameters

*   `opts` **any**  (optional, default `{}`)

### Examples

```javascript
component.parent();
// -> Component
```

Returns **(Component | null)**&#x20;

## parents

Return all parents of the component.

Returns **[Array][5]\<Component>**&#x20;

## getTraits

Get traits.

### Examples

```javascript
const traits = component.getTraits();
console.log(traits);
// [Trait, Trait, Trait, ...]
```

Returns **[Array][5]\**&#x20;

## setTraits

Replace current collection of traits with a new one.

### Parameters

*   `traits` **[Array][5]<[Object][2]>** Array of trait definitions

### Examples

```javascript
const traits = component.setTraits([{ type: 'checkbox', name: 'disabled'}, ...]);
console.log(traits);
// [Trait, ...]
```

Returns **[Array][5]\**&#x20;

## getTrait

Get the trait by id/name.

### Parameters

*   `id` **[String][1]** The `id` or `name` of the trait

### Examples

```javascript
const traitTitle = component.getTrait('title');
traitTitle && traitTitle.set('label', 'New label');
```

Returns **(Trait | null)** Trait getModelToStyle

## updateTrait

Update a trait.

### Parameters

*   `id` **[String][1]** The `id` or `name` of the trait
*   `props` **[Object][2]** Object with the props to update

### Examples

```javascript
component.updateTrait('title', {
 type: 'select',
 options: [ 'Option 1', 'Option 2' ],
});
```

Returns **this**&#x20;

## getTraitIndex

Get the trait position index by id/name. Useful in case you want to
replace some trait, at runtime, with something else.

### Parameters

*   `id` **[String][1]** The `id` or `name` of the trait

### Examples

```javascript
const traitTitle = component.getTraitIndex('title');
console.log(traitTitle); // 1
```

Returns **[Number][9]** Index position of the current trait

## removeTrait

Remove trait/s by id/s.

### Parameters

*   `id` **([String][1] | [Array][5]<[String][1]>)** The `id`/`name` of the trait (or an array)

### Examples

```javascript
component.removeTrait('title');
component.removeTrait(['title', 'id']);
```

Returns **[Array][5]\** Array of removed traits

## addTrait

Add new trait/s.

### Parameters

*   `trait` **([String][1] | [Object][2] | [Array][5]<([String][1] | [Object][2])>)** Trait to add (or an array of traits)
*   `opts` **Options** Options for the add (optional, default `{}`)

### Examples

```javascript
component.addTrait('title', { at: 1 }); // Add title trait (`at` option is the position index)
component.addTrait({
 type: 'checkbox',
 name: 'disabled',
});
component.addTrait(['title', {...}, ...]);
```

Returns **[Array][5]\** Array of added traits

## getName

Get the name of the component.

### Parameters

*   `opts` **[Object][2]** Options (optional, default `{}`)

    *   `opts.noCustom` **[Boolean][3]?** Avoid custom name assigned to the component.

Returns **[String][1]**&#x20;

## setName

Update component name.

### Parameters

*   `name` **[String][1]** New name.
*   `opts` **SetOptions**  (optional, default `{}`)

## getIcon

Get the icon string

Returns **[String][1]**&#x20;

## toHTML

Return HTML string of the component

### Parameters

*   `opts` **[Object][2]** Options (optional, default `{}`)

    *   `opts.tag` **[String][1]?** Custom tagName
    *   `opts.attributes` **([Object][2] | [Function][4])** You can pass an object of custom attributes to replace with the current ones or you can even pass a function to generate attributes dynamically. (optional, default `null`)
    *   `opts.withProps` **[Boolean][3]?** Include component properties as `data-gjs-*` attributes. This allows you to have re-importable HTML.
    *   `opts.altQuoteAttr` **[Boolean][3]?** In case the attribute value contains a `"` char, instead of escaping it (`attr="value &quot;"`), the attribute will be quoted using single quotes (`attr='value "'`).

### Examples

```javascript
// Simple HTML return
component.set({ tagName: 'span' });
component.setAttributes({ title: 'Hello' });
component.toHTML();
// -> 

// Custom attributes
component.toHTML({ attributes: { 'data-test': 'Hello' } });
// -> 

// Custom dynamic attributes
component.toHTML({
 attributes(component, attributes) {
   if (component.get('tagName') == 'span') {
     attributes.title = 'Custom attribute';
   }
   return attributes;
 },
});
// -> 
```

Returns **[String][1]** HTML string

## getInnerHTML

Get inner HTML of the component

### Parameters

*   `opts` **[Object][2]** Same options of `toHTML` (optional, default `{}`)

Returns **[String][1]** HTML string

## getChangedProps

Return an object containing only changed props

### Parameters

*   `res` **Partial\<ComponentDefinition>**&#x20;

Returns **Partial\<ComponentDefinition>**&#x20;

## getId

Return the component id

Returns **[String][1]**&#x20;

## setId

Set new id on the component

### Parameters

*   `id` **[String][1]**&#x20;
*   `opts` **any?**&#x20;

Returns **this**&#x20;

## getEl

Get the DOM element of the component.
This works only if the component is already rendered

### Parameters

*   `frame` **Frame** Specific frame from which taking the element

Returns **[HTMLElement][12]**&#x20;

## getView

Get the View of the component.
This works only if the component is already rendered

### Parameters

*   `frame` **Frame** Get View of a specific frame

Returns **ComponentView**&#x20;

## onAll

Execute callback function on itself and all inner components

### Parameters

*   `clb` **[Function][4]** Callback function, the model is passed as an argument

### Examples

```javascript
component.onAll(component => {
 // do something with component
})
```

Returns **this**&#x20;

## forEachChild

Execute a callback function on all inner child components.

### Parameters

*   `clb` **[Function][4]** Callback function, the child component is passed as an argument

### Examples

```javascript
component.forEachChild(child => {
 console.log(child)
})
```

## remove

Remove the component

### Parameters

*   `opts` **any**  (optional, default `{}`)

Returns **this**&#x20;

## move

Move the component to another destination component

### Parameters

*   `component` **Component** Destination component (so the current one will be appended as a child)
*   `opts` **[Object][2]** Options for the append action (optional, default `{}`)

### Examples

```javascript
// Move the selected component on top of the wrapper
const dest = editor.getWrapper();
editor.getSelected().move(dest, { at: 0 });
```

Returns **this**&#x20;

## isInstanceOf

Check if the component is an instance of some component type.

### Parameters

*   `type` **[String][1]** Component type

### Examples

```javascript
// Add a new component type by extending an existing one
editor.Components.addType('text-ext', { extend: 'text' });
// Append a new component somewhere
const newTextExt = editor.getSelected().append({ type: 'text-ext' })[0];
newTextExt.isInstanceOf('text-ext'); // true
newTextExt.isInstanceOf('text'); // true
```

Returns **[Boolean][3]**&#x20;

## isChildOf

Check if the component is a child of some other component (or component type)

### Parameters

*   `component` **([Component] | [String][1])** Component parent to check. In case a string is passed,
    the check will be performed on the component type.

### Examples

```javascript
const newTextComponent = editor.getSelected().append({
 type: 'text',
 components: 'My text **here**',
})[0];
const innerComponent = newTextComponent.find('b')[0];
innerComponent.isChildOf(newTextComponent); // true
innerComponent.isChildOf('text'); // true
```

Returns **[Boolean][3]**&#x20;

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[6]: https://github.com/GrapesJS/grapesjs/blob/master/src/utils/Resizer.ts

[7]: /modules/Components-js.html

[8]: /modules/Traits.html

[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[10]: https://github.com/GrapesJS/grapesjs/issues/1936

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined

[12]: https://developer.mozilla.org/docs/Web/HTML/Element

---

## File: docs/api/components.md

## Components

With this module is possible to manage components inside the canvas. You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object][1]

```js
const editor = grapesjs.init({
 domComponents: {
   // options
 }
})
```

Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.

```js
// Listen to events
editor.on('component:create', () => { ... });

// Use the API
const cmp = editor.Components;
cmp.addType(...);
```

## Available Events

*   `component:create` - Component is created (only the model, is not yet mounted in the canvas), called after the init() method
*   `component:mount` - Component is mounted to an element and rendered in canvas
*   `component:add` - Triggered when a new component is added to the editor, the model is passed as an argument to the callback
*   `component:remove` - Triggered when a component is removed, the model is passed as an argument to the callback
*   `component:remove:before` - Triggered before the remove of the component, the model, remove function (if aborted via options, with this function you can complete the remove) and options (use options.abort = true to prevent remove), are passed as arguments to the callback
*   `component:clone` - Triggered when a component is cloned, the new model is passed as an argument to the callback
*   `component:update` - Triggered when a component is updated (moved, styled, etc.), the model is passed as an argument to the callback
*   `component:update:{propertyName}` - Listen any property change, the model is passed as an argument to the callback
*   `component:styleUpdate` - Triggered when the style of the component is updated, the model is passed as an argument to the callback
*   `component:styleUpdate:{propertyName}` - Listen for a specific style property change, the model is passed as an argument to the callback
*   `component:selected` - New component selected, the selected model is passed as an argument to the callback
*   `component:deselected` - Component deselected, the deselected model is passed as an argument to the callback
*   `component:toggled` - Component selection changed, toggled model is passed as an argument to the callback
*   `component:type:add` - New component type added, the new type is passed as an argument to the callback
*   `component:type:update` - Component type updated, the updated type is passed as an argument to the callback
*   `component:drag:start` - Component drag started. Passed an object, to the callback, containing the `target` (component to drag), `parent` (parent of the component) and `index` (component index in the parent)
*   `component:drag` - During component drag. Passed the same object as in `component:drag:start` event, but in this case, `parent` and `index` are updated by the current pointer
*   `component:drag:end` - Component drag ended. Passed the same object as in `component:drag:start` event, but in this case, `parent` and `index` are updated by the final pointer
*   `component:resize` - During component resize.

## Methods

*   [getWrapper][2]

*   [getComponents][3]

*   [addComponent][4]

*   [clear][5]

*   [addType][6]

*   [getType][7]

*   [getTypes][8]

*   [Component]: component.html

## getWrapper

Returns root component inside the canvas. Something like `` inside HTML page
The wrapper doesn't differ from the original Component Model

### Examples

```javascript
// Change background of the wrapper and set some attribute
var wrapper = cmp.getWrapper();
wrapper.set('style', {'background-color': 'red'});
wrapper.set('attributes', {'title': 'Hello!'});
```

Returns **[Component]** Root Component

## getComponents

Returns wrapper's children collection. Once you have the collection you can
add other Components(Models) inside. Each component can have several nested
components inside and you can nest them as more as you wish.

### Examples

```javascript
// Let's add some component
var wrapperChildren = cmp.getComponents();
var comp1 = wrapperChildren.add({
  style: { 'background-color': 'red'}
});
var comp2 = wrapperChildren.add({
  tagName: 'span',
  attributes: { title: 'Hello!'}
});
// Now let's add an other one inside first component
// First we have to get the collection inside. Each
// component has 'components' property
var comp1Children = comp1.get('components');
// Procede as before. You could also add multiple objects
comp1Children.add([
  { style: { 'background-color': 'blue'}},
  { style: { height: '100px', width: '100px'}}
]);
// Remove comp2
wrapperChildren.remove(comp2);
```

Returns **[Components][9]** Collection of components

## addComponent

Add new components to the wrapper's children. It's the same
as 'cmp.getComponents().add(...)'

### Parameters

*   `component` **([Object][10] | [Component] | [Array][11]<[Object][10]>)** Component/s to add

    *   `component.tagName` **[string][12]** Tag name (optional, default `'div'`)
    *   `component.type` **[string][12]** Type of the component. Available: ''(default), 'text', 'image' (optional, default `''`)
    *   `component.removable` **[boolean][13]** If component is removable (optional, default `true`)
    *   `component.draggable` **[boolean][13]** If is possible to move the component around the structure (optional, default `true`)
    *   `component.droppable` **[boolean][13]** If is possible to drop inside other components (optional, default `true`)
    *   `component.badgable` **[boolean][13]** If the badge is visible when the component is selected (optional, default `true`)
    *   `component.stylable` **[boolean][13]** If is possible to style component (optional, default `true`)
    *   `component.copyable` **[boolean][13]** If is possible to copy\&paste the component (optional, default `true`)
    *   `component.content` **[string][12]** String inside component (optional, default `''`)
    *   `component.style` **[Object][10]** Style object (optional, default `{}`)
    *   `component.attributes` **[Object][10]** Attribute object (optional, default `{}`)
*   `opt` **[Object][10]** the options object to be used by the \[Components.add][getComponents][14] method (optional, default `{}`)

### Examples

```javascript
// Example of a new component with some extra property
var comp1 = cmp.addComponent({
  tagName: 'div',
  removable: true, // Can't remove it
  draggable: true, // Can't move it
  copyable: true, // Disable copy/past
  content: 'Content text', // Text inside component
  style: { color: 'red'},
  attributes: { title: 'here' }
});
```

Returns **([Component] | [Array][11]<[Component]>)** Component/s added

## clear

Remove all components

### Parameters

*   `opts`   (optional, default `{}`)

Returns **this** 

## addType

Add new component type.
Read more about this in [Define New Component][15]

### Parameters

*   `type` **[string][12]** Component ID
*   `methods` **[Object][10]** Component methods

Returns **this** 

## getType

Get component type.
Read more about this in [Define New Component][15]

### Parameters

*   `type` **[string][12]** Component ID

Returns **[Object][10]** Component type definition, eg. `{ model: ..., view: ... }`

## removeType

Remove component type

### Parameters

*   `id` **[string][12]** 
*   `type` **[string][12]** Component ID

Returns **([Object][10] | [undefined][16])** Removed component type, undefined otherwise

## getTypes

Return the array of all types

Returns **[Array][11]** 

## isComponent

Check if the object is a \[Component].

### Parameters

*   `obj` **[Object][10]** 

### Examples

```javascript
cmp.isComponent(editor.getSelected()); // true
cmp.isComponent({}); // false
```

Returns **[Boolean][13]** 

## addSymbol

Add a new symbol from a component.
If the passed component is not a symbol, it will be converted to an instance and will return the main symbol.
If the passed component is already an instance, a new instance will be created and returned.
If the passed component is the main symbol, a new instance will be created and returned.

### Parameters

*   `component` **[Component]** Component from which create a symbol.

### Examples

```javascript
const symbol = cmp.addSymbol(editor.getSelected());
// cmp.getSymbolInfo(symbol).isSymbol === true;
```

Returns **[Component]** 

## getSymbols

Get the array of main symbols.

### Examples

```javascript
const symbols = cmp.getSymbols();
// [Component, Component, ...]
// Removing the main symbol will detach all the relative instances.
symbols[0].remove();
```

Returns **[Array][11]<[Component]>** 

## detachSymbol

Detach symbol instance from the main one.
The passed symbol instance will become a regular component.

### Parameters

*   `component` **[Component]** The component symbol to detach.

### Examples

```javascript
const cmpInstance = editor.getSelected();
// cmp.getSymbolInfo(cmpInstance).isInstance === true;
cmp.detachSymbol(cmpInstance);
// cmp.getSymbolInfo(cmpInstance).isInstance === false;
```

## getSymbolInfo

Get info about the symbol.

### Parameters

*   `component` **[Component]** Component symbol from which to get the info.
*   `opts` **{withChanges: [string][12]?}**  (optional, default `{}`)

### Examples

```javascript
cmp.getSymbolInfo(editor.getSelected());
// > { isSymbol: true, isMain: false, isInstance: true, ... }
```

Returns **[Object][10]** Object containing symbol info.

## canMove

Check if a component can be moved inside another one.

### Parameters

*   `target` **[Component]** The target component is the one that is supposed to receive the source one.
*   `source` **([Component] | [String][12])** The source can be another component, a component definition or an HTML string.
*   `index` **[Number][17]?** Index position, if not specified, the check will be performed against appending the source to the target.

### Examples

```javascript
const rootComponent = editor.getWrapper();
const someComponent = editor.getSelected();

// Check with two components
editor.Components.canMove(rootComponent, someComponent);

// Check with component definition
editor.Components.canMove(rootComponent, { tagName: 'a', draggable: false });

// Check with HTML string
editor.Components.canMove(rootComponent, '<form>...</form>');
```

Returns **[Object][10]** Object containing the `result` (Boolean), `source`, `target` (as Components), and a `reason` (Number) with these meanings:*   `0` - Invalid source. This is a default value and should be ignored in case the `result` is true.
*   `1` - Source doesn't accept target as destination.
*   `2` - Target doesn't accept source.

[1]: https://github.com/GrapesJS/grapesjs/blob/master/src/dom_components/config/config.ts

[2]: #getwrapper

[3]: #getcomponents

[4]: #addcomponent

[5]: #clear

[6]: #addtype

[7]: #gettype

[8]: #gettypes

[9]: #components

[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[14]: getComponents

[15]: https://grapesjs.com/docs/modules/Components.html#define-new-component

[16]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined

[17]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number