# Django SDK Guide (/docs/django-sdk)



Quick Start with CLI [#quick-start-with-cli]

The fastest way to add EarlySEO to your Django project:

```bash
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 [#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 [#installation]

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

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

***

Configuration [#configuration]

1. Add to INSTALLED_APPS [#1-add-to-installed_apps]

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

2. Set your Site ID [#2-set-your-site-id]

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

Or use an environment variable:

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

***

URL Configuration [#url-configuration]

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

```python
# 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:

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

***

Built-in Templates [#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 [#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 [#blog-list-template]

Create `templates/earlyseo/blog_list.html`:

```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 [#blog-detail-template]

Create `templates/earlyseo/blog_detail.html`:

```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 [#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 [#using-the-client-directly]

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

```python
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 [#how-publishing-works]

1. Write and publish an article in the EarlySEO dashboard
2. EarlySEO delivers your articles via a high-performance API
3. Your Django app fetches articles at request time via the `earlyseo-blog` package
4. Articles include SEO metadata automatically

***

Need Help? [#need-help]

* [Python SDK Overview](/docs/python-sdk)
* [Flask SDK Guide](/docs/flask-sdk)
* [SDK Sitemap Guide](/docs/sdk-sitemap)
* [SDK Integration Setup](/docs/sdk)
* [SDK Troubleshooting](/docs/sdk-troubleshooting)
* Email [team@earlyseo.com](mailto:team@earlyseo.com)
