WagtailWagtail

How to Generate SEO Descriptions for Your Entire Wagtail Site at Once

Apr 01, 2026 · by Tim Kamanin

Recently, I've used Wagtail AI internals to mass-generate SEO descriptions for my blog posts. 150+ pages, done in minutes — way faster than clicking through the admin UI one page at a time.

Wagtail AI package provides you with a solid set of AI tools that help with text generation. Those tools are mainly to be used in the admin interface and provide content hints within rich-text editor, help generating image alt texts, title and search descriptions. But that's only on the surface.

Besides UI features, Wagtail AI abstracts away the traditional plumbing everyone has to sustain when working with LLM APIs: prompting, backends, requests, responses, and all that data massaging. And that's what I used to generate hundreds of search meta descriptions at once for my blog.

The entire LLM pipeline in Wagtail AI is just two function calls:

  • get_agent_settings() — returns the AgentSettings instance with the prompt template
  • get_llm_service() — returns a configured LLM client (reads from your WAGTAIL_AI["PROVIDERS"] setting)

When Wagtail AI generates search descriptions it:

  1. Loads the prompt template from AgentSettings (a Wagtail settings model)
  2. Injects page's actual content into the prompt template
  3. Sends it to the LLM via get_llm_service() and returns the response

And that's it!

Here's how to wrap it all in a Django management command that runs this pipeline for each post and saves generated description:

from django.core.management.base import BaseCommand

# These two imports are the key — they give us access to wagtail_ai's
# configured LLM client and prompt templates without needing the admin UI.
from wagtail_ai.agents.base import get_agent_settings, get_llm_service

from tow.posts.models import PostPage


class Command(BaseCommand):
    def handle(self, **options):
        # Load the AgentSettings model — this holds the prompt templates
        # configured in Wagtail admin under Settings → Agents.
        settings = get_agent_settings()

        # Get the prompt template for SEO descriptions. By default:
        # "Create an SEO-friendly meta description... {content_html}"
        prompt_template = settings.page_description_prompt

        # Get the LLM client configured in your WAGTAIL_AI["PROVIDERS"] setting.
        # This is cached — safe to call repeatedly without creating new connections.
        llm = get_llm_service()

        # Loop through every live PostPage.
        for page in PostPage.objects.live():
            # Render the StreamField body to HTML — str() on a StreamField
            # renders all blocks (rich text, images, code, etc.) to their HTML output.
            content_html = str(page.body)

            # Insert the page's HTML content into the prompt template,
            # replacing the {content_html} placeholder.
            formatted_prompt = prompt_template.format(content_html=content_html)

            # Send the prompt to the LLM as a single user message —
            # this is the same format wagtail_ai's BasicPromptAgent uses.
            result = llm.completion(
                messages=[
                    {
                        "role": "user",
                        "content": [{"type": "text", "text": formatted_prompt}],
                    }
                ]
            )

            # Extract the generated description from the LLM response
            # (OpenAI-style response object: choices[0].message.content).
            page.search_description = result.choices[0].message.content.strip()

            # Save as a new published revision — this updates the live page
            # and creates a revision entry in Wagtail's history.
            page.save_revision().publish()

            self.stdout.write(
                self.style.SUCCESS(
                    f'Generated "{page.search_description}" and saved it for "{page.title}"'
                )
            )

The command above is pretty barebones, but it should give you idea how the approach works.

Wagtail AI is very handy addition to Wagtail CMS and there's more hidden gems in it. I've only scratched the surface here. I encourage you to go and see yourself what's possible with Wagtail AI. If you want to integrate AI into your workflows, reach out. I'd be glad to assist.

Hey, if you've found this useful, please share the post to help other folks find it:

There's even more:

Subscribe for updates