In this tutorial we are going to create a new custom theme for Stackbit using Unibit. We will then convert it into another static site generator (Hugo) and connect it to a Headless CMS (DatoCMS)

If you wish to convert your theme into other static site generators the theme must be built with Unibit. You may also import themes built on other static site generators (like Gatsby) but they can only leverage the functionality that connects to Headless CMS and deployment etc.

Installing Unibit

npm install -g unibit

For more Unibit CLI commands see Unibit Installation Docs

Creating the basic site structure

Let's start by reviewing the basic file structure of a Unibit site.

  └── my-theme
      ├── layouts                    
      │   ├── body.html           [required extends from base.html]
      │   ├── home.html           [extends from body.html]
      ├── components
      │   ├── html_head.html      [reserved, required]
      │   ├── post_body.html      [reserved, required]
      ├── content
      │   ├──
      ├── static
      │   └── *                   [any static files will be copied to final site]
      ├── stackbit.yaml           [required for importing theme in]
      └── config.yaml              

Create a new folder called my-theme (or whatever you would like your sites project folder to be named). Create the following folders layouts, components, content, static.

config.yaml and stackbit.yaml

The config.yaml and stackbit.yaml files live in root directory and provide much of the sites global configuration.

Create a new file called config.yaml - the config.yaml contains site properties that can be used in theme layouts.

// config.yaml
baseurl: "/"
title: "Universal"
  homepage_heading: "Universal Tutorial"

Create a new file called stackbit.yaml - the stackbit.yaml is used to define a content model which enables conversion to other static site generators and connecting to a variety of headless CMS. We will cover this in more detail in Part 2 of the tutorial.

// stackbit.yaml
stackbitVersion: ~0.2.39

body.html layout

Create a new file called body.html in the layouts folder

{% extends "base.html" %}
{% block body %}
<div class="wrapper">
  {% block content %}{% endblock %}
{% endblock %}

body.html is the only required layout file and it must extend from base.html. Unibit uses Nunjucks templating and the extends and block tags are part of Nunjucks template inheritance.

base.html is an internal file that is generated by Unibit, you cannot edit or override it but body.html must extend from it.

htmlhead.html and postbody.html components

For the base layouts to work we need to add 2 required components used by base.html

Create a new file called html_head.html in the components folder

// components/html_head.html
<title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Create an empty file called post_body.html in the components folder

Homepage layout

Create a new layout called home.html

{% extends "body.html" %}

{% block content %}

<h1>{{ site.params.homepage_heading }}</h1>
<h2>{{ page.params.sub_heading }}</h2>

{{ page.content  }}

{% endblock %}

Homepage content

Create new Markdown file with the following content:

title: Home
template: home
sub_heading: "Welcome to my custom Stackbit theme"

This is the homepage

Building the site

At this point we have all the required files to compile our site. Let's build the site using Unibit. From the sites root directory run the command

unibit build

You will see the build output in the terminal. The production ready static site has been generated into the /public/ folder. If you look inside the public folder you will see at this stage a single index.html file. As you can see it as bundled all of the layouts together and the content from the markdown file has been injected into the content area.

To preview the site you can use a simple webserver to serve the files in the public folder

npm install -g http-server

From the projects root directory run http-server ./public