Skip to content

Commit eb1504f

Browse files
lesnik512claude
andauthored
Plan + record: docs-site og:image rollout (#24)
* docs: design docs-site og:image rollout Wire each of the 7 docs-site repos to emit og:image/twitter:image pointing at a self-hosted social card, via a MkDocs Material custom_dir + main.html override. Ships as 7 per-repo PRs; this bundle is the org-level record. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: implementation plan for docs-site og:image rollout Eight tasks: a pilot PR (modern-di), five more docs repos, the that-depends special case (existing docs/overrides), and finalizing the .github bundle. Shared override template + per-repo procedure in Global Constraints. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: finalize og:image rollout bundle summary All 7 docs repos shipped (one PR each): modern-di#248, that-depends#219, lite-bootstrap#141, httpware#86, faststream-redis-timers#54, faststream-outbox#120, semvertag#43. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: correct rollout motivation (one repo lacked site_url) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b41d4d9 commit eb1504f

2 files changed

Lines changed: 447 additions & 0 deletions

File tree

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
---
2+
summary: docs-site og:image shipped — all 7 docs repos serve a self-hosted social card via a Material override; one PR per repo.
3+
---
4+
5+
# Design: docs-site og:image rollout
6+
7+
## Summary
8+
9+
Make each of the seven `modern-python` docs sites emit a proper
10+
`og:image`/`twitter:image` pointing at its own social card, so link unfurls on
11+
GitHub/Slack/X/etc. show the branded card instead of nothing. Each docs repo
12+
self-hosts its card (`docs/assets/social-card.png`, copied from this repo's
13+
`brand/projects/<repo>/social-card.png`) and gains a small MkDocs Material
14+
template override that emits the Open Graph + Twitter meta. Shipped as **seven
15+
PRs**, one per docs repo. This planning bundle lives in `.github` (the org/brand
16+
home where the cards are generated); no code changes land in `.github`.
17+
18+
## Motivation
19+
20+
The cards shipped in `brand/projects/<repo>/social-card.png` (PR #23) but nothing
21+
consumes them yet — the docs sites have no `og:image`, so shared links are bare.
22+
Probing confirmed all 7 sites are live MkDocs Material on their subdomain, none
23+
use Material's `social` plugin (no auto-card to conflict with), and only
24+
`that-depends` has a `custom_dir` (`docs/overrides`). (At rollout, one repo —
25+
`faststream-redis-timers` — turned out to have no `site_url` in `mkdocs.yml`; its
26+
PR added it, since the override needs it.)
27+
28+
The 7 docs repos: `modern-di`, `that-depends`, `lite-bootstrap`, `httpware`,
29+
`faststream-redis-timers`, `faststream-outbox`, `semvertag`.
30+
31+
## Non-goals
32+
33+
- README logos — a separate, later spec (this is the og:image piece only).
34+
- Cards for non-docs repos — they have no docs site.
35+
- Auto-generating cards with Material's `social` plugin — we use the bespoke
36+
cards already generated in this repo.
37+
- Changing the card design or this repo's own og:image.
38+
39+
## Design
40+
41+
### 1. Per-repo change set (identical shape across all 7)
42+
43+
Each docs repo PR adds:
44+
45+
1. **`docs/assets/social-card.png`** — the repo's card, copied verbatim from
46+
`modern-python/.github`'s `brand/projects/<repo>/social-card.png` (current
47+
`main`).
48+
2. **`overrides/main.html`** — a Material override (template below). For
49+
`that-depends`, this goes in its existing `docs/overrides/` instead of a new
50+
`overrides/`.
51+
3. **`mkdocs.yml`** — add `theme.custom_dir: overrides` for the six repos that
52+
lack it. `that-depends` already sets `custom_dir: docs/overrides` — no change.
53+
54+
### 2. The override template
55+
56+
One file, identical for every repo (it reads values from `mkdocs.yml`, so nothing
57+
is hard-coded per repo):
58+
59+
```jinja
60+
{% extends "base.html" %}
61+
{% block extrahead %}
62+
{{ super() }}
63+
{% set base = config.site_url if config.site_url.endswith('/') else config.site_url ~ '/' %}
64+
{% set card = base ~ 'assets/social-card.png' %}
65+
{% set title = (page.title ~ ' · ' ~ config.site_name) if (page.title and not page.is_homepage) else config.site_name %}
66+
{% set description = page.meta.description if page.meta and page.meta.description else config.site_description %}
67+
<meta property="og:type" content="website">
68+
<meta property="og:site_name" content="{{ config.site_name }}">
69+
<meta property="og:title" content="{{ title }}">
70+
<meta property="og:description" content="{{ description }}">
71+
<meta property="og:url" content="{{ page.canonical_url }}">
72+
<meta property="og:image" content="{{ card }}">
73+
<meta property="og:image:type" content="image/png">
74+
<meta property="og:image:width" content="1280">
75+
<meta property="og:image:height" content="640">
76+
<meta name="twitter:card" content="summary_large_image">
77+
<meta name="twitter:title" content="{{ title }}">
78+
<meta name="twitter:description" content="{{ description }}">
79+
<meta name="twitter:image" content="{{ card }}">
80+
{% endblock %}
81+
```
82+
83+
**Trailing-slash guard is load-bearing:** these repos' `site_url` has no trailing
84+
slash (e.g. `https://modern-di.modern-python.org`), unlike this repo's
85+
(`https://modern-python.org/`); the `base` computation normalises it so the card
86+
URL is `https://<repo>.modern-python.org/assets/social-card.png`, never
87+
`…orgassets/…`.
88+
89+
It extends `base.html` and only appends to `extrahead` via `{{ super() }}`, so it
90+
adds meta without overriding anything Material already renders.
91+
92+
### 3. Asset sourcing
93+
94+
The card is copied from this `.github` checkout:
95+
`brand/projects/<repo>/social-card.png``<docs-repo>/docs/assets/social-card.png`.
96+
It is committed into the docs repo (self-hosted), so the docs site serves it
97+
same-origin and there is no cross-repo runtime dependency. If a card is later
98+
regenerated here, re-copy it into the repo (rare; noted as a maintenance step).
99+
100+
### 4. Execution: seven PRs
101+
102+
One PR per repo, done sequentially and verified before the next:
103+
clone → branch → add card + override (+ `custom_dir` where missing) → verify
104+
(below) → push → PR → watch CI. Branch name per repo: `docs-ogimage`.
105+
`that-depends` is the one special case (existing `docs/overrides/`,
106+
`custom_dir` already set).
107+
108+
## Operations
109+
110+
After each PR merges and the site redeploys, the card is live at
111+
`https://<repo>.modern-python.org/assets/social-card.png`. Optionally validate the
112+
unfurl with a debugger (e.g. opengraph.xyz) — manual, out of band.
113+
114+
## Out of scope
115+
116+
- README logos (separate spec).
117+
- Any change to this `.github` repo's site or to the card design.
118+
119+
## Testing
120+
121+
Per repo, before opening the PR:
122+
123+
- Build the docs the way the repo builds them (e.g. `uv run mkdocs build` or the
124+
repo's documented command). The build must succeed.
125+
- Assert the generated `site/index.html` contains
126+
`<meta property="og:image" content="https://<repo>.modern-python.org/assets/social-card.png">`
127+
and `site/assets/social-card.png` exists.
128+
- Spot-check one interior page's built HTML carries the same `og:image`.
129+
130+
## Risk
131+
132+
- **Docs build needs Material + plugins installed.** Cloning a repo and running
133+
`mkdocs build` may require its docs dependencies. Likelihood medium, impact
134+
low. *Mitigation:* install via the repo's own dev/docs extra
135+
(`uv sync`/`uv run`), or `uvx --with mkdocs-material[imaging] mkdocs build`; if
136+
a repo's plugin set is heavy and unavailable, fall back to verifying the
137+
override is valid Jinja and the card file is present, and rely on the repo's CI
138+
to build.
139+
- **`that-depends` already has a `main.html` in `docs/overrides/`.** Then it must
140+
be *merged* (append the `extrahead` block), not overwritten. *Mitigation:* the
141+
plan inspects `docs/overrides/` first and merges if a `main.html` exists.
142+
- **Per-repo `mkdocs.yml` drift.** A repo might key the theme differently.
143+
*Mitigation:* the plan reads each `mkdocs.yml` before editing; the override
144+
template itself is config-driven and unaffected.
145+
- **Card staleness.** The committed card can drift from a regenerated one in
146+
`.github`. Likelihood low (cards rarely change), impact low. *Mitigation:* the
147+
later README spec or a follow-up can document a re-copy step; out of scope here.

0 commit comments

Comments
 (0)