Front-end development with Hubspot Part 1

Recently, we’ve started using Hubspot, which is a service that helps companies with their inbound marketing. It provides a content management system (which they call a ‘content optimization system’ :p) that can be hooked in to fairly easily. For me, its syntax is very similar to twig, a popular php templating language. It provides control structures, filters, functions etc. There’s some nice bits and some truly flakey bits – here’s what I’ve learnt so far…

Hubspot templates can be created either through the web ui or locally and then synched using their ‘cos uploader‘ tool. This seems like a great idea providing you watch out for a few little annoyances. By working locally, you can version your source files using whatever you want. Actual content is versioned in the hubspot back-office.

The challenge

So, we tried to devise a workable development process. This needed to meet the following conditions –

  1. would allow designers to create a flat site where basic functionality could be tested locally.
  2. would allow the flat templates to fairly easily be split up ready for inclusion in hubspot
  3. would separate out dev work from production-ready templates, meaning that it would be possible to work on and show new features to clients within hubspot without affecting existing live templates and modules.

We are not completely there yet, and I know there are facets of our solution that could be improved, but we’re getting there.

File structure

After watching a few fairly cryptic videos on the hubspot website, and then contacting the hubspot hq for more info, we arrived on the following file structure –


  1. components – this contains all stuff thats common to all environments, including images, scss, js and custom modules for use in hubspot (note that custom modules can’t be built and uploaded using the cos_uploader, they must be made inside the hubspot ui)
  2. flat – this area contains flat files that allow designers to work locally without any dependency on hubspot
  3. dev
    • All files in the dev area get uploaded to a corresponding ‘dev’ area in hubspot. Inside the ‘files’ folder, there is another ‘dev’ folder, which holds images. This is necessary, since the uploader will upload anything in the ‘files’ folder using a corresponding structure. So, with this setup, its possible to work on ‘dev’ images, that are separated from images used on the live site (but potentially with the same name)
    • Templates contains all the site pages, as well as a separate ‘assets’ folder which contains compiled css and javascript. All these files need to contain hubspot meta data, which determines where the file is uploaded.
  4. prod – Same as dev except files and templates in this folder get uploaded to the ‘prod’ area.

Each environment needs to have a ‘files’ folder and a ‘templates’ folder. Anything in files gets uploaded to the file manager in hubspot using the same folder structure as has been set up locally. So, in the dev environment ‘files’ folder, there is another ‘dev’ folder, meaning that all assets inside here will get uploaded to a ‘dev’ folder in hubspot. In the same way, the prod environment has a ‘prod’ folder inside the ‘files’ folder.

Required stuff

Each code file (html, css, js) that needs to be uploaded to hubspot needs to have the hubspot metadata added to it, which looks like this…

 "category": "include", 
 "creatable": false, 
 "id": 2910118466, 
 "path": "dev/_master.html"

You can read about all the parameters here:

A few points to note…

  1. You don’t need to specify the full path, only relative to the area it will be uploaded into. So, for includes, these will go into the ‘coded files > custom > system’ folder. The above example would go into the ‘dev’ folder of this area, creating a file called ‘_master.html.’
  2. Initially, there is no need for an id. Once the uploader uploads the file, it will add the id into the file.
  3. For css and js, according to hubspot, you don’t need to add the ‘category’ field, but it doesn’t hurt either.
  4. CSS and Javscript should not be added to the file manager of hubspot. So, they need to go in the ‘templates’ folder. In the example above, we split out the ‘templates’ folder to have an ‘assets’ folder that contains the compiled css and js.


This is fairly simple

  1. designers work on flat site
  2. when ready, grunt is used to copy assets to the dev environment
  3. In dev, the files are split up into templates, hubspot metadata is added and hubl markup to add CMS (sorry, COS) integration.
  4. Files are uploaded (inside the dev folder there is an instance of the cos_uploader)
  5. When ready, grunt is used to copy assets to the prod environment

The tricky thing that we can’t see a way around at the moment is the point at which flat is copied to dev. Since files are split up, copying between flat and dev can only really happen once. It kind of cuts the link between flat and dev so both must be manually kept in synch.

Hubspot file structure

There are a number of ways to set up templates in hubspot. You can create includes that can be added to certain pages or you can create an inheritance type structure whereby you create a base template that other child templates inherit. The base template defines blocks that are re-defined inside child templates. This is kind of similar to how razor works in .net or twig in php.

So, that’s what we did. We’ve got a master template that defines a few blocks that are filled in by child templates.

<body class="{%block page-class %}{% endblock %}">

{% block page_content %}{% endblock %}

{% block footer_scripts %}{% endblock %}

This is standard hubl markup syntax. To actually use this in a child template, you’d do the following…

{% extends "custom/pages/dev/_master.html" %}
{%block page-class %}
{% endblock %}

{% block page_content %}
<h1>Page title</h1>
{% endblock %}

This is a snippet from the index page. It extends the master template.

Weird thing

The weird thing here is that its referencing the master template which, in hubspot exists in the ‘custom > system > dev’ folder. However, the public reference to the master template is ‘custom > pages > dev,’ even though it doesn’t exist in the ‘pages’ folder.

To be sure what the public url for the template is, you can go to hubspot, look at the coded file from the design manager and select ‘actions > get public url.’


 Referencing css/js

Since these were added to the ‘coded files’ area of design manager in hubspot, you can get the public url for these in the same way as getting the public url of the master template. Then its a case of plonking that into your template.

<link rel="stylesheet" href="{{ get_public_template_url("custom/pages/dev/main.css") }}">

<script src="{{ get_public_template_url("custom/pages/dev/main.js") }}"></script>


That’s about it for the actual set up. The actual engine that drives the various build processes is grunt, which is discussed next.



2 thoughts on “Front-end development with Hubspot Part 1

  1. Hi Simon,

    Just wondering if you are still using this folder structure and workflow or if you’ve made improvements to it. Let me know, thanks!

    1. hi, thanks for the comment. After having worked on a few hubspot projects now, it seems they designed it to be used from the hubspot browser-based design manager. This does use things like versioning but it does mean its hard to use sass/less or other grid systems. But, hubspot at the moment forces you to use bootstrap 2 if you want to use the drag-and-drop template system. Pros and cons.

Leave a Reply