How to build a super dynamic website with Gatsby.js and Contentful.

Do you want to know how to create hundreds of pages for marketing in a short time? If yes, you in the right place.

Aleksei, Chekmarev
Billie Engineering Crew
6 min readDec 20, 2019

--

© Illustration: Adriano García Suárez/Billie

After choosing a CMS (How we choose a CMS) we decided upon Contentful. This is a great service to manage all content. To create our website we built an architecture, which based on sections.

So we created two content models in the Contentful, one for pages

app.contentful.com: content model Pages

and one more for sections.

app.contentful.com: content model Section

Each section looks almost the same, it has type, title, text, image and maybe a button. Later we added className and imageMobile, even if we have SVG images and grid.

Type as template

The main field here — type. In Contentful we created it as a dropdown of the types by design, for example, SectionTop, SectionInfo, SectionContact. It was the main trigger to get a template for the frontend. The challenge was to create pages in gatsby when you don’t know anything about them, even the link or name.

Here Gatsby.js comes to our help. Gatsby.js is super cool, it has methods to create pages for you (create pages). After issuing a request to Contentful to get all pages we dynamically create all pages inside a Promise.

Inside pages Template, we need just to fill the page with the proper sections and templates for it. All of this we create as normal React Component and which we dynamically import when we need it.

So we finished the website. Content for the main page looks like this.

app.contentful.com: content Main page

When we navigate to the SectionMainTop we are able to see all the content and edit or remove anything we like.

app.contentful.com: content SectionMainTop banner

It’s so great, the marketing team doesn’t need to ask a FrontEnd developer to change anything in the content. Anyone with zero knowledge of development, can add pages, edit text, replace images or anything they like.

From our perspective, it’s also a big plus that the marketing team is unable to modify the overall UX of the site. We maintain control over the look and feel of the site, SEO and functionality. Our internal users have exactly the amount of flexibility they need and we maintain the control we need to ensure a good frontend user experience.

But, not always so smooth…

After showing this flexible and super dynamic website to the marketing team, we encountered a new problem. It was to slow for the marketing team to create landing pages which were almost all nearly the same design! What the marketing team needed was a template that was easy to copy and modify — because this was what they wanted to do 70-odd times.

So that’s what we created for them…

We decided to create one more template for the marketing team with a simpler content model. The new content model was not comprised of sections. It was built to be copied and modified.

Now you can duplicate the page without creating a new section.

app.contentful.com: a new content model for a Marketing page

As you see, we just add a big list of the fields that we need on the page. All information is mixed now, main banner and title with text for it.

New problems with GraphQL

New content modal was a good idea for marketing, but it was different enough from our old architecture to cause us problems. Remember that we dynamically hydrated react components with content and instantiated those by name where the name was equal to the sections in contentful.

We needed to support both content models, a sophisticated one for complex pages with sections like our front page and the simplified model for marketing pages. We renamed the id for all fields so that it would be convenient to parse it in a loop and use it in already created templates. Contentful was able to let us map these fields from meaningful names like ‘headline-top’ to less user-friendly (but more convenient) names like ‘title0’ which were used in our code.

app.contentful.com: settings content model filed

We decided to make it work was to dynamically instantiate react components in a loop and hydrate the state of a page component with these components. Thanks to Contentful validation and the ability to make all fields required, we were able to make this solution work reliably, avoiding problems with GraphQL schema. We split all the fields, checking if the next element is a title and add to a special object to use in the template. Of Course, we know which one we want and where, so we just hardcode templates. It’s only an array of the type sections on the page.

Then in the loop, we create a new array of the sections to be able to use templates.

In the end, we also added sections that we already have, info block or feedback. In this model, it’s not possible to add sections in the middle of the page, but you can check in the loop for different types (this was enough for us).

Fully dynamic import.

It was a big problem to understand how to render components if we didn’t import them before at the top of the JSX file.

The great thing is to use Loadable in the loop inside render. We used one amazing higher-order component for loading components with dynamic imports.

First, we implemented react-loadable, but it’s not maintained anymore. Then we decided to use loadable-components and there is no problem so far.

Here the documentation about the library.

react-loadable was the recommended way for React code splitting for a long time. However, today it is not maintained any more and it is not compatible with Webpack v4+ and Babel v7+.

There also other solutions for it, React lazy or Universal-component.

This is how we render all content for pages.

So basically we have an array of the objects for sections (editableBlock). We made a list of the types of sections for the current page (sectionsList), and import all components on the fly.

This is a list of templates (aka types) of the sections

The marketing team was really happy, we were happy to help them, everyone was happy! They can create lots of pages very quickly, for example, partner pages dedicated to each partner using the same template. We received a lot of thanks from the sales team, even though for now this is just the first version of our CMS.

I hope sharing our experience in dynamic content management will enlighten and enable y’all to create your own amazing content management solutions. Thank you for reading.

--

--