Twitter/X Embed#
Twitter/X embeds are opt-in and never load a third-party widget script.
twitter: true renders the privacy-conscious link card. Use the object form to
fetch the post body, author, avatar, photos, and video posters at build time.
Fetched cards also render timestamp, source link, available engagement metrics,
a nested quoted-post card, and a “Replying to @…” link when that metadata is
present. Set appearance: "full" for a sveltweet / react-tweet-shaped static
card, or override one embed with appearance="full":
import { oxContent } from "@ox-content/vite-plugin";
export default {
plugins: [
oxContent({
embeds: {
twitter: {
fetch: true,
lang: "en",
appearance: "compact",
timeZone: "UTC",
mediaOutputDir: "public/ox-content/twitter",
mediaPublicPath: "/ox-content/twitter",
},
},
}),
],
};
<XPost url="https://x.com/evanyou/status/1688035849638977536" />
<XPost url="https://x.com/evanyou/status/1688035849638977536" appearance="full" />
Fetched metadata is cached in memory and under .cache/ox-content/twitter by
default. Avatars, photos, and video posters — including those on a quoted post —
are copied into the configured output directory, so the generated page can use a
strict img-src 'self' policy. Video and animated GIF files are downloaded only
when downloadVideo is true, stay within maxVideoBytes, and are never
hotlinked from video.twimg.com. If the post is deleted, private, or
unavailable during a build, Ox Content falls back to the link-only card instead
of failing the build. A missing quoted post is omitted without discarding the
root card.
| Option | Default | Purpose |
|---|---|---|
fetch |
false |
Fetch post content from X at build time. |
lang |
"en" |
Syndication language and displayed date. |
timeout |
10000 |
Metadata request timeout in milliseconds. |
cache |
true |
Enable in-memory and persistent JSON caches. |
cacheDir |
.cache/ox-content/twitter |
Persistent metadata cache directory. |
mediaOutputDir |
public/ox-content/twitter |
Local directory for avatars, photos, and videos. |
mediaPublicPath |
/ox-content/twitter |
URL prefix emitted for downloaded media. |
downloadVideo |
false |
Download MP4 video and animated GIF assets. |
maxVideoBytes |
8388608 |
Skip videos larger than this (8 MiB). |
appearance |
"compact" |
"full" for sveltweet-shaped static chrome. |
timeZone |
"UTC" |
IANA zone for full-card timestamps. |
Full appearance is static HTML/CSS: no hydration, widget iframe, or per-card
listeners. It reuses the same materialized avatar/photo/video assets as compact.
Pages that only render compact cards do not ship the full-card CSS.
Custom ssg: false hosts import @ox-content/vite-plugin/styles/social.css
and, for full cards, styles/twitter-full.css. See
Component styles.
The full-card visual contract follows MIT-licensed
react-tweet (Copyright (c) 2023 Luis
Alvarez) and sveltweet (Copyright (c)
2024 ryoppippi). Notices are in Credits and
social-tweet-full.css. X, Twitter, and related marks are trademarks of their
respective owners.
Intentional differences from sveltweet@0.5.1 / react-tweet:
- Copy link is a static permalink with
data-ox-tweet-copyhooks. The card stays useful without JavaScript; integrations that enhance those hooks get the same Copy link / Copied! swap as react-tweet. - No fonts or assets from the X/Twitter CDN. The card uses the page font stack.
- Timestamps default to UTC so build output does not depend on the builder
timezone. Set
timeZone: "Europe/London"(or another IANA zone) to match a site-local clock. Invalid zones fall back to UTC. - Downloaded video uses native
<video controls>instead of a custom player. - Government / legacy verified badges share the checkmark glyph and change color only. Side-by-side sveltweet VRT is not in CI; HTML fixtures cover the states.