January 11, 2026 · 6 min read★ Featured
Wagtail’s power comes from how it organizes content. In this post, we’ll explore its project structure and how StreamField lets you create dynamic, reusable content blocks.
In the last post, we explored how APIs bridge the frontend and backend. But before your frontend can fully leverage that content, it needs a well-structured backend. That’s where Wagtail’s project architecture and StreamField come in.
Wagtail is more than a CMS. It’s a framework that gives you flexible content modeling. Understanding its structure is key to building decoupled, dynamic websites.
Before diving into project structure, it helps to understand who developed Wagtail and its connection to Django.
Wagtail was originally developed in 2014 by Torchbox as an open-source content management system. It is built on top of Django, so it inherits many of Django’s conventions, such as:
Because of this, developers familiar with Django will feel at home using Wagtail. At the same time, Wagtail adds CMS-specific features like StreamField, page hierarchies, and image handling that make content management flexible.
For more information, check the official Wagtail documentation and Django documentation.
What is a typical project structure?
A typical Wagtail project looks like this:
myproject/
├── myproject/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── home/
│ ├── models.py
│ ├── templates/
│ └── wagtail_hooks.py
├── blog/
│ ├── models.py
│ ├── templates/
│ └── wagtail_hooks.py
├── core/
│ ├── blocks.py
│ ├── mixins.py
│ └── utils.py
├── static/
└── manage.py
Project folder (myproject/)\
Contains global settings, URL configuration, and WSGI/ASGI entry points. Think of it as the “brain” of your project.
Core app (core/)
Houses reusable code: StreamField blocks, mixins, utility functions, and shared templates. This ensures consistency and reduces duplication across apps.
Apps (home/,blog/, ...)
Each app handles a content type or feature. Apps are modular—like LEGO blocks, you can add or remove them as needed.
Models (models.py)
Where your content structure lives. Pages, blocks, and custom content types are defined here.
Templates (templates/)
Standard Django templates render content if you’re not fully decoupling.
Static (static/)
Holds CSS, JavaScript, and images for frontend rendering.
This modular structure is essential when you want to decouple your frontend: it keeps content organized and easy to fetch via API.
At the heart of Wagtail’s flexibility is StreamField. It allows content editors to build pages from reusable, composable blocks, instead of being restricted to rigid page fields.
Think of StreamField like LEGO bricks:
Think of building a page like assembling a custom sandwich at a deli:
This analogy helps editors and developers understand why StreamField is flexible but controlled—just like picking sandwich ingredients within a menu.
from wagtail.models import Page
from wagtail.fields import StreamField
from wagtail import blocks
from core.blocks import CalloutBlock
class BlogPage(Page):
body = StreamField([
('heading', blocks.CharBlock(classname="full title")),
('paragraph', blocks.RichTextBlock()),
('image', blocks.ImageChooserBlock()),
('callout', CalloutBlock()),
])
CalloutBlock lives in the core app, making it reusable across multiple apps without duplication.In a decoupled Wagtail project, multiple apps often share functionality—blocks, mixins, templates, or utility functions. The core app is the place for all shared code:
core/
├── blocks.py # Reusable StreamField blocks
├── mixins.py # Shared page behaviors
└── utils.py # Helper functions
Benefits of a Core App:
Example:
# core/blocks.py
from wagtail import blocks
class CalloutBlock(blocks.StructBlock):
title = blocks.CharBlock(required=True)
message = blocks.TextBlock(required=True)
# blog/models.py
from core.blocks import CalloutBlock
from wagtail.models import Page
from wagtail.fields import StreamField
class BlogPage(Page):
body = StreamField([
('paragraph', blocks.RichTextBlock()),
('callout', CalloutBlock()),
])
This pattern keeps your project DRY (Don’t Repeat Yourself) and makes your frontend API consistent.
core/: Easier imports and maintenance.After understanding project structure and StreamField:
Mastering Wagtail’s structure, StreamField, and core app concepts sets the foundation for building powerful, maintainable decoupled content-driven applications.
Reach out via the contact form or connect on Linkedin!