DEV Community

Discussion on: Upgraded embed experience and new embed types in DEV posts

Collapse
 
ben profile image
Ben Halpern The DEV Team

In case anyone wants to peruse the PR where this landed in Forem

feat: add AI tool embed tags and paste-to-embed editor UX #22853

What type of PR is this? (check all applicable)

  • [x] Refactor
  • [x] Feature
  • [ ] Bug Fix
  • [ ] Optimization
  • [x] Documentation Update

Description

Adds embed support for 5 AI development tools via Forem's existing {% embed url %} liquid tag system, plus a paste-to-embed UX in the article editor.

New Embeds

Service URL Patterns Embed Method
HuggingFace *.hf.space, huggingface.co/spaces/*, huggingface.co/datasets/* iframe (Spaces + Dataset Viewer)
Bolt.new bolt.new/~/*, *.bolt.host iframe
Lovable *.lovable.app iframe
v0.dev v0.dev/chat/*, *.vusercontent.net iframe
Warp app.warp.dev/block/* iframe (converts to /block/embed/ URL)

Editor Paste-to-Embed

When a user pastes a URL into the article body editor, an inline popover appears near the cursor offering to convert it into an {% embed url %} tag. The popover:

  • Uses Forem's existing getCursorXY utility and c-autocomplete__popover styles
  • Auto-dismisses after 5 seconds or on keypress
  • Works for any URL (not limited to the 5 new services)

Architecture

All embeds use UnifiedEmbed only — no standalone {% tagname %} liquid tag registration. Each tag class:

  1. Defines REGISTRY_REGEXP for URL matching
  2. Implements parse_input to normalize URLs for iframe src
  3. Registers via UnifiedEmbed.register(TagClass, regexp: ...)
  4. Renders through a shared partial pattern (liquids/_tagname.html.erb)

Services Evaluated but Not Included

  • Claudebin — embed API requires undocumented query params
  • Streamlitknown upstream iframe redirect loop caused by SameSite=Lax cookies
  • ChatGPT, Amp, Cursor — no embeddable share URLs or blocked by CSP/x-frame-options

Related Tickets & Documents

  • N/A

QA Instructions, Screenshots, Recordings

Testing embeds

  1. Create or edit an article
  2. In the body, add any of these liquid tags:
    {% embed https://huggingface.co/spaces/microsoft/TRELLIS.2 %}
    {% embed https://huggingface.co/datasets/nyu-mll/glue %}
    {% embed https://simple-team-project-djg1.bolt.host %}
    {% embed https://shared-doc-chat.lovable.app %}
    {% embed https://v0.dev/chat/public-link-request-PUaBPjRAhiL %}
    {% embed https://app.warp.dev/block/vzFATak939iqGWfNh7wsAP %}
    
  3. Preview/publish — each should render as an iframe embed

Testing paste-to-embed

  1. Copy any URL to clipboard
  2. Paste it into the article body textarea
  3. An inline popover should appear near the pasted text with "Embed" and "Dismiss" buttons
  4. Clicking "Embed" replaces the URL with {% embed <url> %}
  5. Clicking "Dismiss" (or waiting 5s, or pressing any key) removes the popover

UI accessibility checklist

  • [x] Semantic HTML implemented?
  • [x] Keyboard operability supported?
  • [ ] Checked with axe DevTools and addressed Critical and Serious issues?
  • [x] Color contrast tested?

Added/updated tests?

  • [x] Yes

Ruby (44 examples, 0 failures):

  • spec/liquid_tags/huggingface_tag_spec.rb — 10 examples (Spaces, Datasets, embed viewer)
  • spec/liquid_tags/bolt_tag_spec.rb — 7 examples (bolt.host, bolt.new)
  • spec/liquid_tags/lovable_tag_spec.rb — 6 examples
  • spec/liquid_tags/v0_tag_spec.rb — 9 examples (vusercontent.net, v0.dev/chat)
  • spec/liquid_tags/warp_tag_spec.rb — 6 examples (block URL → embed URL conversion)
  • spec/liquid_tags/ai_embeds_integration_spec.rb — 6 routing + 5 rendering examples

JavaScript (7 tests passing):

  • app/javascript/article-form/components/__tests__/pasteURLHelpers.test.js — popover display, embed replacement, dismiss, fallback positioning

[optional] Are there any post deployment tasks we need to perform?

No. All embeds register automatically on app boot via UnifiedEmbed.register. No migrations or ENV changes needed.

CleanShot 2026-02-26 at 13 30 17 CleanShot 2026-02-26 at 13 51 44

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

It's great to have these new features, and thanks to the team (especially @jonmarkgo). But tell me, @ben, can't you fix this ugly Github embed?
I would really like to use it in my articles, just like I use other embeds, but honestly, it's too ugly!

Github embed