Make a page of your site a livecard, with your agent
Makes one page of a site a livecard, a page that runs inside a post on X: the player card tags, framing for X on that route only, what X’s crawler is really served, and an embed mode for scrolling, links and overlays, checked live with clickd.
Add it, from the top of the site’s repositorynpx skills add subinternal/clickd --skill clickd-livecards
Then ask your agentMake our /demo page run inside a post on X with a player card, and check what X’s crawler gets.
One route of your site gets the card tags and a framing rule that lets X and only X frame it17. Then your agent checks it the way X’s crawler is served, before anyone posts the link.
A route of its own, such as /in-post, never the home page: it gets headers and behavior the rest of the site must not have. The share address goes in the post; the player address is what X frames. They may be one.
Done whenThe route exists on its own, on https.
Two addresses
share https://example.com/in-post
player https://example.com/in-post
Plan the frame
X scales the frame to the timeline’s width, keeping the ratio you declare, so the page shows its narrow layout. One tool, one demo, one screen of a game. Where there is no frame, X’s apps show the picture, so it has to make sense on its own.
Done whenWhat fits in the frame is decided, and the picture reads alone.
On the share address, in the page’s head. Every address absolute https, a picture the frame’s size and over 68,600 pixels, and exactly one twitter:card: some frameworks print a second one from the Open Graph settings.
Done whenThe HTML the server sends has nine card tags and one twitter:card.
A response header on the player route only, and no X-Frame-Options. Every other route keeps refusing to be framed. In a meta tag it is ignored, and two policies on one response are both enforced.
Done whenThe live response carries one frame-ancestors rule naming X’s four hosts.
Turned on by the route, on the server. In it the page scrolls an inner element, opens every link in a new tab, hides chat widgets and sign-up prompts, and starts anything that plays muted.
Done whenThe page scrolls, links open in new tabs, and nothing covers it in a 560 by 420 frame.
Scrolling in the frame
html.framed, html.framed body { height: 100%; overflow: hidden; }
html.framed main { height: 100dvh; overflow-y: auto; overscroll-behavior: contain; }
Check what the crawler is served
Fetch the live route as X’s crawler, every time. A CDN, an edge worker or bot protection often answers social crawlers from a path of its own, and a local server never runs the edge.
Done whenThe crawler gets the player tags, and clickd’s card check passes.
Frame it on the site itself first, then post the link from a spare account and open it on x.com and in X’s apps. X’s validator now shows only a still picture even when it works: a real post is the test.
Done whenThe frame loads, scrolls and opens its links in new tabs inside a real post.
The edge in front of a site often answers social crawlers with another page’s card. The browser looks right; the post shows a plain picture.
example.com/in-post, fetched twice
The same address, the same minute.
Sample
Your browserMozilla/5.0
twitter:cardplayer
twitter:player/in-post
frame-ancestorsx.com and 3 more
X-Frame-OptionsNot sent
X’s crawlerTwitterbot/1.0
twitter:cardsummary_large_image
twitter:playerMissing
frame-ancestors'self'
X-Frame-OptionsDENY
Where it runs
X describes the player card for video, audio and media, and the skill says so.2 This is what to expect.
x.com in a desktop browserThe page, framed inside the postRuns in the post
X’s apps on a phoneThe picture, then the page in the app’s browser on a tapOpens on a tap
X’s card validatorAsks for a sign-in, and shows a still picture even when it worksNot a test
When to reach for it
Reach for it when
You want a demo, a tool or a game to be usable inside a post, without leaving the timeline.
A player card shows as a plain image, a blank frame, or a frame that will not scroll.
X’s crawler gets a different card from the one your browser sees.
Leave it when
You want a normal link preview with a large image: the share tags alone do that.
You want to embed a post on your own site, or post a video.
Install it by hand
The line at the top adds it for any agent. Or fetch its 5 files where your agent looks. Your agent also needs clickd connected over MCP: connecting an agent shows how.
Loads skills from .claude/skills/ in the repository, for everyone who works in it, or ~/.claude/skills/ for every project on your machine. Claude uses it when a request matches its description, or type /clickd-livecards.
Puts the files in .claude/skills/clickd-livecards/.
Loads skills from .agents/skills/ in the repository and its parent folders, or ~/.agents/skills/ for every project. Codex uses it when a task matches its description, or mention it as $clickd-livecards; /skills lists them.
Puts the files in .agents/skills/clickd-livecards/.
Loads skills from .cursor/skills/ or .agents/skills/ in the repository, or ~/.cursor/skills/ for every project. It also reads .claude/skills/, so one copy there serves both. The agent uses it when it is relevant, or type / in Agent chat and pick it.
Puts the files in .cursor/skills/clickd-livecards/.
An agent that does not load skills can still follow the file. Save the folder in the repository and point its standing instructions at it, with a line in AGENTS.md, which many agents read. The agent reads AGENTS.md when it starts, and follows the file when the task matches.
SKILL.md stays short and sends your agent to a reference when a step needs it.
SKILL.mdThe seven steps from picking the route to testing it in a post, the card tags, the framing headers, the crawler check, the embed mode, the card cache and the report.176 lines
references/card-tags.mdEvery card tag with X’s limits, the picture at the frame’s size and its 68,600 pixel floor, where a second twitter:card comes from, and the tags in plain HTML and in Next.js.134 lines
references/framing-headers.mdWhy the framing rule reads as it does, what breaks it, and the config for Next.js, Express with Helmet, Nginx, Cloudflare Pages, Vercel and Netlify, each with its trap.159 lines
references/embed-mode.mdWhere the page runs in each X client, turning the mode on by route, and scrolling, links, sign-in and cookies, overlays, media, https and weight, with a whole route as an example.131 lines
references/troubleshooting.mdX’s crawler and its address ranges, four commands that find a cause, each symptom with its fix, the card cache and the validator.65 lines
2Cards markup, X developer docs, archived.Every card tag, the title, description and alt lengths, the image formats and size, and the Open Graph fallback for each tag.
3Player Card, X developer docs, archived.The 68,600 pixel floor, how each client shows the card, and the validator's still picture.
4Troubleshooting Cards, X developer docs, archived.Twitterbot's user agent, its address ranges and AS, the two-way lookup, TLS, the size limits, `robots.txt`, a player address that must be a simple page, and the cache.