Installation

Requirements

  • Python 3.10 or later
  • Django 4.2 or newer

No other third-party packages are required.


Install the package

pip install django-seo-suite

Add to INSTALLED_APPS

Add "seo_suite" to INSTALLED_APPS. The optional contrib apps are listed below; include only the ones you need.

# settings.py

INSTALLED_APPS = [
    # ... your existing apps ...
    "seo_suite",

    # Optional: admin-editable SEO keyed by URL path
    # Adds one table, one migration, Django Admin integration.
    "seo_suite.contrib.seopath",

    # Optional: admin-editable SEO for third-party models via generic relation
    # Requires django.contrib.contenttypes (usually already present).
    "seo_suite.contrib.seoobject",
]

Run migrations:

python manage.py migrate

The core seo_suite app ships a single migration: the table behind the versioned robots.txt workflow. The optional contrib apps (seopath, seoobject) add their own tables when installed. The SEO metadata mixins are abstract, so they create tables only inside your own apps' migrations.

Optional: serve robots.txt

To use the versioned robots.txt workflow, include the package URLs in your root urlconf:

# urls.py
from django.urls import include, path

urlpatterns = [
    # ...
    path("", include("seo_suite.urls")),   # serves /robots.txt
]

See the robots.txt guide.


Add the context processor

The seo context processor makes the resolved metadata available as {{ seo }} in every template. It is the mechanism that lets {% seo_head %} work without any extra code in your views.

# settings.py

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.request",  # required
                # ... other context processors ...
                "seo_suite.context.seo",                       # add this
            ],
        },
    }
]

django.template.context_processors.request is required. It is almost always already present.

The seo variable is a SimpleLazyObject: metadata is resolved only when the template actually accesses it, so pages that do not use {% seo_head %} pay no cost.


Add the template tag to your base template

In the <head> section of your base template:

{% load seo_suite %}
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  {% seo_head %}
  <!-- your other head content -->
</head>

{% seo_head %} renders the full block: title, meta tags, canonical, hreflang alternates, Open Graph, Twitter cards, and JSON-LD. See Customising output if you need finer control.


Verify the installation

With no further configuration, every page will already emit sensible defaults (a robots meta tag and an og:type tag) from the built-in global defaults. Open your browser's DevTools and inspect <head>. You should see at minimum:

<meta name="robots" content="index,follow">
<meta property="og:type" content="website">

The Quickstart shows you how to add a title and description to a model in under five minutes.


Optional: django.contrib.sites

django-seo-suite works without django.contrib.sites. If the app is installed, the current site ID is detected automatically and can be used to serve different SEO defaults per site. See Site-wide defaults for details.