feat(demo): a link preview card for the hosted demo - #178
Merged
Merged
Conversation
Pasting either link showed nothing: the app's own page had no Open Graph tags, and the Space's card had no thumbnail. - `scripts/social_card.html` is a 1200x630 card in the playground's own language -- mist paper, one verdigris accent, Schibsted Grotesk and Fragment Mono -- carried by the words, with a fragment of a plan turning into SQL underneath. `python scripts/render_social_card.py` renders it with headless Chrome into the two places that need it, and a test holds those two byte-identical. - The playground adds the Open Graph and Twitter tags to the built page's head as each request goes out (`preview.py`) rather than baking them in: a crawler runs no JavaScript, and `og:image` and `og:url` have to be absolute, so the host comes off the request -- the forwarded headers when a proxy set them, which is what the Space does. The card is served at `/social-card.png` and ships in the wheel. - The Space's front-matter gains `thumbnail`, read over raw GitHub so the card works before the Space has built.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pasting either link showed nothing today. The app's own page
(https://nadeem4nk-nl2sql-demo.hf.space) had no Open Graph tags, and the
Space's page had a
short_descriptionbut nothumbnail, so its card had noimage. This gives both a card.
The card
1200x630, in the playground's own language: mist paper, graphite ink, one
verdigris accent, Schibsted Grotesk and Fragment Mono, and the playground's own
mark. The words carry it -- the product name, the line "Ask a database in
plain English, the model plans, the code writes the SQL" at 52px over two
lines, and the quieter "Bring your own API key, Sample data, Open source".
Under a rule, one restrained cue: a fragment of the plan the model writes
turning into the SQL the code writes from it. No screenshot, nothing small
enough to disappear in a thumbnail.
It is generated, not drawn by hand into a binary:
scripts/social_card.htmlis the source, andpython scripts/render_social_card.pyinlines the playground's bundled fontsand shoots it with headless Chrome. The script writes the same 61 KB to both
places that need it --
docs/assets/social-card.png, which the Space'sthumbnailreads over raw GitHub, andpackages/nl2sql/src/nl2sql/cli/demo/playground/assets/social-card.png, whichthe app serves and the wheel carries -- and a test holds the two
byte-identical, so a regeneration cannot go out half-changed.
The app's tags
preview.pyadds them to the built page's<head>as each request goes out,rather than baking them into the bundle or having React set them:
sees;
og:imageandog:urlhave to be absolute, and no single absolute URL isright -- the same page is the Space, a container, and
http://127.0.0.1:8000.So the host comes off the request:
X-Forwarded-ProtoandX-Forwarded-Hostwhen a proxy set them, which is what the Space does; the
Hostheaderotherwise; and the URL the app itself saw if neither is a host, which also
means a forged header cannot write a URL into the page. Served over HTTP behind
the Space's headers:
The full set is
description,og:type,og:site_name,og:title,og:description,og:url,og:image,og:image:width,og:image:height,og:image:alt,twitter:card=summary_large_image,twitter:title,twitter:descriptionandtwitter:image. The page's old static<meta name="description">is gone fromweb/playground/index.html, so thereis exactly one and it says what the card says. The card is served at
GET /social-card.pngasimage/png.Checked, and not checked
pytest -m "not integration" -q: 1589 passed, 5 skipped (1578 before;the 5 skips are
langchain_anthropicmissing locally). The hosted-mode teststhat prove no key reaches disk or logs stay green -- the route-enumeration
test in
test_playground_settings.pylists the new route, so the newresponse is checked for the key too.
npm testinweb/playground: 106 passed. The bundle was rebuilt fromsource with
npm ci && npm run build, never hand-edited.mkdocs build --strict: clean.TestClient:GET /returnstext/html; charset=utf-8with the tags in the head, the proxied requestreturns the
hf.spaceURLs above, andGET /social-card.pngreturnsimage/png, 62327 bytes, PNG magic intact.against a branch. Run X's validator or https://opengraph.dev against the
Space once this is deployed.
docs/deployment/hosted-demo.mdgains a The link preview section coveringboth cards, how the absolute URL is derived, and how to regenerate the image.