EarlySEO LogoEarlySEO Docs

Flask SDK Guide

Add an EarlySEO blog to your Flask application with the earlyseo-blog Python package. Blueprint setup, Jinja templates, and configuration.

Open .mdx

Quick Start with CLI

The fastest way to add EarlySEO to your Flask project:

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

The CLI will:

  1. Detect your Flask project
  2. Ask for your Site ID (from Dashboard → Integrations → SDK)
  3. Generate starter templates and a .env file

Prefer manual setup? Follow the steps below.


Prerequisites

  • Python ≥ 3.9
  • Flask ≥ 2.0
  • 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[flask]"

This installs the core package plus Flask-specific extras (blueprint, Jinja helpers).


Blueprint Setup

Register the EarlySEO blog blueprint in your Flask app:

from flask import Flask
from earlyseo_blog.flask.views import create_blog_blueprint

app = Flask(__name__)
app.config["EARLYSEO_SITE_ID"] = "your-site-id"

blog_bp = create_blog_blueprint()
app.register_blueprint(blog_bp, url_prefix="/blog")

Or load the Site ID from an environment variable:

import os

app.config["EARLYSEO_SITE_ID"] = os.environ.get("EARLYSEO_SITE_ID", "")

Routes

The blueprint 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 when registering the blueprint:

app.register_blueprint(blog_bp, url_prefix="/articles")

Built-in Templates

The package ships with built-in HTML that renders a clean blog layout out of the box. No template files are required to get started — just register the blueprint and visit /blog/.


Custom Jinja Templates

To customize the look of your blog, create template files in your project's templates/earlyseo/ directory. Flask will use your templates instead of the built-in ones.

Blog list template

Create templates/earlyseo/blog_list.html:

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

{% block head %}
  <style>{{ article_css }}{{ blog_css }}</style>
{% 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_for('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 - 1 }}">← Previous</a>
    {% endif %}
    <span>Page {{ current_page }} of {{ total_pages }}</span>
    {% if current_page < total_pages %}
      <a href="?page={{ current_page + 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" %}

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

{% block head %}
  <style>{{ article_css }}{{ blog_css }}</style>
  <meta name="description" content="{{ article.meta_description }}" />
{% endblock %}

{% block content %}
  <article>
    <h1>{{ article.title }}</h1>
    {% if article.featured_image_url %}
      <img src="{{ article.featured_image_url }}" alt="{{ article.title }}" />
    {% endif %}
    {{ content_html | safe }}
  </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

Full App Example

A minimal Flask app with EarlySEO blog:

import os
from flask import Flask
from earlyseo_blog.flask.views import create_blog_blueprint

app = Flask(__name__)
app.config["EARLYSEO_SITE_ID"] = os.environ["EARLYSEO_SITE_ID"]

app.register_blueprint(create_blog_blueprint(), url_prefix="/blog")

@app.route("/")
def home():
    return '<h1>My Site</h1><p><a href="/blog">Read the blog</a></p>'

if __name__ == "__main__":
    app.run(debug=True)

Run it:

export EARLYSEO_SITE_ID=your-site-id
python app.py

Visit http://localhost:5000/blog to see your articles.


Using the Client Directly

For API endpoints or custom logic, use the client directly:

from flask import jsonify
from earlyseo_blog import EarlySeoClient

@app.route("/api/articles")
def api_articles():
    client = EarlySeoClient(site_id=app.config["EARLYSEO_SITE_ID"])
    page = client.get_list_page(1)
    return jsonify({
        "articles": [{"title": a.title, "slug": a.slug} for a in page.articles]
    })

Async client (with Quart or async Flask)

from earlyseo_blog import AsyncEarlySeoClient

async with AsyncEarlySeoClient(site_id="your-site-id") as client:
    page = await client.get_list_page(1)

Install the async extra:

pip install "earlyseo-blog[async]"

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 Flask app fetches articles at request time via the earlyseo-blog package
  4. Articles include SEO metadata automatically

Need Help?

On this page