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.

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.0.2.tar.gz (15.2 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.0.2-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for seoslug-1.0.2.tar.gz
Algorithm Hash digest
SHA256 c3736cbde865bc3a2495bf60480e4f9ffd702f4d4cae133ac024165179d02c06
MD5 1e3e9eccc1d949f3a380704bb841cbb1
BLAKE2b-256 a77cff74a548e26624ee0e4ea87ef984a51b6e94a186144dc22ce4b56a3dc4b2

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for seoslug-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 24d1afd49ec072061eb462618680991feb5ec8d2391a5776b374f27d00edea1d
MD5 308654510a71f4ea10a04b839a91576a
BLAKE2b-256 1f1ee2279fd07f41e1e85121ce8276b60861479e186e77ac0e788bbd4e02ab5e

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