Video Tour of Wagtail 8.0
Published September 19, 2026
This video is from Wagtail CMS 2023 .
In this video, we enable Wagtails powerful Headless CMS (v2 API) by writing just 12 lines of code.
Wagtail comes with a lot of really powerful features. Many features are not enabled by default as to keep your site running quickly and efficiently. One of those amazing features is the Wagtail v2 API, which can return any page, image, document, orderable and StreamField as a JSON response for your SPA/PWA to consume.
To test your API endpoint, you can open your Browsers Console (right click - inspect - console) and type in this JavaScript, which will make a request to your main Pages listing view:
https://gist.github.com/KalobTaulien/9cff04417209e074b2b1f927af581ac4 (I wasn't allowed to paste the raw code, but here's the Gist)
Tutorial: https://learnwagtail.com/tutorials/how-to-enable-the-v2-api-to-create-a-headless-cms/
Git Commit: https://github.com/CodingForEverybody/learn-wagtail/commit/8988bd85cc88e6fb58e36ab4a2632b4358ae5fc4
Learn Wagtail from scratch with the official Wagtail for Beginners Course
https://learnwagtail.com/wagtail-for-beginners/
Used in this video: Wagtail 2.4, Python 3.7, Django 2.1.5 #Wagtail #Django #Python
Wagtail’s v2 API can expose pages, images, and documents as JSON for a headless CMS, allowing a separate frontend built with Vue, React, Angular, or another framework to consume the content. The speaker explains that the API in Wagtail 2.4 is read-only, then shows how to enable `wagtail.api.v2` and Django REST Framework, create an API router, register the three endpoints, and add the router to `urls.py` before the Wagtail URL include. Requests such as `/api/v2/pages`, `/images`, and `/documents` return list and detail data, while the existing Wagtail admin and website continue to work normally. Custom model fields are not included by default and will require additional configuration, which the speaker leaves for a subsequent lesson.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Hello and welcome back to another lesson on learning Wagtail. In this video, we're going to be getting started with Headless CMS. We're going to enable Wagtail's V2 API and turn our website into More like yeah, single-page application kind of website. Now, just as a disclaimer, we're not going to get into view. js, React, Angular, or any other front-end library. This is simply Wagtail. And the reason that we're not going to get into any front-end framework is because I don't want this to be a biased video for anybody. I want anybody to be able to come in. Learn how to enable Wagtails V2 API so that they can create headless CMSs with any front-end framework that you choose. So the first thing I need to do, as always, I need to go into my website.
Let's see this clear pip env shell and then python3 manage. py run server or just python manage. py run server if you're already if you're already running python3 And now our site is accessible at localhost port 8000. Now before we really get started, there's one more thing I need to tell you. This API is read-only. Now I'm using Wagtail 2. 4. And in future releases, this may support writing, but right now it is a read-only API. And honestly, for most websites, this is really good. This is pretty much all you need. And in fact, before we do that, I want to show you a website. So this is the TALUS World of Science Edmonton website.
This is a website that I had the pleasure of working on with a few other developers. This is using Wagtails Headless. CMS, it's using the V2 API, and it is running view. js, but you could do this in React or Angular or anything else. The nice thing about this is these page transitions are completely smooth. You notice how the page doesn't blink. It doesn't It doesn't flash in front of you anytime we change a page, which is really really nice. All of the data that we need to get is also fetched through the Wagtail Headless API. So this is just one cool website. There are probably thousands of them by now that are running something very, very similar to this But I just wanted to show you that, basically, by enabling Wagtail's headless CMS option, or the
the V2 API, we can really create any sort of single-page application. And if at any point in time you were like, well, I want my application to work on iOS and Android and maybe a desktop app, well, this is the way to do it. If you ever wanted to turn your website into a full application, this is the way to do it. The first thing we're going to need to do is we actually need to enable this. Now this already comes with Wagtail, which is pretty cool. And I'm going to throw this down here. Actually I'm going to put it with all the Wagtail stuff. Makes more sense to keep the Wagtail stuff with the Wagtail stuff. So I'm going to enable an app called Wagtail. api. v2. And just to make things really, really nice, uh, just give us some sort of GUI, I'm also going to install REST Framework.
Now these should come with your Wagtail installation, but if REST Framework does not come with your default Wagtail website for whatever reason, maybe you're using a different version of Wagtail, just make sure you do a pip install Django Rest framework. So we can close this down, close down our settings, and we need to open up our URLs. So this is one file that we're going to want to keep open. And right beside our URLs. py file, we're going to add a new file called api. py New file, api. py. And we need to import four different imports. We need to instantiate a Wagtail API router and we need to uh register three endpoints. So So the first thing we want to import here is our pages API
API endpoint. Nailed it. Uh and then images API endpoint. And also documents API endpoint. And then the last one we need to import is our Wagtail API router, which is going to handle URLs and all that good magic behind the scenes for us. Now I'm gonna leave those up there sort of as pseudocode and I'm gonna I'm just going to sort of write out the next few lines and we'll come back to the imports So the the next thing we need to do is we need to in instantiate some sort of API router. And this one's going to come from Wagtail API router and this takes a namespace as its only parameter. And we're gonna call it WagTail
API. And that is simply the URL namespace. That's all that one is. And then we actually need to register our endpoints. Like anything in Wagtail or Django, we need to register things. We can't just install anything willy-nilly and assume that things are going to work. This isn't WordPress, and that's how you get a really, really bad website. In Django and in Wagtail, we are explicit with everything. We make sure that things are done on purpose. And that makes sure that our applications are running the way that they should be running. And it's not going to surprise you at any point in time. So let's do an API router. register endpoint. And this is going to take some sort of name and some sort of Endpoint. And I'm going to copy that over three times.
And in our first one, we're going to call this pages, our second one is going to be called images, and our third one is going to be called documents. So the first parameter is simply your URL, and I'll show you those in a little bit later in this video about how we can customize those. And the second parameter is simply what we're importing here. So our pages. our images and our documents api endpoints so let's go ahead and copy those over let's make that a little smaller images Okay, and that's really all we need to do. And last thing we just need to finish off our imports. Now our import from Pages API is going to come from Wagtail. api. v2. dot endpoints
import and our images one is going to come from Wagtail dot images. v2 Import. And our documents, as you probably had guessed it. Wagtail. Documents. . v2. endpoints. import. And lastly our Wagtail API router. This one's gonna come from somewhere a little bit different. I guess not too different. This one's going to come from Wagtail. api. v2. v2. roder. Import Wagtail API router. And I'm just going to move those up so that they are in alphabetical order. Save that and you will notice that your application does absolutely nothing. The reason for that is just because we have a file in here does not mean it's actually being used.
Our next step is to go into our URLs. py and enable this So I am going to just add from dot dot API import, API, router, and then in our URL patterns, all I have to do is add one pattern There is one caveat to this though. That pattern has to be above this line where it says include Wagtail URLs. It has to go before this. Let's add an entry here. So we're going to add URL regex. It's going to start with API slash v2 It's not going to end with anything, and we're going to give it our API router. urls.
Put a comma after that. And so these two just match here. That's all I'm doing. Now when I save and open up my terminal, no module named Wagtail Images V2. Yep, that's pretty common. It's Wagtail Images da da da da da da da Right there and right there, it's. api. And that one is dot api. Alrighty. So just a correction there when we import is from Wagtail. images. api. v2. And our terminal shows us that everything is working as expected. So you go back to your website and you refresh and you notice that still nothing has changed. But if we were to go to
Uh the URL that we just typed, where are we here? Go to URLs. py, and if we open up slash API slash v2, you are going to notice Let's go slash API slash v2. You're going to notice that when I hit enter, this does not work. What's the deal with that? Now the reason that that doesn't work is because there's nothing here. It's not going to list every single thing on your website. That's a lot of data to to expose. Instead, we break this down into pages, images, and documents. So when I go to localhost port 8000 slash API slash v2 slash pages, I'm going to get a list view of all of my pages. Now if you're wondering where did I get slash api slash v2 slash pages from? Great question. So I got the API slash v2 from here.
That's in my URLs. py. And in my API. py, pages comes from here. So if we wanted to change this to just P, short for pages, we could do that. or pages v2 or page endpoint. We could call it whatever we want and that will change it in the URL for us Now we're not going to do that because currently this is basically everything that the documentation already covers. And so if you're looking at this and you're comparing it to the docs, this will make a lot more sense if I keep it the same as what's in the documentation. So let's head on over to API V2 slash pages. We see that we have all these pages in here. Maybe I can make this bigger. There we go. So we go to lowcost 8000 slash API slash V2
slash pages. That's a mouthful. But it gives us a lot of cool information. This is why we enabled the REST framework. application as well is because it gives us this nice little uh visual center to look at. So we can see that it's returning a JSON object. It gives us some metadata, total count, how many pages are there The items, it's a list of dictionaries. Uh so our first one has an ID of three. Uh it has metadata in there as well. What type is it? Is it it's a home page, it has a detail URL, so we could click that. we could go to the HTML URL, uh which we could use directly in our application. It gives us a slug, a first published ad, and a title. And the same thing happens with page number four, which is called about. And page number five, which is called blog. And so on and so on.
Now there are ways that we can customize this, we can show certain fields, we can hide certain fields, we can add Django Rest framework serializers to it. We're not going to cover all of that in this video because that is just a little too much to really go through but we can explore this a little bit so to get a detail page we can see that we have a detail URL in here and this is going to go to localhost slash API slash v2 slash pages slash three. So I'm just going to append a three in my URL. And this is going to show me my home page. And you can see that this is the URL that it's talking about. So now on this page we actually get a little bit more information. We'll get a search description, SEO title, show and menus, and a parent page. Well because this is the home page, there is no parent page. So that one is going to be no. Showing menus is false, so it's a Boolean, everything else looks like strings.
Lastly, we can go in here and we can say, hey, do we want this to spit out just JSON or just uh regular formatted API like what we're looking at? So let's. Changes view over to JSON and we can see that it's just raw JSON. Actually Mozilla made this pretty nice for me. Firefox made this quite nice for me. Instead of just gross JSON, it's uh it's quite nice And then we have options. We have different options that we can uh we can use in our application. We're not going to get into that either. And then just one more thing, uh, because if you are following along with this part, I mentioned that there is a pages endpoint, images endpoint, and a documents endpoint. So if we change this from API slash v2 slash pages to images, we will see that we will get a list of images.
So we've got an original Facebook image. We've got an image called Business Chairs Company 7070. Another Pexels photo, because that's where I get all my stock photos from is Pexels. com. It gives us the image ID, it gives us a detail URL if we needed more details. Uh it gives us any tags that are associated with it. Are there any tags on these? No, I've been terrible at content entry. I've not been adding tags. Uh gives us a type. So are you using a Wagtail image class? Are you using your own custom class? It will give you that and it'll give you a download URL. And again, if you wanted the detailed view, you could simply type in the ID that you find in here. So if you go into your website slash API slash v2 slash images, again that's a mouthful, and append the number one to your URL.
You will see it brings you to your detail view for your image. And this also gives you a width and a height. And you can do the exact same thing with documents. However, I don't think I have any documents. Nope, I don't have any documents, so this returns an empty list of items. So that's all there really is to enabling your Wagtail V2 API. Everything you need already comes with Wagtail, which is really, really nice. And this does not change anything on your backend where your admin is, none of this stuff is going to change. So this still all works as normal. Your whole website actually, in fact, works as normal. So you didn't actually break anything. So our website still looks like our somewhat boring and ugly website, but you notice that it still works.
The only thing we did was we said, oh, okay, on top of everything, we just want our API to spit out some JSON for us so that we can consume it using React or View or something like that. Okay, so I am back on the pages list view, and all I'm going to do is inspect my element, and we're going to do a little JavaScript test in here. So I'm gonna open up my console. Can I make that bigger? Yep. Alright, so this is gonna be tricky because this is at the bottom of my page. So I'm just going to type some JavaScript into my browser's console And all I'm going to do is use the JavaScript fetch API to make sure that this is actually returning what I'm expecting it to return. So I'm going to type fetch.
I'm going to grab this entire URL from up here. And apparently, due to security, I am not allowed to paste that. Okay, interesting. HTTP, HTTP, I'll dig this the long way then. Localhost port 8000. Slash API slash V2 slash pages. And then whoops. Let's do it then. The result is going to be result. json, so let's JSONify our response. And then let's take that response, response. And let's console log it. Console logresponse. And assuming I have typed everything correctly in here, we are going to see a JSON response in the form of a JavaScript object.
So in our object here, we have items. We've got eight in here. Does that match this? Meta. Yep, there's eight in there. There's eight items in here. Uh we have eight objects. We have IDs, we got meta, we got title, we have everything that we saw in our API. In this page, everything that we saw is now accessible in JavaScript. So voila, just like that, you have now enabled your Wagtail V2 API and you are ready to get started. with single page applications and other really cool types of websites that run off of a headless CMS. Alright, so in the next lesson, uh we're going to cover how to enable custom model fields to show up in our Wagtail API because If you notice, if we go to pages
three, we actually don't have all the data. If we open up Home models. py, we have banner title, subtitle, image, banner CTA. We even have a stream field in here And none of that shows up in here, strangely, so in the next lesson I'm going to show you how in just a couple of lines of code you can make sure that all of your content shows up in here. And then later down the road, we're going to talk about customizing what is output by our API and how to customize what is output so that you don't get all the information because sometimes Sometimes you don't care about the first published date or the SEO title or the type. And sometimes you just need to know a title, a slug, and maybe a description, possibly an image. So we're going to cover all sorts of headless CMS stuff
in the coming lessons. Alright, for now that is all there is to know. We just had to get this installed. So uh in the next few lessons we're going to cover a lot more, but this lesson was just getting Our Wagtail V2 API enabled and working. You can always reference everything that I've talked about in this video in the Wagtail docs at docs. wagtail. io. My name is Caleb Tallin. I am the voice behind the video. You can find more videos like this on learnwagtail. com And lastly, if you found this video was helpful, don't forget you can share, you can subscribe, or you can leave a comment. I love hearing comments from everybody. And if you're interested in subscribing, simply hit that button in the bottom right.
Or if you want to see more videos from this YouTube playlist, click the image in the top right. Thanks for joining me, and I will see you in the next video. Where we learn more about headless CMS
In the Wagtail 2.4 version shown, the v2 API is read-only. Future releases might support writing, but this talk only demonstrates retrieving data.
Discussed at 0:47Add `wagtail.api.v2` and Django REST Framework, create an `api.py` with a `WagtailAPIRouter`, register the pages, images, and documents endpoints, and include the router at `/api/v2/` in `urls.py` before the Wagtail URL include.
Discussed at 2:22The root API URL does not list all site data. You must request a registered endpoint such as `/api/v2/pages`, `/api/v2/images`, or `/api/v2/documents`.
Discussed at 8:36The pages endpoint returns JSON containing metadata such as the total count and an items list. Each page can include its ID, type, detail URL, HTML URL, slug, publication date, title, and additional fields on its detail endpoint.
Discussed at 10:07Use the browser’s JavaScript `fetch` API to request an endpoint such as `/api/v2/pages`, parse the response with `.json()`, and then use the resulting object in JavaScript.
Discussed at 14:00Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published September 19, 2026
Published July 9, 2026
Published May 20, 2026
Published April 16, 2026
Published April 1, 2026
Published March 10, 2026