Repository navigation
Conversation
Adds an allows_embeds preference, on by default, to users and to organizations. Users change it in Settings → Profile, organization admins in the organization's settings, each through a dedicated controller like the pastéis mode. The preference is exported with the account and hidden from serialization. 🤖 Generated with Claude Code
GET /embed/{commit} renders a card of the commit, optionally with the
rest of its self-thread and its replies down to three levels or all,
as a guest sees it: the route skips the web group, so it never starts a
session or sets a cookie, and PreventFraming leaves it out in favour of
frame-ancestors *. The URL must be signed, so only the embed dialog can
hand one out, and every value outside the allowed ones falls back to
its default.
Commits that can't be shown keep their place as [deleted],
[embedding disabled] or [unavailable] tombstones. A card holds at most
40 commits, and an embeds limiter budgets each card per address with a
global ceiling per address on top.
The card has its own Vite entry, which loads only its page, and draws
the thread's rail with the commit page's geometry.
🤖 Generated with Claude Code
The card posts its height to the page that frames it whenever it changes. embed.js, a static script, listens for those messages, trusts only the ones from /dev/null's origin, and resizes the frame that sent each one. Including it twice listens once. 🤖 Generated with Claude Code
The embed dialog's Link tab will hand out the commit's page flagged with `embed` and carrying the card's signed query. GET /oembed turns such a link into a rich response framing the card, with embed.js, so blogging platforms build the card from the link alone. Bare and tampered links answer 401, links that aren't one of our commits 404, commits that can't be embedded 401, and any format but JSON 501. The commit's page advertises the endpoint only when it is opened from such a link. The endpoint skips the session and has its own per-address limit. 🤖 Generated with Claude Code
The arch tests keep queries away from HTTP resources and controllers away from abort_if. CommitEmbedQuery now returns models, which the controller shows through ShownStreams::embedNode, and the oEmbed statuses (501, 404, 401) move to ShowOEmbedRequest's authorization. 🤖 Generated with Claude Code
Members find Embed commit in a commit's "…" menu, after Send in Remotes, on approved commits whose author allows embeds: the web now tells each commit whether it is embeddable. The dialog follows the Settings pages: switches for the rest of the thread and the replies, segmented controls for replies per level, levels, max height and theme. Each change asks the new commit-embed-link endpoint, members only, for the card's signed URL and the commit link that stands for it; the preview frames the real card, and the HTML and Link tabs copy the code with a mono [embed <hash>] copied toast. The card's dates now read in the reader's own time, like on /dev/null. 🤖 Generated with Claude Code
With the rest of the thread shown, the author's next commit read twice: on the trunk, as 2/3, and among the replies. The replies now leave it out, like on the commit's page. 🤖 Generated with Claude Code
The profile page read it with usePage in its own markup, which the profile sync tests, rendering the page as a plain function, could not run. UserEmbedsSetting reads it itself, like PasteisModeSetting. 🤖 Generated with Claude Code
Behind a proxy that terminates TLS, or on another domain of the app, the card's absolute signature no longer matched the URL the app saw, so every card answered 403. Embeds are now signed and checked on their path and query only, like signed:relative. 🤖 Generated with Claude Code
The commit-embed-link endpoint now returns the code to paste, highlighted by the same CodeSpans as commit bodies, so the dialog shows it with the CodeBlock component, its wrap toggle and copy control. The iframe puts one attribute per line, so it reads without scrolling. A Markdown tab joins HTML and Link: Markdown renderers leave frames out, so it gives the commit's preview image linked to the commit, for READMEs and docs. 🤖 Generated with Claude Code
On a dark page, a light corner showed around the card: the app's page background painted the card's document, and a frame whose color scheme differs from its document's gets an opaque backdrop. The card's page stays transparent, and every frame (preview, HTML code, oEmbed) keeps color-scheme: normal like the card. 🤖 Generated with Claude Code
The tests tsconfig rejected setting a height on frames typed as empty objects, and the linter wants node:test calls marked with void, like the other node:test files. 🤖 Generated with Claude Code
The card was already part of the SSR bundle, which renders every page; a test now renders it the way ssr.tsx does and reads the commit, its replies, tombstones and footer in the server's HTML, so a reader with JavaScript off, or a sandboxed frame, still gets the whole card. Links opened outside the frame through a click handler only; a <base target="_blank"> now does it without JavaScript too. 🤖 Generated with Claude Code
A card asked for in Dark only turned dark through the inline script, so with JavaScript off it stayed light. The server now sets the dark class itself for an explicit Dark; only Auto still asks the browser. 🤖 Generated with Claude Code
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
The footer keeps the /dev/null wordmark and "View on /dev/null". 🤖 Generated with Claude Code
The header now reads like a commit on /dev/null: name, handle, date and the 1/3 thread badge, with the hash on the right except on the embedded commit, which carries it in its commit line like the focused commit on its page. The embedded commit's body is 17px, as there. The counts become /dev/null's actions row, read-only: the star with its count and the "› 5 replies" link, both opening the commit on /dev/null. Dates stay absolute. 🤖 Generated with Claude Code
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.
Summary
A first implementation of the commit embeds described in #1521, so the RFC can be discussed on something that runs. It's a draft: the design is open for discussion there, and this PR will follow what's decided.
Changes
/embed/{uuid}: a signed, framable, sessionless card showing the commit, its thread and replies the way /dev/null draws them (same header, thread badge and actions row, read-only), with tombstones for what can't be shown. It reads without JavaScript.embed.jsto size the frame, and an/oembedendpoint for the signed commit link.Not built yet: the 30-second cache, the
429fallback, a constant-query tree, and shared rail components.Validation
Locally: Pest (5919 passed), vitest (1069),
node:test, PHPStan, Pint,tsc, lint. Hosted CI not run yet.Visual evidence
Light and dark screenshots are in #1521, next to the parts they show. The card on a plain page:
Device verification
Desktop Chrome on macOS, light and dark, plus a 420px-wide page. Not checked on a phone.
Independent review
Not done yet; to be requested before this leaves draft.
Limitations
The items above that aren't built, and the open questions in #1521 (the name, the rollout in smaller PRs).