SEO flywheel: /today digest, sitemap, robots, home OG tags

Make the summary pages discoverable so traffic compounds passively:
- /today: a server-rendered, shareable + indexable digest of today's brief —
  each item's title (→ /a summary), our summary, and a source link. OG/Twitter
  meta + self-canonical.
- /sitemap.xml: dynamic — home, /today, and every accepted non-duplicate /a page
  with lastmod. robots.txt allows all and points to it.
- Home (SPA shell) gains canonical + OG/Twitter tags for cleaner unfurls.
- Caddy routes /today + /sitemap.xml to the API. 133 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-05 19:37:05 +00:00
parent 427210ac3e
commit ea58039fb9
5 changed files with 176 additions and 0 deletions
+34
View File
@@ -800,6 +800,40 @@ def create_app() -> FastAPI:
_kick_summary(article_id, background_tasks)
return {"status": "pending", "summary": None}
@app.get("/today", response_class=HTMLResponse)
def today_digest() -> HTMLResponse:
with get_conn() as conn:
b = queries.brief(conn)
items = b.get("items") or []
if not items:
return HTMLResponse(share.render_not_found(PUBLIC_BASE_URL), status_code=404)
return HTMLResponse(share.render_digest(items, PUBLIC_BASE_URL, b.get("brief_date")))
@app.get("/sitemap.xml")
def sitemap() -> Response:
with get_conn() as conn:
rows = conn.execute(
"SELECT a.id, COALESCE(a.published_at, a.discovered_at) AS lm "
"FROM articles a JOIN article_scores s ON s.article_id = a.id "
"WHERE s.accepted = 1 AND a.duplicate_of IS NULL "
"ORDER BY lm DESC LIMIT 5000"
).fetchall()
base = PUBLIC_BASE_URL
urls = [
f"<url><loc>{base}/</loc><changefreq>hourly</changefreq><priority>1.0</priority></url>",
f"<url><loc>{base}/today</loc><changefreq>daily</changefreq><priority>0.9</priority></url>",
]
for r in rows:
lm = (r["lm"] or "")[:10]
lastmod = f"<lastmod>{lm}</lastmod>" if lm else ""
urls.append(f"<url><loc>{base}/a/{r['id']}</loc>{lastmod}</url>")
xml = (
'<?xml version="1.0" encoding="UTF-8"?>'
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
+ "".join(urls) + "</urlset>"
)
return Response(content=xml, media_type="application/xml")
@app.post("/api/import")
def import_local(body: ImportBody, request: Request) -> dict:
"""Fold this device's anonymous history/saved into the account (one-time)."""