Drag and Drop Areas

Last updated:

This page illustrates and explains the dnd_area experience and concepts. Because this experience is fairly encompassing it's a good idea to get familiar with it before diving into code. 

Once you are ready to build, see getting started with dnd_area, and the dnd_area reference.

Drag and drop areas allow developers to create areas of pages that empower content creators. Drag and drop areas allow content creators to place modules, change layout, and some styling within the content editors. This enables you to create fewer templates, which content creators can use to make a multitude of pages with various purposes and layouts on their own. Content creators can do this without ever fumbling with code or requiring new templates for small layout changes. Because they're so flexible and useful it is a good idea to have at least 1 template in your theme include drag and drop areas.

Drag and drop areas can't be used in blog listing, blog post, and email templates at this time.

The content creator experience

When a content creator creates a page using a template that has drag and drop areas they first see the page with predefined modules placed in a layout by the developer. This helps the content creator to understand how visually most pages using this template should or tend to look. This is a starting point however not a locked-in appearance. The content creator can drag and drop modules, sections, rows, and columns around to re-arrange them. They can resize them, edit their content, and adjust various visual styling settings which enable them to vertically and horizontally align content and add backgrounds.

For content creators this is a lot of power. This gives them enough flexibility to make simple  page changes without bugging a developer for small tweaks.

The page editor experience for dnd_areas

The developer experience

For developers working with dnd_area is semi-similar to working with common CSS frameworks and their grids. Developers lay out the page using containers called sections, which contain  rows. Inside of those rows are modules and columns. Nearly everything that content creators can do in the page editor with drag and drop area tags developers can do in code in the templates themselves. What developers are building is the default content for pages using that template.

The benefit of using drag and drop areas versus hard coding modules tags into the template, is that content creators can change the content and layout inside of them. Because of this flexibility one template with drag and drop areas can solve for a multitude of page designs. 

For a taste of what this looks like in your code the CMS Theme Boilerplate templates are built using dnd_area.

dnd_area coded in VS Code

Drag and drop areas and their elements

Drag and drop areas are made up of a handful of building blocks that define the layout and support styling alignment flexibility. The dnd_area tag creates a region in the page that the page editor recognizes, enabling adding, removing, and rearranging of drag and drop elements. You define these using HubL inside of HTML+HubL templates. All of the drag and drop elements live inside of a drag and drop area. You cannot nest drag and drop areas, and drag and drop elements cannot contain drag and drop areas themselves. 

An important thing to understand as developers is that the contents of the drag and drop area  you define in the template, is a starting point for pages using that template. Content creators can completely change the content within a drag and drop area. Your job is to provide a sane starting point for them to modify from.

Example structure

This diagram is a breakdown of how the various drag and drop elements can be nested. A key concept to understand is that both sections and rows can contain columns and modules.

Drag and Drop element relationships


Sections are a special type of row. Sections are created in templates using the dnd_section tag. They are the only drag and drop element that can be a direct descendant of a drag and drop area. You can think of sections like an outer wrapping container. They can enable content to be full width or have a confined center max width. Because sections wrap around columns and modules, it makes it easy to rearrange and implement large portions of content. The dnd_section tag does not render an HTML <section> element.

Section in page editor

The appearance of a section in the page editor.


Columns are wrappers for rows and modules. You place columns inside of a row, or section which is a specialized row. Columns are created in templates using the dnd_column tag.

Use multiple columns inside of a row to place rows and the modules they contain horizontally. 

Columns are vertical regions that can contain rows. You can make columns of different sizes by changing their width. A row’s size is 12 "columns" wide, this refers to the CSS grid. The columns inside of a row can be any size smaller than 12 but cannot add up to more than 12.

When multiple rows are placed inside of a column the modules inside of those rows will appear vertically stacked. Since modules are columns themselves, a module cannot be a direct descendant of a column, they must be contained within a row.

dnd_area column in page editor

The appearance of a column in the page editor.


Rows are wrappers for columns. Rows are created in templates using the dnd_row tag. Since modules are columns you can place them directly inside of a row. This will cause the modules to appear horizontally adjacent to each other.

Modules can be organized vertically by placing them inside of rows. If you want to place a module above another you would place that module inside a row. You would then add another module in a row above or below that first row. 

dnd_area row in page editor

The appearance of a row in the page editor.


Modules are a fundamental part of the HubSpot CMS, acting as reusable building blocks that you use to piece together a site, and display content. When building a template you place modules inside of drag and drop rows and sections using the dnd_module tag. Modules are also columns. Meaning if you place two module tags, or a module and a column directly next to each other, they will appear side-by-side horizontally. 

No drag and drop elements can be placed within a module. Modules cannot be direct children of a dnd_area.

HTML structure and styling

Drag and drop areas and their elements when rendered have class names for a 12 column grid based on bootstrap 2. To make it easy to get up and running, you can use the _layout.css file from the CMS Theme Boilerplate. This provides default styles for those class names. 

You are not required to use this stylesheet and can provide your own styles instead. If you are building your site based off of the CMS Theme Boilerplate and want to use your own CSS, you will want to remove layout.css from being called in base.html. For your own CSS grid you will need to target those same grid class names, but the styling is up to you.

Drag and drop areas when rendered create divs with classes that are used by the page editor. Examples would be widget-span and widget-type-cell. You should not directly target these classes as they are used by page-editor and could change down the road.

Instead in your dnd_area HubL add a class parameter with a class name you would like to use

<div class="container-fluid my-custom-class">
    <div class="row-fluid-wrapper">
        <div class="row-fluid">
            <div class="span12 widget-span widget-type-cell " style="" data-widget-type="cell" data-x="0" data-w="12">
            <!--end widget-span -->

Editor and attribute styling

With drag and drop areas content creators can have some effect on styling of the page. For example they can set a section to have a background. Developers can pass default values for those settings through attributes.

When the page is actually rendered, the styles that are generated based on those settings is added to the standard_header_includes.

At launch of dnd_area those styles were loaded from standard_footer_includes. That was changed recently to standard_header_includes and is rolling out to all HubSpot accounts with the HubSpot CMS.


If you are changing templates built with flexible columns to now use drag and drop areas there's a few things you should understand. Flexible columns are not the same as drag and drop areas, you can't swap from a template that only has a flex column to one that only has a drag and drop area. We don't allow this as a safety precaution. The content would not map from the flex column to the drag and drop area. To illustrate why this is, suppose you built your new template so you have a sidebar and a main content area. Your sidebar is a flexible column, your main content is a drag and drop area. The swapping tool would map the flexible column to the flexible column.