Guide: Open Graph and social images¶
Every page that has a title, meta_description, and canonical_url already
produces functional Open Graph and Twitter card tags automatically. The basics
need no extra configuration.
What gets emitted automatically¶
When the resolver finalises metadata, it fills gaps in the og and twitter
dicts from the resolved page-level fields:
| Tag | Automatic source |
|---|---|
og:title |
title (unless og:title already set) |
og:description |
meta_description (unless og:description already set) |
og:url |
canonical_url (unless og:url already set) |
og:image |
og_image (unless og:image already set) |
twitter:title |
og:title |
twitter:description |
og:description |
twitter:image |
og:image |
twitter:card |
"summary_large_image" if an image is present, else "summary" |
The og:type default of "website" comes from SEO_SUITE["DEFAULTS"]["og"].
Adding a social sharing image¶
The simplest way is to map your image field:
class Article(SeoModelMixin, models.Model):
cover = models.ImageField(upload_to="covers/", blank=True)
SEO_FIELD_MAP = {"og_image": "cover"}
Or, if your field follows one of the conventional names (image,
cover_image, photo, thumbnail, og_image), no mapping is needed at all.
Once og_image is set, both og:image and twitter:image are populated
automatically, and twitter:card becomes "summary_large_image".
Setting og:type per model¶
The default og:type is "website". For articles and blog posts you
typically want "article". Override it via the og dict:
class Article(SeoModelMixin, models.Model):
...
def get_seo_metadata(self, context=None):
from seo_suite.metadata import SeoMetadata
base = super().get_seo_metadata(context)
og_override = SeoMetadata.partial(og={"type": "article"})
return SeoMetadata.merge(base, og_override)
Or, more concisely, at the view level:
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
def get_seo_metadata(self, context=None):
from seo_suite.metadata import SeoMetadata
return SeoMetadata.partial(og={"type": "article"})
Custom og: and twitter: tags¶
Supply any Open Graph or Twitter tag as a key in the respective dict. Keys are
the part after og: or twitter::
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
def get_seo_metadata(self, context=None):
from seo_suite.metadata import SeoMetadata
return SeoMetadata.partial(
og={
"type": "article",
"site_name": "My Blog",
"locale": "en_US",
},
twitter={
"site": "@myblog",
"creator": "@author",
},
)
The og and twitter dicts are deep-merged across layers (see
How resolution works): a higher-priority layer's
keys win key-by-key; neither dict is replaced wholesale.
Site-wide og:site_name¶
The og:site_name tag is commonly set once for the whole site. Add it to the
global defaults:
SEO_SUITE = {
"DEFAULTS": {
"title_suffix": " | My Blog",
"robots": "index,follow",
"og": {
"type": "website",
"site_name": "My Blog",
},
},
}
All pages inherit og:site_name from this default; any higher-priority layer
can still override og:type per-page without affecting og:site_name.
Suppressing og or twitter tags on specific pages¶
Set a key to None or "" to suppress it from a specific page. Because
og and twitter dicts are deep-merged, you can suppress one key without
clearing the rest:
class InternalToolView(SeoViewMixin, TemplateView):
def get_seo_metadata(self, context=None):
from seo_suite.metadata import SeoMetadata
return SeoMetadata.partial(og={"image": None}) # suppress og:image only
Rendered HTML output¶
For an article page with a cover image, the rendered output looks like:
<meta property="og:type" content="article">
<meta property="og:site_name" content="My Blog">
<meta property="og:title" content="How Django Routing Works">
<meta property="og:description" content="A deep dive into URL resolvers.">
<meta property="og:url" content="https://example.com/articles/how-django-routing-works/">
<meta property="og:image" content="https://example.com/media/covers/routing.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="How Django Routing Works">
<meta name="twitter:description" content="A deep dive into URL resolvers.">
<meta name="twitter:image" content="https://example.com/media/covers/routing.jpg">