SEO
Implemented UtilitiesServer-rendered page metadata: title, description, canonical, Open Graph, language alternatives and safe JSON-LD.
A wdj composition built from the existing component library.
Presentation commands show demo feedback. Read the interaction guide to connect real actions.
Page metadata
One head include, with explicit page-specific values.
Include once inside the document head. Pass a page-specific metadata dictionary from Django; the component validates absolute URLs and escapes text and JSON-LD.
# views.py
seo = {
"title": "Products | Example",
"description": "Browse our available products.",
"canonical_url": "https://example.com/products/",
"site_name": "Example",
}
# Inside base.html <head>, replacing existing metadata:
{% include "wdj/components/seo.html" with seo=seo only %}
{% include "wdj/htmx_config.html" only %}
Optional keys: robots, type, locale, image, image_alt, alternates and json_ld. The example above is escaped; it does not insert a second title or canonical into this page.
Show template
{% load wdj %}
<div class="grid gap-3">
<p class="text-base text-kumo-subtle">Include once inside the document head. Pass a page-specific metadata dictionary from Django; the component validates absolute URLs and escapes text and JSON-LD.</p>
<pre tabindex="0" class="overflow-x-auto rounded-lg bg-kumo-elevated p-4 font-mono text-base"><code>{% verbatim %}# views.py
seo = {
"title": "Products | Example",
"description": "Browse our available products.",
"canonical_url": "https://example.com/products/",
"site_name": "Example",
}
# Inside base.html <head>, replacing existing metadata:
{% include "wdj/components/seo.html" with seo=seo only %}
{% include "wdj/htmx_config.html" only %}{% endverbatim %}</code></pre>
<p class="text-base text-kumo-subtle">Optional keys: <code>robots</code>, <code>type</code>, <code>locale</code>, <code>image</code>, <code>image_alt</code>, <code>alternates</code> and <code>json_ld</code>. The example above is escaped; it does not insert a second title or canonical into this page.</p>
<a href="/guide/#seo" class="text-base text-kumo-link hover:underline">SEO and HTMX integration checklist</a>
</div>
Language and structured data
Reciprocal translations and schema matching the visible page.
Pass Python dictionaries, not JSON strings. Add only language versions and content that exist on the consuming site.
seo["alternates"] = [
{"lang": "en", "url": "https://example.com/en/products/"},
{"lang": "fr", "url": "https://example.com/fr/products/"},
]
seo["json_ld"] = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{"@type": "ListItem", "position": 1,
"name": "Home", "item": "https://example.com/"},
{"@type": "ListItem", "position": 2,
"name": "Products", "item": "https://example.com/products/"},
],
}
Each translation must link back to the others and use its own canonical URL. For a private page, set seo["robots"] = "noindex, nofollow"; access control remains the application's responsibility.
Show template
{% load wdj %}
<div class="grid gap-3">
<p class="text-base text-kumo-subtle">Pass Python dictionaries, not JSON strings. Add only language versions and content that exist on the consuming site.</p>
<pre tabindex="0" class="overflow-x-auto rounded-lg bg-kumo-elevated p-4 font-mono text-base"><code>seo["alternates"] = [
{"lang": "en", "url": "https://example.com/en/products/"},
{"lang": "fr", "url": "https://example.com/fr/products/"},
]
seo["json_ld"] = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{"@type": "ListItem", "position": 1,
"name": "Home", "item": "https://example.com/"},
{"@type": "ListItem", "position": 2,
"name": "Products", "item": "https://example.com/products/"},
],
}</code></pre>
<p class="text-base text-kumo-subtle">Each translation must link back to the others and use its own canonical URL. For a private page, set <code>seo["robots"] = "noindex, nofollow"</code>; access control remains the application's responsibility.</p>
</div>
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| seo | dict | {} | Page metadata: title, description, canonical_url, robots, site_name, type, locale, image, image_alt, alternates [{lang, url}] and json_ld (dict/list). Include once in head; see docs/SEO.md. |