Skip to main content

Framework-agnostic canonical URL normalization and SEO payload generation

Project description

seoslug

Canonical URL normalization + deterministic SEO payload generation for content platforms.

Python License DeepWiki


What is seoslug?

seoslug turns your content entities into production-ready SEO metadata, canonical URLs, Open Graph, Twitter Cards, and JSON-LD, deterministically. Same input always produces the same output, making your SEO layer testable, cacheable, and predictable.

One function call. Complete SEO coverage. No surprises.


Quick start

from seoslug import SEOConfig, URLPolicy, SEOEntity, build_seo_payload

config = SEOConfig(
    canonical_host="blog.example.com",
    public_base_url="https://blog.example.com",
    url_policy=URLPolicy(
        enforce_https=True,
        lowercase_paths=True,
        trailing_slash="never",
    ),
)

entity = SEOEntity(
    entity_type="post",
    slug="my-post",
    title="My Post",
    excerpt="Example excerpt",
)

payload = build_seo_payload(entity, "/posts/my-post", config)

That's it. payload contains everything you need: title, description, canonical, og, twitter, and schema_jsonld, ready to inject into your HTML.

Why deterministic?

Most SEO tools produce different output for the same input: random cache busters, timestamps, or dictionary key order changes. seoslug does none of that.

payload1 = build_seo_payload(entity, path, config)
payload2 = build_seo_payload(entity, path, config)
assert payload1 == payload2  # Always True

This seemingly small property unlocks powerful workflows. You can commit expected SEO output to Git and validate it in CI: if SEO changes, your build fails. The same URL always generates an identical payload, so you can cache forever without invalidation logic. Diffing staging against production instantly reveals configuration drift, and you can track how your SEO evolves right alongside your code.

What seoslug handles

URL normalization: HTTPS enforcement, trailing slash policy, lowercase paths, query parameter sorting. Optionally strips tracking parameters using detrack.

Open Graph and Twitter Cards: og:title, og:image, twitter:card, and everything else search engines and social platforms expect.

JSON-LD: Auto-generates schema.org schemas (Article, WebPage, VideoObject, CollectionPage, SearchResultsPage) based on your entity type. Map any entity type to any schema type via config. Override with custom JSON-LD when needed.

Robots directives: index/noindex and follow/nofollow based on entity status.

Configurable fallbacks: Define what happens when a field is missing. Title can fall back to meta_title, then entity.title, then "Untitled". Description falls back from meta_description to entity.excerpt to an auto-generated HTML body snippet. The HTML body is only parsed when no higher-precedence source is available.

Plugin hooks: Extend the payload with custom JSON-LD, inject organization schemas, or transform descriptions via the post_process hook system.

And everything is pure: no environment variables, no system clock, no random numbers, no external API calls.

Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seoslug-1.1.0.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

seoslug-1.1.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file seoslug-1.1.0.tar.gz.

File metadata

  • Download URL: seoslug-1.1.0.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for seoslug-1.1.0.tar.gz
Algorithm Hash digest
SHA256 ec73f4c20e5d777132f3ba0ac475470fcda09bdaeb4bc217e495fe7fc69f2b02
MD5 e39439256236a5305b1071260adc2334
BLAKE2b-256 6bc0566a4222daf885fbb2ca2e2b0b67cc627d1571ce8209697582592eb41fda

See more details on using hashes here.

File details

Details for the file seoslug-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: seoslug-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for seoslug-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 15289efc2ad6790e3bf5b8185e7ea64c6a4ff8ea0754945e113fd289d73d6fec
MD5 be09a149140953d240fd03ae9f312c7a
BLAKE2b-256 233aaeb6635e8ea4ea060bfe1d059711dbae19afbd45ba1cc86cd8bd88929751

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page