Skills/Livecardsv2.1.0

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.

For a site’s developer who wants one page to work inside a postTest a livecardBuild one on clickd

Seven steps, in order

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.

  1. 1Pick the route
  2. 2Plan the frame
  3. 3Write the card tags
  4. 4Let X frame that route, and only that route
  5. 5Give the page an embed mode
  6. 6Check what the crawler is served
  7. 7Test it in a frame, then in a post

Pick the route

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.
The size it declares
twitter:player:width   640
twitter:player:height  480

Write the card tags

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.
In the head of /in-post
<meta name="twitter:card" content="player">
<meta name="twitter:site" content="@youraccount">
<meta name="twitter:title" content="A short title">
<meta name="twitter:description" content="One sentence.">
<meta name="twitter:image" content="https://example.com/in-post.png">
<meta name="twitter:image:alt" content="What the picture shows.">
<meta name="twitter:player" content="https://example.com/in-post">
<meta name="twitter:player:width" content="640">
<meta name="twitter:player:height" content="480">

Let X frame that route, and only that route

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.
On /in-post only
Content-Security-Policy: frame-ancestors 'self'
  https://x.com https://*.x.com
  https://twitter.com https://*.twitter.com

Give the page an embed mode

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.
Terminal
curl -s -A "Twitterbot/1.0" https://example.com/in-post \
  | grep -o '<meta name="twitter:[^>]*>'

Test it in a frame, then in a post

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.
A test page on the same site
<iframe scrolling="no" src="/in-post" width="560" height="420"></iframe>

Why step 6 is never skipped

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.

Terminal, for Claude Code
mkdir -p .claude/skills/clickd-livecards/references
curl -fsSL https://clickd.com/skills/livecards/SKILL.md -o .claude/skills/clickd-livecards/SKILL.md
curl -fsSL https://clickd.com/skills/livecards/references/card-tags.md -o .claude/skills/clickd-livecards/references/card-tags.md
curl -fsSL https://clickd.com/skills/livecards/references/framing-headers.md -o .claude/skills/clickd-livecards/references/framing-headers.md
curl -fsSL https://clickd.com/skills/livecards/references/embed-mode.md -o .claude/skills/clickd-livecards/references/embed-mode.md
curl -fsSL https://clickd.com/skills/livecards/references/troubleshooting.md -o .claude/skills/clickd-livecards/references/troubleshooting.md
PowerShell, for Claude Code
New-Item -ItemType Directory -Force .claude\skills\clickd-livecards\references | Out-Null
Invoke-WebRequest https://clickd.com/skills/livecards/SKILL.md -OutFile .claude\skills\clickd-livecards\SKILL.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/card-tags.md -OutFile .claude\skills\clickd-livecards\references\card-tags.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/framing-headers.md -OutFile .claude\skills\clickd-livecards\references\framing-headers.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/embed-mode.md -OutFile .claude\skills\clickd-livecards\references\embed-mode.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/troubleshooting.md -OutFile .claude\skills\clickd-livecards\references\troubleshooting.md -UseBasicParsing

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.

Terminal, for Codex
mkdir -p .agents/skills/clickd-livecards/references
curl -fsSL https://clickd.com/skills/livecards/SKILL.md -o .agents/skills/clickd-livecards/SKILL.md
curl -fsSL https://clickd.com/skills/livecards/references/card-tags.md -o .agents/skills/clickd-livecards/references/card-tags.md
curl -fsSL https://clickd.com/skills/livecards/references/framing-headers.md -o .agents/skills/clickd-livecards/references/framing-headers.md
curl -fsSL https://clickd.com/skills/livecards/references/embed-mode.md -o .agents/skills/clickd-livecards/references/embed-mode.md
curl -fsSL https://clickd.com/skills/livecards/references/troubleshooting.md -o .agents/skills/clickd-livecards/references/troubleshooting.md
PowerShell, for Codex
New-Item -ItemType Directory -Force .agents\skills\clickd-livecards\references | Out-Null
Invoke-WebRequest https://clickd.com/skills/livecards/SKILL.md -OutFile .agents\skills\clickd-livecards\SKILL.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/card-tags.md -OutFile .agents\skills\clickd-livecards\references\card-tags.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/framing-headers.md -OutFile .agents\skills\clickd-livecards\references\framing-headers.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/embed-mode.md -OutFile .agents\skills\clickd-livecards\references\embed-mode.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/troubleshooting.md -OutFile .agents\skills\clickd-livecards\references\troubleshooting.md -UseBasicParsing

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.

Terminal, for Cursor
mkdir -p .cursor/skills/clickd-livecards/references
curl -fsSL https://clickd.com/skills/livecards/SKILL.md -o .cursor/skills/clickd-livecards/SKILL.md
curl -fsSL https://clickd.com/skills/livecards/references/card-tags.md -o .cursor/skills/clickd-livecards/references/card-tags.md
curl -fsSL https://clickd.com/skills/livecards/references/framing-headers.md -o .cursor/skills/clickd-livecards/references/framing-headers.md
curl -fsSL https://clickd.com/skills/livecards/references/embed-mode.md -o .cursor/skills/clickd-livecards/references/embed-mode.md
curl -fsSL https://clickd.com/skills/livecards/references/troubleshooting.md -o .cursor/skills/clickd-livecards/references/troubleshooting.md
PowerShell, for Cursor
New-Item -ItemType Directory -Force .cursor\skills\clickd-livecards\references | Out-Null
Invoke-WebRequest https://clickd.com/skills/livecards/SKILL.md -OutFile .cursor\skills\clickd-livecards\SKILL.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/card-tags.md -OutFile .cursor\skills\clickd-livecards\references\card-tags.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/framing-headers.md -OutFile .cursor\skills\clickd-livecards\references\framing-headers.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/embed-mode.md -OutFile .cursor\skills\clickd-livecards\references\embed-mode.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/troubleshooting.md -OutFile .cursor\skills\clickd-livecards\references\troubleshooting.md -UseBasicParsing

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.

Terminal, for Any other agent
mkdir -p docs/clickd-livecards/references
curl -fsSL https://clickd.com/skills/livecards/SKILL.md -o docs/clickd-livecards/SKILL.md
curl -fsSL https://clickd.com/skills/livecards/references/card-tags.md -o docs/clickd-livecards/references/card-tags.md
curl -fsSL https://clickd.com/skills/livecards/references/framing-headers.md -o docs/clickd-livecards/references/framing-headers.md
curl -fsSL https://clickd.com/skills/livecards/references/embed-mode.md -o docs/clickd-livecards/references/embed-mode.md
curl -fsSL https://clickd.com/skills/livecards/references/troubleshooting.md -o docs/clickd-livecards/references/troubleshooting.md
echo "For running a page inside a post on X, follow docs/clickd-livecards/SKILL.md." >> AGENTS.md
PowerShell, for Any other agent
New-Item -ItemType Directory -Force docs\clickd-livecards\references | Out-Null
Invoke-WebRequest https://clickd.com/skills/livecards/SKILL.md -OutFile docs\clickd-livecards\SKILL.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/card-tags.md -OutFile docs\clickd-livecards\references\card-tags.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/framing-headers.md -OutFile docs\clickd-livecards\references\framing-headers.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/embed-mode.md -OutFile docs\clickd-livecards\references\embed-mode.md -UseBasicParsing
Invoke-WebRequest https://clickd.com/skills/livecards/references/troubleshooting.md -OutFile docs\clickd-livecards\references\troubleshooting.md -UseBasicParsing
Add-Content AGENTS.md "For running a page inside a post on X, follow docs/clickd-livecards/SKILL.md."

Puts the files in docs/clickd-livecards/.

What is inside

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

Version 2.1.0, October 31, 2026ChangesSKILL.md in fullSourcesAs data, in skills.json

Sources

25 pages

Each is in a ## Sources list in the file that cites it, by the page’s own title.

Google Search Central

  1. 1How Google interprets the robots.txt specification, Google Search Central. One group followed, the most specific that matches, which Twitterbot follows too.

Platforms

  1. 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.
  2. 3Player Card, X developer docs, archived. The 68,600 pixel floor, how each client shows the card, and the validator's still picture.
  3. 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.
  4. 5next.js/packages/next/src/lib/metadata/metadata-elements.tsx, Vercel, on GitHub. Next.js writes `twitter:player:stream` for each listed player.
  5. 6next.js/packages/next/src/lib/metadata/metadata-resolution-primitives.ts, Vercel, on GitHub. Next.js fills the X tags from Open Graph when the page sets none.
  6. 7next.js/packages/next/src/shared/lib/router/utils/html-bots.ts, Vercel, on GitHub. The bots, Twitterbot among them, that get metadata in the head rather than streamed.
  7. 8Static Configuration with vercel.json, Vercel docs. The `headers` property, its `source` and its key and value pairs.
  8. 9Custom headers, Netlify Docs. `_headers` and `netlify.toml`, and that they skip Functions, Edge Functions and proxied responses.
  9. 10Headers, Cloudflare Docs. Cloudflare Pages `_headers`, rules that combine, the comma join, detaching with `!`, and Pages Functions left out.
  10. 11headers, Next.js docs. `headers()` in `next.config.js`, the last match winning, and `X-Frame-Options` superseded by `frame-ancestors`.
  11. 12Response, Express. `res.set`, which sets a header on the response.
  12. 13Helmet.js, Helmet. Helmet's default `X-Frame-Options: SAMEORIGIN` and `frame-ancestors 'self'`, and how to change a directive.
  13. 14HTTP, Node.js docs. `response.removeHeader`, which drops a header before it is sent.
  14. 15Module ngx_http_headers_module, nginx. `add_header`, `always`, and inheritance only when a level sets none.
  15. 16Module ngx_http_proxy_module, nginx. `proxy_hide_header`, which keeps a proxied header from the client.

Standards and protocols

  1. 17Content-Security-Policy: frame-ancestors directive, MDN Web Docs. The sources it takes, every ancestor checked, no fallback to `default-src`, and no support in `<meta>`.
  2. 18X-Frame-Options header, MDN Web Docs. `DENY`, `SAMEORIGIN`, the obsolete `ALLOW-FROM`, and no effect in `<meta>`.
  3. 19Content Security Policy Level 3, W3C. A `*.` host matches subdomains, and an enforced `frame-ancestors` makes a browser ignore `X-Frame-Options`.
  4. 20Content-Security-Policy (CSP) header, MDN Web Docs. More than one policy can only restrict further.
  5. 21Third-party cookies, MDN Web Docs. What makes a cookie third-party, and how Firefox, Safari and Chrome treat them by default.

Agent skills format and clients

  1. 22Extend Claude with skills, Anthropic, Claude Code docs. Where Claude Code loads skills from, and how one is called.
  2. 23Build skills, OpenAI, ChatGPT Learn. Where Codex loads skills from, and how one is called.
  3. 24Agent Skills, Cursor docs. Where Cursor loads skills from, and how one is called.
  4. 25Specification, Agent Skills. The format every skill here keeps: the folder, the frontmatter and its limits.