# Interactive media and embeds

Canonical URL: https://encode.wiki/reference/interactive-media/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): 49891387c7fd47e0b8b10c8c1299431f4e84625e70113af33613ccf59255aead

import {
  forgejoPullPreview,
  githubReleasePreview,
  githubRepositoryPreview,
  gitlabIssuePreview,
} from '../../../data/examples/forge-previews';

Encode Wiki provides focused components for encoding-oriented visual evidence. Their no-JavaScript states retain the underlying images or links, and their enhanced controls work with touch, mouse, and keyboard input.

## Before-and-after image slider

Drag the divider, tap a position, or focus the comparison and use the arrow keys. Both images must be local site assets with matching dimensions so the comparison remains stable and does not disclose reader data to another host.

> **Image comparison — Illustrative banding and shape degradation.** [Open the before image](/media/examples/gradient-reference.svg) · [Open the after image](/media/examples/gradient-banded.svg)

```mdx
import ImageComparison from '../../../components/ImageComparison.astro';

<ImageComparison
  beforeSrc="/media/comparisons/reference.png"
  beforeAlt="Describe the reference image."
  beforeLabel="Reference"
  afterSrc="/media/comparisons/encoded.avif"
  afterAlt="Describe the encoded result and visible differences."
  afterLabel="Encoded"
  caption="Frame 120: reference compared with the test encode"
  width={1920}
  height={1080}
/>
```

## Expandable prose images

Ordinary images inside page content are expandable automatically. Click or focus the example below and press Enter or Space. A native dialog shows the largest source the browser selected and retains an “Open original image” link.

<img
  src="/media/examples/gradient-reference.svg"
  alt="Smooth reference gradient used to demonstrate the page image lightbox."
  width="960"
  height="540"
  loading="lazy"
/>

Carousel, chart, and comparison images are excluded because those components already own their interactions. Add `data-no-image-expand` to an image or ancestor when expansion would be inappropriate.

## X post embeds

X posts are supported without loading a third-party script during ordinary page reading. The reader must choose **Load post** before the site requests X's official widget. The integration requests X's do-not-personalize mode and always preserves a direct post link if the widget is blocked or unavailable.

> **External post:** [Example post from the US Department of the Interior](https://x.com/Interior/status/463440424141459456)

```mdx
import XPostEmbed from '../../../components/XPostEmbed.astro';

<XPostEmbed
  url="https://x.com/account/status/1234567890123456789"
  label="Describe why this post is relevant"
  hideMedia={false}
  hideThread={true}
/>
```

Only HTTPS post URLs on `x.com` and `twitter.com` are accepted. Other providers should receive a provider-specific, consent-gated component and a Content Security Policy review instead of an unrestricted raw iframe.

## Bluesky post embeds

Bluesky posts use the provider's oEmbed endpoint and widget only after the reader chooses **Load post**. The response is reduced to an allowlisted blockquote before Bluesky's widget scans it. A direct link remains available if the post is private, deleted, blocked, or unavailable.

<BlueskyPostEmbed
  url="https://bsky.app/profile/bsky.app/post/3mnzpi4dv7s25"
  label="Example post from Bluesky"
/>

```mdx
import BlueskyPostEmbed from '../../../components/BlueskyPostEmbed.astro';

<BlueskyPostEmbed
  url="https://bsky.app/profile/account.example/post/3example"
  label="Describe why this Bluesky post is relevant"
/>
```

Only `https://bsky.app/profile/{account}/post/{id}` URLs are accepted.

## LinkedIn post embeds

LinkedIn posts are also consent gated. The component creates LinkedIn's official post iframe only after the reader chooses **Load post**. LinkedIn only makes public posts available for embedding and does not support every post format.

<LinkedInPostEmbed
  url="https://www.linkedin.com/posts/linkedin_stay-up-to-date-on-your-linkedin-activity-activity-6124295313319538688-ILYg"
  label="Example public post from LinkedIn"
  height={480}
/>

```mdx
import LinkedInPostEmbed from '../../../components/LinkedInPostEmbed.astro';

<LinkedInPostEmbed
  url="https://www.linkedin.com/feed/update/urn:li:activity:1234567890123456789"
  label="Describe why this LinkedIn post is relevant"
  height={480}
/>
```

The `url` may be a public post URL, a `feed/update` URL, LinkedIn's copied iframe URL, or a post URN such as `urn:li:activity:…`. Heights from 240 to 900 pixels are accepted.

## Repository and release cards

Forge cards are compact, static HTML built from `src/data/forge/snapshot.json`, a committed snapshot of public forge metadata. Builds never contact a forge, and readers contact one only when they follow a link. If a repository or resource is missing from the snapshot, the card renders as a plain link.

### Project cards

`ProjectCard` is the card at the top of each tool page. It shows the repository, its description, the latest release (or latest version tag) and its date, the date of the last commit and the license. On shared hosts such as GitHub, GitLab.com and Codeberg it also shows the star count. A badge appears only when the project is archived or had no commits in the year before the snapshot.

> **Repository:** [xiph/rav1e](https://github.com/xiph/rav1e). The fastest and safest AV1 encoder. Latest release: [v0.8.1](https://github.com/xiph/rav1e/releases/tag/v0.8.1), Jun 16, 2025. Last commit: Aug 31, 2026. License: BSD-2-Clause. Stars: 4,160.

> **Repository:** [psy-ex/svt-av1-psy](https://github.com/psy-ex/svt-av1-psy) (Archived). The Scalable Video Technology for AV1 (SVT-AV1 Encoder and Decoder) with perceptual enhancements for psychovisually optimal AV1 encoding. Latest release: [v3.0.2](https://github.com/psy-ex/svt-av1-psy/releases/tag/v3.0.2), Apr 20, 2025. Last commit: Feb 12, 2026. License: BSD-3-Clause-Clear. Stars: 396.

> **Repository:** [videolan/x264](https://code.videolan.org/videolan/x264) (No commits since Sep 2025). x264, the best and fastest H.264 encoder. Last commit: Sep 10, 2025. License: GPL-2.0-or-later.

```mdx
import ProjectCard from '../../../components/ProjectCard.astro';

<ProjectCard repository="https://github.com/xiph/rav1e" />
<ProjectCard repository="https://gitlab.com/AOMediaCodec/SVT-AV1" tag="v4.2.0" />
<ProjectCard
  repository="https://code.videolan.org/videolan/x264"
  provider="gitlab"
  release={false}
/>
```

Set `release={false}` for projects that publish neither releases nor version tags, and `tag` to show a specific release instead of the latest. `src/data/forge/tool-projects.json` maps each tool page to its upstream repository and records whether the project publishes releases, only version tags, or neither. `node scripts/insert-project-cards.mjs` adds the import and card to every mapped page that lacks one; `--check` reports missing cards without writing.

### Refresh the snapshot

```sh
pnpm forge:refresh
GITHUB_TOKEN=… pnpm forge:refresh --only rav1e
```

The refresh script reads the tool mapping and every `ForgeCard`, `ReleaseCard` and `ProjectCard` in the content (cards in code blocks and cards with example data are skipped), queries the GitHub, GitLab and Forgejo APIs, and records `fetchedAt` for each entry. Anonymous requests work, but GitHub allows only 60 an hour. `GITHUB_TOKEN` is sent only to `api.github.com` and `GITLAB_TOKEN` only to `gitlab.com`; other hosts are queried anonymously. Pass `--wait` to sleep through rate limits and `--only <text>` to refresh matching URLs. Entries that fail keep their previous data and the script exits non-zero.

### Repository, issue and pull request cards

`ForgeCard` accepts a repository, issue, pull request or merge request URL. The examples below pass `preview` data from `src/data/examples/forge-previews.ts` instead of reading the snapshot.

> **Repository:** [xiph/rav1e](https://github.com/xiph/rav1e). The fastest and safest AV1 encoder. Last commit: Aug 31, 2026. License: BSD-2-Clause. Stars: 4,160.

> **Forge link:** [#2182 SVT-AV1](https://gitlab.com/AOMediaCodec/SVT-AV1/-/issues/2182). Repository: [AOMediaCodec/SVT-AV1](https://gitlab.com/AOMediaCodec/SVT-AV1).

> **Forge link:** [#1 forgejo](https://codeberg.org/forgejo/forgejo/pulls/1). Repository: [forgejo/forgejo](https://codeberg.org/forgejo/forgejo).

```mdx
import ForgeCard from '../../../components/ForgeCard.astro';

<ForgeCard url="https://github.com/xiph/rav1e" />
<ForgeCard url="https://github.com/owner/project/issues/123" />
<ForgeCard url="https://gitlab.com/group/project/-/merge_requests/42" />
<ForgeCard url="https://codeberg.org/owner/project/pulls/7" />
```

Issue and pull or merge request cards show the reference, title, state, repository, author, update date, comment count and labels. GitHub, GitLab.com, GitGud, Codeberg and Forgejo's own instance are detected automatically. Use a provider hint for other self-hosted instances:

```mdx
<ForgeCard url="https://git.example.org/group/project/-/issues/12" provider="gitlab" />
<ForgeCard url="https://code.example.org/owner/project/pulls/12" provider="forgejo" />
```

The refresh script only queries HTTPS URLs on public DNS names and refuses hosts that resolve to private or local addresses.

### Release cards

`ReleaseCard` accepts a repository base URL. Omit `tag` for the latest published release at the time of the snapshot, or set it for a specific release.

> **Forge link:** [v0.8.1](https://github.com/xiph/rav1e/releases/tag/v0.8.1) (Latest). Repository: [xiph/rav1e](https://github.com/xiph/rav1e). Published: Jun 16, 2025.

```mdx
import ReleaseCard from '../../../components/ReleaseCard.astro';

<ReleaseCard repository="https://github.com/xiph/rav1e" />
<ReleaseCard repository="https://github.com/xiph/rav1e" tag="v0.7.1" />
<ReleaseCard repository="https://gitgud.io/group/project" provider="gitlab" />
```

Release cards show the release name and tag, the publication state (pre-releases and drafts are labelled), the author, date and asset count.
