Use GrapesJS For Building Web Builder Framework

GrapesJS is a Free and Open Source Web Builder Framework that provides an extensive set of HTML elements from which you can build HTML templates without any knowledge of coding. You can see a demo, and you can add new building blocks according to your need. GrapesJS was designed to create dynamic templates faster and easier.

This post is about to give you an idea of what is Grapesjs and how you can extend it to build your own web builder. You will get to know how to do initialization and how can you add different blocks and components, how you can use built-in component types and create your own custom types, and also how to style your components.

Initialization:

First, you have to install grapesjs and then initialize the editor.

 

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

<div id="gjs"></div>

<script type="text/javascript">
  var editor = grapesjs.init({
      container : '#gjs',
      plugins: ['grapesjs-preset-webpage', customBlocks, customTypes]
  });
</script>

 

Plugins:

Contain all the building blocks which you can use to make Html templates, grapesjs-preset-webpage is a dependency that provides default building blocks of grapesjs.

 

Blocks:

Block is a group of components that you can easily drag and drop in the editor canvas and you are able to remove, copy and move that block inside the canvas. GrapesJS provides built-in blocks but you can also make your own custom blocks using BlockManager. e.g.

 

const myFirstBlock = editor = {
 var blockManager = editor.BlockManager;
 // 'my-first-block' is the ID of the block
 blockManager.add('my-first-block', {
  label: 'Button',
  content: {
    type: button, 
    tagName: 'button',
    draggable: false,
    attributes: { class: 'container'},
    style: { 'background-color': '#ffffff' },
    content: "Change Title",
  }
 });
}

 

In this way, you can make your own custom blocks and add different attributes to them. You can also set default styling and different attributes such as draggable: false. After creating blocks you have to add the block name to the plugins array at the time of initializing the editor. e.g.

 

 var editor = grapesjs.init({
      container : '#gjs',
      plugins: ['grapesjs-preset-webpage', myFirstBlock ]
 });

 

Now our first block has been added to the editor at the end of collections as you can see in the screenshot below.

 

Grapesjs

 

You can also update existing blocks e.g.

 

blockManager.get('my-first-block').set({
  label: 'Updated simple block',
  attributes: {
    title: 'Updated title'
  }
})

 

Component:

Each element you dropped in the canvas is transformed into a GrapesJS component. You can also add different components in a block you can nest components as much as you can, and then rearrange the element with the help of the editor. Grapesjs editor provides the ability to see the HTML and CSS code structure and you can also see designs on different screen sizes to check responsiveness.

 

{
  tagName: 'div',
  components: [
    {
      type: 'image',
      attributes: { src: 'https://path/image' },
    }, {
      tagName: 'span',
      style: {
       'background-color': '#ffffff',
       'font-family': 'Ubuntu, sans-serif',
      },
      type: 'text',
      attributes: { title: 'foo' },
      components: [{
        type: 'textnode',
        content: 'Hello world!!!'
      }]
    }
  ]
}

 

Component Type:

You can use built-in types for elements and also create custom types and can customize accordingly in the following way.

 

editor.DomComponents.addType('my-cusotm-type', {
  isComponent: el => el.tagName === 'INPUT',

  // Model definition
  model: {
    // Default properties
    defaults: {
      tagName: 'input',
      draggable: 'form, form *', // Can be dropped only inside `form` elements
      droppable: false, // Can't drop other elements inside
      attributes: { // Default attributes
        type: 'text',
        name: 'default-name',
        placeholder: 'Insert text here',
      },
      traits: [

           // discussed in the below sections.
      ],
    }
  }
});

 

isComponent method receives a parsed HTMLElementNode which makes the editor understand when to apply my-custom-type. The model property holds the description of your component and you can access all the child elements through the model and modify it. You have to add custom types in the plugins array as we did for blocks during initialization. You can also update component types using the AddType method.

You can also add event listeners on props or attribute changes in the init function and trigger functions on changes while adding custom types. e.g.

 

editor.DomComponents.addType('my-custom-type', {
  // ...
  model: {
    defaults: {
        // defined above
    },

    init() {
      // Listen to any attribute change
      this.on('change:attributes', this.handleAttrChange);
      // Listen to title attribute change
      this.on('change:attributes:title', this.handleTitleChange);
    },

    handleAttrChange() {
      console.log('Attributes updated: ', this.getAttributes());
    },

    handleTitleChange() {
      console.log('Attribute title updated: ', this.getAttributes().title);
    },
  }
});

 

After initializing, you can get a component instance, that instance will be responsible for the final data of your template which you can use and change accordingly. e.g.

 

const components = editor.getComponents()

 

Then you can find your required component based on its type, attributes, or identifiers. 

You can use different methods such as getAttributes, setAttributes, etc.

 

const componentHTML = component.toHTML();
const componentType = component.get('type'); // eg

 

Each component triggers a lifecycle hook method based on the actions such as triggering updated hook method when the model is updated and triggers removed hook method when the model is removed.

 

Panels:

GrapesJs provides a Panel from which you can perform actions.

 

grapesjs

 

This is the GrapesJS default Panel from which you can clear canvas, preview web pages, see HTML and CSS code and perform some other actions.

When you click on the panel button GrapesJS executes the command which we have discussed above. 

If you are extending GrapesJS, you may need to add new options in the Panel. Let’s add a new button in the Panel.

 

editor.Panel.addButton('views', {
     id: 'sign-out',
     label: 'Sign Out',
     className: 'fa fa-sign-out', // button icon
     command: {
       run: () => {
         // When sign-out button is clicked, this command will be   executed;
         signOut()// sign out the user from system
       }
     },
  });

 

LayerManager:

Grapesjs also provides the ability to manage the HTML node tree structure. You can easily see the parent and child of each node or HTML element, and you can easily change the position of the node through the layer manager using drag and drop which makes it easier to manage the tree structure. You just have to specify where you want to render your layer manager during initialization.

 

layerManager: {
   appendTo: '.layers-container'
},

 

Looking to hire a Grapesjs Development team

Share the details of your request and we will provide you with a full-cycle team under one roof.

Get an Estimate

 

This is the tree overview of the structured nodes and it is also showing the count of child nodes.

 

grapesjs

 

StyleManager:

GrapesJS provides a StyleManager module, which helps you to style any component which is present in the canvas.

 

styleManager : {
    sectors: [{
      name: 'Dimension',
      buildProps: ['width', 'min-height']
    }]
}

 

You can add any CSS property in the build props array, and then apply it to blocks using the editor.

Through the component model, you can change and get the style of every component.

 

const models = editor.getComponents().models
 model.addStyle({
    'height': '50px',
 });
const style = model.getStyle();

 

StyleManager also allows you to set CSS for different states such as hover, and active using editor and you can also change CSS for hover state dynamically with the CssComposer module.

 

const id = model.getId();
editor.CssComposer.setRule(`#${id}:hover`, { 'color': 'red'  });

 

Traits:

Traits are the element attributes such as title, placeholder, checkbox, and dropdown. The common use of traits to give access to users to set attributes of components such as placeholder, and title. You can bind different input traits on elements and react to change. You need to write the following code to add custom traits and retain existing trait functionality.

 

domComponents.addType('my-custom-type', {
         model: {
           defaults: {
             traits: [  ...domComponents.getType('my-custom-type').model.prototype.defaults.traits, // to retain default traits
               {
                 type: 'select',
                 label: 'Custom Trait',
                 name: 'custom_trait',
                 options: [
                     { value: '', name: 'None' },
                     { value: 'Js', name: 'Javascript}
                 ]
               }
            ],
         }
      }
 });

 

Device Manager:

You can also view your HTML pages on different screen sizes using device managers to make responsive templates.

 

deviceManager: {
       devices:
       [
         {
           id: 'desktop',
           name: 'Desktop',
           width: '',
         },
         {
           id: 'tablet',
           name: 'Tablet',
           width: '768px',
           widthMedia: '992px',
         },
         {
           id: 'mobilePortrait',
           name: 'Mobile portrait',
           width: '320px',
           widthMedia: '575px',
         },
       ]
     },

 

By default GrapesJS provides three devices, you can override them and add new devices according to your needs. You can also trigger events when the device changes and also get the currently selected device.

 

editor.on('change:device', () => {
  console.log('Current device: ', editor.getDevice()
});

 

StorageManager:

After making your HTML pages, you need to save your pages and load them again when you want to change your templates. Grapesjs covers this important feature as well. By default, Grapesjs saves the data in local storage.

 

storageManager: {
       id: 'gjs-', // Prefix identifier that will be used inside storing and loading
       type: 'local',
       autosave: true,
       storeComponents: true,
       storeStyles: true,
       storeHtml: true,
       storeCss: true,
},

 

Other than that you can get the HTML and CSS of your template and save them wherever you want using these functions.

 

Html = editor.getHtml();
Css = editor.getCss();

 

You can load HTML and CSS using these functions.

 

editor.setComponents(Html);
editor.setStyle(Css);

 

Theming:

You can improve the theme of the editor for better visual representations by changing a few CSS rules. You can change the primary, secondary, and other hover state colors by overriding the default CSS rule, if you want to change the primary color for the background you just need to write the following CSS.

 

/* Primary color for the background */
.gjs-one-bg {
  background-color: #78366a;
}

 

Events:

Event Listeners are most frequently used in Javascript which we can use to perform specific tasks when the event occurs. GrapesJS provides multiple events which you can register with the help of the editor instance. If you want to override the existing functionality of GrapesJS you would need to find out when the GrapesJS has completely loaded,  otherwise, it wouldn’t work.

GrapesJS triggers the event when the loading is complete, you can listen to it in the following way with the help of the editor instance:

 

editor.on('load', () => {
     let styleManager = editor.StyleManager;
     let fontProperty = styleManager.getProperty('typography''font-family');
     fontProperty.set('defaults', 'Roboto');
     styleManager.render();
});

 

GrapesJS apply the default font-family of ‘Ubuntu’. If you want to change this font family according to your requirements, then you have to register the load event and have to change the default font family to ‘Roboto’ with the help of StyleManager as you can see in the above code block.

There are other events as well you can use according to your needs, such as:

  • Component Create Event
  • Component Update Event
  • Style Update Event
  • Property Update Event

Commands:

GrapesJS provides a set of commands, which are functions that can be used across the editor cycle. Grapesjs provides a set of default commands which we can use and extend. We can make our custom commands as well. Once the command is executed, nothing is left behind just like a simple function. But grapesJS provides a feature of stateful commands from which you can find out what was the last returned value from the command. For stateful commands, you have to use both run() and stop() methods.

If you want to clear canvas, Grapes provides a command, you have to run the following code:

 

editor.runCommand('canvas-clear');

 

‘canvas-clear’ is the default command of GrapesJS. If you want to extend the default command, you can do it in the following way:

 

editor.Commands.add('canvas-clear', editor => {
    editor.DomComponents.clear();
    editor.CssComposer.clear();
});

 

You can add your own functionality in the above code block. For custom commands use the following pattern:

 

editor.Commands.add('custom-command', {
   run(editor) {
    alert(`Command is active`) 
     return “Grapesjs”
   }
   stop(editor) {
     alert(`Command is disabled`)
   }
})
editor.runCommand('custom-command');
console.log(editor.Commands.getActive()); //return “Grapesjs” which is last return value of command
editor.stopCommand('custom-command') // stop command

Moreover, GrapesJS provides a lot more features that can make your life easier by minimizing the codebase.

 

Share this article

Leave a comment