# SDK Sitemap (/docs/sdk-sitemap)



Adding blog article URLs to your sitemap helps search engines discover and index your content. The EarlySEO SDK provides built-in sitemap helpers for every supported framework.

Next.js [#nextjs]

Automatic setup (CLI) [#automatic-setup-cli]

If you ran `npx @earlyseo/blog init`, a sitemap file was already created at `app/blog/sitemap.ts` (serves `/blog/sitemap.xml`). The base URL is auto-detected from the request Host header, so no extra configuration is needed. You can optionally set `NEXT_PUBLIC_BASE_URL` in `.env.local` if you want to hard-code it.

Manual setup [#manual-setup]

The SDK exports two helpers:

* `getBlogSitemapEntries()` — returns an array of sitemap entries to merge with your own
* `createBlogSitemap()` — returns a standalone sitemap function

Standalone blog sitemap (recommended) [#standalone-blog-sitemap-recommended]

Create a dedicated sitemap just for blog articles at `/blog/sitemap.xml`. This won't conflict with your main `app/sitemap.ts`:

```tsx
// app/blog/sitemap.ts  →  /blog/sitemap.xml
import { createBlogSitemap } from "@earlyseo/blog/next";

const siteId = process.env.EARLYSEO_SITE_ID!;

// baseUrl is auto-detected from NEXT_PUBLIC_BASE_URL or the request Host header
export default createBlogSitemap({ siteId });
```

Merge into an existing sitemap [#merge-into-an-existing-sitemap]

If you already have `app/sitemap.ts`, add blog entries to it:

```tsx
import { getBlogSitemapEntries } from "@earlyseo/blog/next";
import type { MetadataRoute } from "next";

const siteId = process.env.EARLYSEO_SITE_ID!;

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  // baseUrl auto-detected from NEXT_PUBLIC_BASE_URL or Host header
  const blogEntries = await getBlogSitemapEntries({ siteId });

  return [
    { url: "https://example.com", lastModified: new Date() },
    // your other pages…
    ...blogEntries,
  ];
}
```

Standalone blog sitemap [#standalone-blog-sitemap]

If you want a dedicated sitemap just for blog articles:

```tsx
// app/blog/sitemap.ts  →  /blog/sitemap.xml
import { createBlogSitemap } from "@earlyseo/blog/next";

const siteId = process.env.EARLYSEO_SITE_ID!;

export default createBlogSitemap({ siteId });
```

Options [#options]

| Option            | Type          | Default       | Description                                                                           |
| ----------------- | ------------- | ------------- | ------------------------------------------------------------------------------------- |
| `siteId`          | `string`      | —             | Your EarlySEO Site ID (required)                                                      |
| `baseUrl`         | `string`      | auto-detected | Your site's public URL. Falls back to `NEXT_PUBLIC_BASE_URL` then request Host header |
| `basePath`        | `string`      | `/blog`       | Blog route prefix                                                                     |
| `changeFrequency` | `string`      | `weekly`      | Sitemap change frequency hint                                                         |
| `priority`        | `number`      | `0.7`         | Sitemap priority for article pages                                                    |
| `fetchInit`       | `RequestInit` | —             | Additional fetch options (e.g. `{ next: { revalidate: 3600 } }`)                      |

Environment variables [#environment-variables]

Add to `.env.local`:

```bash
EARLYSEO_SITE_ID=your-site-id
# Optional: baseUrl is auto-detected from the Host header if not set
NEXT_PUBLIC_BASE_URL=https://example.com
```

***

Django [#django]

The SDK provides an `EarlySeoBlogSitemap` class that plugs into Django's built-in [sitemaps framework](https://docs.djangoproject.com/en/stable/ref/contrib/sitemaps/).

1. Add django.contrib.sitemaps to INSTALLED_APPS [#1-add-djangocontribsitemaps-to-installed_apps]

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

2. Register the sitemap in URLs [#2-register-the-sitemap-in-urls]

```python
# urls.py
from django.contrib.sitemaps.views import sitemap
from earlyseo_blog.django.sitemap import EarlySeoBlogSitemap

sitemaps = {
    "blog": EarlySeoBlogSitemap,
}

urlpatterns = [
    path("blog/", include("earlyseo_blog.django.urls")),
    path("sitemap.xml", sitemap, {"sitemaps": sitemaps}, name="sitemap"),
]
```

That's it. Django will serve blog article URLs at `/sitemap.xml`.

Configuration [#configuration]

| Setting                 | Default                      | Description                             |
| ----------------------- | ---------------------------- | --------------------------------------- |
| `EARLYSEO_SITE_ID`      | —                            | Your site ID (required)                 |
| `EARLYSEO_BLOG_PATH`    | `/blog`                      | Blog URL prefix used in sitemap `<loc>` |
| `EARLYSEO_CDN_BASE_URL` | `https://media.earlyseo.com` | Override CDN base URL                   |

Combining with other sitemaps [#combining-with-other-sitemaps]

Add your own sitemaps alongside the blog:

```python
from django.contrib.sitemaps import Sitemap
from earlyseo_blog.django.sitemap import EarlySeoBlogSitemap

class StaticSitemap(Sitemap):
    changefreq = "monthly"
    priority = 0.8

    def items(self):
        return ["home", "about", "contact"]

    def location(self, item):
        return f"/{item}/"

sitemaps = {
    "static": StaticSitemap,
    "blog": EarlySeoBlogSitemap,
}
```

***

Flask [#flask]

The SDK provides two ways to add a sitemap to your Flask app.

Option 1: Automatic route registration [#option-1-automatic-route-registration]

Register a `/blog/sitemap.xml` route with one call:

```python
from flask import Flask
from earlyseo_blog.flask.views import create_blog_blueprint
from earlyseo_blog.flask.sitemap import register_blog_sitemap

app = Flask(__name__)
app.config["EARLYSEO_SITE_ID"] = "your-site-id"
app.config["EARLYSEO_BASE_URL"] = "https://example.com"

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

Visit `/blog/sitemap.xml` to see the generated XML.

Option 2: Build your own sitemap [#option-2-build-your-own-sitemap]

Use `create_blog_sitemap_entries()` to get entry dicts and build a custom sitemap:

```python
from earlyseo_blog.flask.sitemap import create_blog_sitemap_entries

@app.route("/sitemap.xml")
def full_sitemap():
    blog_entries = create_blog_sitemap_entries(
        base_url="https://example.com",
        blog_path="/blog",
    )
    # Merge with your own entries and render XML
    all_entries = static_entries + blog_entries
    return render_sitemap_xml(all_entries)
```

Configuration [#configuration-1]

| Config Key              | Default                      | Description                                      |
| ----------------------- | ---------------------------- | ------------------------------------------------ |
| `EARLYSEO_SITE_ID`      | —                            | Your site ID (required)                          |
| `EARLYSEO_BASE_URL`     | `""`                         | Your site's public URL for absolute sitemap URLs |
| `EARLYSEO_CDN_BASE_URL` | `https://media.earlyseo.com` | Override CDN base URL                            |

***

How it works [#how-it-works]

The sitemap helpers:

1. Fetch your site manifest from the EarlySEO CDN
2. Iterate through all paginated article list pages
3. Collect every article slug and its creation date
4. Return properly formatted sitemap entries

No database queries, no API keys — just the same CDN that powers your blog pages.

***

Verify your sitemap [#verify-your-sitemap]

After setup:

1. Start your dev server
2. Visit your sitemap URL (e.g. `/sitemap.xml` or `/blog/sitemap.xml`)
3. Confirm blog article URLs appear in the XML
4. Use [Google Search Console](https://search.google.com/search-console) to submit your sitemap

***

Need help? [#need-help]

* [SDK Integration Setup](/docs/sdk)
* [SDK Troubleshooting](/docs/sdk-troubleshooting)
* Email [team@earlyseo.com](mailto:team@earlyseo.com)
