How to build a landing page using Wagtail CMS

Michael Yin

Full Stack Developer

Last updated on Feb 22 2020

Table of Contents


Wagtail CMS is a very good option if you want to build a dynamic landing page application.

  1. The Streamfield feature of Wagtail can let you customize your data model to fit the design.

  2. The FormBuilder feature of Wagtail can let you build a flexible and powerful form to collect data.

  3. Wagtail CMS is based on Django, which means you can use 3-party apps of the ecosystem to extend its feature easily.

In this Wagtail CMS tutorial, I will teach you how to build a simple landing page using Wagtail, we would let the editor can control data displayed on landing page in Wagtail admin.

startbootstrap-freelancer is the landing page theme here because it is based on bootstrap so it would be easy to modify or extend the theme.

Note: source code of this tutorial is available at wagtail-freelancer

Step 1 - Analyze the landing page template, build data models

First, let's take a look at the sample landing page and try to analyze it.

Below are the fields that we wish to make them editable.

  1. Title (Start bootstrap)
  2. Subtitle (Web Developer - Graphic Artist - User Experience Designer)
  3. Profile image
  4. Portfolio (Contains more than one block)

We would talk more about portfolio in the next step, let's first define page models to make other fields editable, and below is the code snipprt.

class FreelancerPage(AbstractForm):

    subtitle = models.CharField(max_length=100, blank=True)
    profile_image = models.ForeignKey(

    content_panels = AbstractForm.content_panels + [
        ], "Hero"),
            FieldPanel('about_text', classname="full"),
        ], "Hero"),


We also need to modify template to make the value to show in page. If you have experience with HTML, this would be super easy.

{% if page.profile_image %}
  {% image page.profile_image original as profile_image %}
  <img src="{{ profile_image.url }}" class="img-fluid mb-5 d-block mx-auto rounded-circle">
{% else %}
  <img class="img-fluid mb-5 d-block mx-auto rounded-circle" src="{% static 'freelancer/img/profile.png' %}" alt="">
{% endif %}

<h1 class="text-uppercase mb-0">{{ page.title }}</h1>
<hr class="star-light">
<h2 class="font-weight-light mb-0">
    {{ page.subtitle }}

Step 2 - Implement custom data models using Streamfield of Wagtail

Most CMS can get tasks above done in an easy way, but I really doubt if they can also get tasks below done in an elegant way.

Sometimes, we wish to define custom data models in pages so we can better manage them without touching tedious HTML.

Here, what is the best way to create&edit the content of portfolio?

  1. We can treat portfolio field in the page as a container.
  2. The portfolio container can contain multiple portfolio block
  3. Eash portfolio block has title, image, text fields.

We can add content to portfolio block , edit, reorder to manage the portfolio of the page.

Wagtail has a tech called StreamField to help us get this job done. With simple model definition code, we can config the model.

class FreelancerPage(AbstractForm):

    portfolio = StreamField([
        ('portfolio', PortfolioBlock()),
    ], null=True, blank=True)

    content_panels = AbstractForm.content_panels + [

class PortfolioBlock(blocks.StructBlock):
    heading = blocks.CharBlock(classname="full title")
    image = ImageChooserBlock()
    intro = blocks.RichTextBlock()

As you can see this is very clean and easy to manage.

Please check the video below to see how StreamField works here.

Step 3 - Use Formbuilder of Wagtail to build form

In most landing pages, there would be a contact form for the reader to contact the site owner.

But, what if I want to add another field to the form, for example, a dropdown list which tell me your profession? Can I get it done without coding?

Wagtail has a FormBuilder feature to help editor create a flexible custom form with just clicks.

Here I would show you how to use it to build a simple contact form, but you can also use it to build your own custom form.

class FreelancerFormField(AbstractFormField):
    page = ParentalKey('FreelancerPage', related_name='form_fields')

class FreelancerPage(AbstractForm):
    content_panels = AbstractForm.content_panels + [
        InlinePanel('form_fields', label="Form fields"),

As you can see, this is easy and clean. After you defined the FreelancerPage, you an add, edit form fields in Wagtail admin. No coding needed any more.

Please check video below to see how FormBuilder works in Wagtail.


In this Wagtail tutorial, we learned how to use Wagtail CMS to build a landing page application, Wagtail CMS has 2 advantages compared with other CMS.

  1. The StreamField is flexible and can let you define custom models in easy way.

  2. The FormBuilder feature is also powerful and flexible, you can quickly build custom form in your application without using 3-party services.

So where should you go next?

  1. You can try to import Recaptcha to your form to avoid spam, please check wagtail-django-recaptcha

  2. If you want to know more about StreamField, please read Wagtail StreamField tutorial

  3. FormBuilder also support email notification, please read Wagtail FormBuilder tutorial

Note: source code of this tutorial is available at wagtail-freelancer

You can also check the full list of my wagtail tutorial here wagtail tutorial series

Table of Contents

Subscribe to get notified about new great blog posts about Web Development

Let’s Work on
Contact Us


Get notified about new great Web Development Tutorial