Skip to content

Open Graph link previews for shared articles#639

Merged
mircealungu merged 1 commit into
masterfrom
article-link-previews
May 27, 2026
Merged

Open Graph link previews for shared articles#639
mircealungu merged 1 commit into
masterfrom
article-link-previews

Conversation

@mircealungu
Copy link
Copy Markdown
Member

What

Extends the shared-lesson link previews (#637/#638) to articles shared as zeeguu.org/read/article?id=N. Two new public, no-auth endpoints in article.py:

  • GET /shared_article_preview/<id> — server-rendered OG/Twitter HTML (title, description, image, canonical → the app page, meta-refresh fallback).
  • GET /shared_article_image/<id>.png — a 1200×630 card.

The card

Unlike audio lessons (no inherent image → branded card), articles reliably have a hero image, so the card features the article's own photo full-bleed under a bottom scrim, with white title + a <Language> Article pill + CEFR · N min read · Source. When an article has no image, it falls back to the branded cream card (the article sibling of the audio card). og_image.render_article_card does both.

Data comes from article.article_info() (title, language, img_url, word_count→min read, cefr_level) + article.feed.title for the source. CEFR is shown here (a single level is a key "is this for me?" filter for articles — distinct from the misleading level-transitions we avoid elsewhere).

Robustness: a transient image-fetch failure serves the fallback without caching it (short TTL), so the photo card appears once the fetch succeeds; otherwise cards are rendered once and cached on disk per article id.

Out of scope / deploy

  • nginx routing for /read/article is staged separately in the ops repo (location = /read/article → crawler UAs proxied to /shared_article_preview/$arg_id).
  • After deploy: nothing to clear (new cache dir og-images/shared-articles/).

Verified by rendering the photo card and the no-photo fallback via the real render_article_card; endpoints compile; .png route + requests confirmed. Not run end-to-end locally (DB drift) — smoke-test on deploy.

🤖 Generated with Claude Code

Mirrors the audio-lesson previews (#637/#638) for articles shared as
zeeguu.org/read/article?id=N. New public, no-auth endpoints in article.py:
- GET /shared_article_preview/<id>  → server-rendered OG/Twitter HTML
- GET /shared_article_image/<id>.png → a 1200x630 card

The card features the article's own photo full-bleed under a scrim, with the
title, source, reading time (word_count/200), and CEFR level — falling back to
the branded cream card when an article has no image (rendered by
og_image.render_article_card). A transient image-fetch failure serves the
fallback without caching it, so the photo card appears once the fetch succeeds.

nginx routing for /read/article is staged separately in the ops repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

ArchLens detected architectural changes in the following views:
diff

@mircealungu mircealungu merged commit 74e5a89 into master May 27, 2026
3 checks passed
@mircealungu mircealungu deleted the article-link-previews branch May 27, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant