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.
Quick Start with CLI
The fastest way to add EarlySEO to your Django project:
pip install "earlyseo-blog[django]"
earlyseo-blogThe CLI will:
- Detect your Django project
- Ask for your Site ID (from Dashboard → Integrations → SDK)
- Add
earlyseo_blog.djangoto yourINSTALLED_APPS - Generate starter templates and a
.envfile
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" # defaultURL 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 Pattern | Name | Description |
|---|---|---|
/blog/ | earlyseo_blog:blog_list | Paginated article list (?page=N) |
/blog/<slug>/ | earlyseo_blog:blog_detail | Single 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:
| Variable | Type | Description |
|---|---|---|
articles | list | List of ArticleListItem objects |
current_page | int | Current page number |
total_pages | int | Total number of pages |
total_articles | int | Total article count |
article_css | str | Article-specific CSS |
blog_css | str | Blog 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:
| Variable | Type | Description |
|---|---|---|
article | Article | Full article object |
content_html | str | Rendered HTML of the article body |
article_css | str | Article-specific CSS |
blog_css | str | Blog layout CSS |
Template Tags
Load the EarlySEO template tags with {% raw %}{% load earlyseo %}{% endraw %}.
| Tag | Description |
|---|---|
{% 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
- Write and publish an article in the EarlySEO dashboard
- EarlySEO writes JSON files to the global CDN
- Your Django app fetches JSON at request time via the
earlyseo-blogpackage - Articles include SEO metadata automatically
Need Help?
Python SDK
Add an EarlySEO blog to your Django or Flask app with the earlyseo-blog Python package. Overview, installation, CLI scaffold, and standalone client.
Flask SDK Guide
Add an EarlySEO blog to your Flask application with the earlyseo-blog Python package. Blueprint setup, Jinja templates, and configuration.