EarlySEO LogoEarlySEO Docs

Django SDK Guide

Add an EarlySEO blog to your Django project with the earlyseo-blog Python package. Full setup with views, URLs, templates, and template tags.

Open .mdx

Quick Start with CLI

The fastest way to add EarlySEO to your Django project:

pip install "earlyseo-blog[django]"
earlyseo-blog

The CLI will:

  1. Detect your Django project
  2. Ask for your Site ID (from Dashboard → Integrations → SDK)
  3. Add earlyseo_blog.django to your INSTALLED_APPS
  4. Generate starter templates and a .env file

Prefer manual setup? Follow the steps below.


Prerequisites

  • Python ≥ 3.9
  • Django ≥ 3.2
  • SDK integration enabled in EarlySEO (Dashboard → Integrations → SDK)
  • Site ID from the SDK integration card
  • At least one published article

Installation

pip install "earlyseo-blog[django]"

This installs the core package plus Django-specific extras (views, template tags, URL config).


Configuration

1. Add to INSTALLED_APPS

# settings.py
INSTALLED_APPS = [
    # …
    "earlyseo_blog.django",
]

2. Set your Site ID

# settings.py
EARLYSEO_SITE_ID = "your-site-id"

Or use an environment variable:

import os
EARLYSEO_SITE_ID = os.environ.get("EARLYSEO_SITE_ID", "")

3. Optional: Custom CDN URL

# settings.py (only if using a custom CDN)
EARLYSEO_CDN_BASE_URL = "https://media.earlyseo.com"  # default

URL Configuration

Include the EarlySEO URLs in your project's URL config:

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

urlpatterns = [
    # your other routes…
    path("blog/", include("earlyseo_blog.django.urls")),
]

This registers two routes:

URL PatternNameDescription
/blog/earlyseo_blog:blog_listPaginated article list (?page=N)
/blog/<slug>/earlyseo_blog:blog_detailSingle article view

You can change the prefix to any path:

path("articles/", include("earlyseo_blog.django.urls")),

Built-in Templates

The package ships with built-in HTML templates that render a clean blog layout out of the box. No template files are required to get started.


Custom Templates

To customize the look of your blog, override the built-in templates by creating your own in your project's templates/ directory.

Blog list template

Create templates/earlyseo/blog_list.html:

{% raw %}
{% extends "base.html" %}
{% load earlyseo %}

{% block extra_head %}
  {% earlyseo_styles %}
{% endblock %}

{% block content %}
  <h1>Blog</h1>

  {% for article in articles %}
    <article>
      {% if article.featured_image_url %}
        <img src="{{ article.featured_image_url }}" alt="{{ article.title }}" />
      {% endif %}
      <h2>
        <a href="{% url 'earlyseo_blog:blog_detail' slug=article.slug %}">
          {{ article.title }}
        </a>
      </h2>
      <p>{{ article.meta_description }}</p>
    </article>
  {% endfor %}

  <!-- Pagination -->
  <nav>
    {% if current_page > 1 %}
      <a href="?page={{ current_page|add:'-1' }}">← Previous</a>
    {% endif %}
    <span>Page {{ current_page }} of {{ total_pages }}</span>
    {% if current_page < total_pages %}
      <a href="?page={{ current_page|add:'1' }}">Next →</a>
    {% endif %}
  </nav>
{% endblock %}
{% endraw %}

Context variables available:

VariableTypeDescription
articleslistList of ArticleListItem objects
current_pageintCurrent page number
total_pagesintTotal number of pages
total_articlesintTotal article count
article_cssstrArticle-specific CSS
blog_cssstrBlog layout CSS

Blog detail template

Create templates/earlyseo/blog_detail.html:

{% raw %}
{% extends "base.html" %}
{% load earlyseo %}

{% block title %}{{ article.title }}{% endblock %}

{% block extra_head %}
  {% earlyseo_styles %}
  <meta name="description" content="{{ article.meta_description }}" />
{% endblock %}

{% block content %}
  {% earlyseo_article article %}
{% endblock %}
{% endraw %}

Context variables available:

VariableTypeDescription
articleArticleFull article object
content_htmlstrRendered HTML of the article body
article_cssstrArticle-specific CSS
blog_cssstrBlog layout CSS

Template Tags

Load the EarlySEO template tags with {% raw %}{% load earlyseo %}{% endraw %}.

TagDescription
{% raw %}{% earlyseo_styles %}{% endraw %}Outputs a <style> block with article + blog CSS
{% raw %}{% earlyseo_article_css %}{% endraw %}Outputs article CSS only
{% raw %}{% earlyseo_article article %}{% endraw %}Renders full article HTML (header, featured image, body)

Using the Client Directly

For advanced use cases (APIs, management commands, etc.), use the client directly:

from earlyseo_blog import EarlySeoClient
from django.conf import settings

client = EarlySeoClient(site_id=settings.EARLYSEO_SITE_ID)

# In a view
def api_articles(request):
    page = client.get_list_page(1)
    data = [{"title": a.title, "slug": a.slug} for a in page.articles]
    return JsonResponse({"articles": data})

How Publishing Works

  1. Write and publish an article in the EarlySEO dashboard
  2. EarlySEO writes JSON files to the global CDN
  3. Your Django app fetches JSON at request time via the earlyseo-blog package
  4. Articles include SEO metadata automatically

Need Help?

On this page