ReqEmbed (ReqEmbed v0.3.2)

View Source

Req plugin for oEmbed.

Features

  • Auto-Discovery: Finds oEmbed endpoints via HTML link tags (oEmbed discovery)
  • 350+ Providers: YouTube, Twitter, Instagram, and more
  • Content Types: Video, Photo, Rich media, and Link embeds
  • Phoenix Ready: HEEx component and HTML helpers
  • Customizable: CSS classes, responsive design, and embed options

Installation

Add :req_embed dependency:

def deps do
  [
    {:req_embed, "~> 0.2"}
  ]
end

Or use Igniter:

mix igniter.install req_embed

Usage

req_embed can be used directly as a Req plugin, or as a Phoenix component to render oEmbed content in HEEx templates.

Intro

Watch this ElixirCasts episode that covers all the features listed below.

ElixirCasts Episode 196

Req Plugin

req = Req.new() |> ReqEmbed.attach()

Req.get!(req, url: "https://www.youtube.com/watch?v=XfELJU1mRMg").body
#=>
# %ReqEmbed.Video{
#   type: "video",
#   version: "1.0",
#   title: "Rick Astley - Never Gonna Give You Up (Official Music Video)",
#   author_name: "Supirorguy508",
#   author_url: "https://www.youtube.com/@supirorguy5086",
#   provider_name: "YouTube",
#   provider_url: "https://www.youtube.com/",
#   cache_age: nil,
#   thumbnail_url: "https://i.ytimg.com/vi/XfELJU1mRMg/hqdefault.jpg",
#   thumbnail_width: 480,
#   thumbnail_height: 360,
#   html: "<iframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/XfELJU1mRMg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen title=\"Rick Astley - Never Gonna Give You Up (Official Music Video)\"></iframe>",
#   width: 200,
#   height: 113
# }

When successful, the response body will contain either one of the following structs representing the oEmbed type:

Phoenix Component

Use ReqEmbed.embed/1 to display oEmbed content in HEEx templates:

<ReqEmbed.embed url="https://www.youtube.com/watch?v=XfELJU1mRMg" class="aspect-video" />

Renders:

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" class="aspect-video" frameborder="0" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/XfELJU1mRMg?feature=oembed" title="Rick Astley - Never Gonna Give You Up (Official Music Video)"></iframe>

Note that :phoenix_live_view is required to use the component, it's not a direct dependency.

Raw HTML

Or alternatively use ReqEmbed.html/2 to get the oEmbed content as HTML:

ReqEmbed.html("https://www.youtube.com/watch?v=XfELJU1mRMg")
# <iframe width="200" height="113" src="https://www.youtube.com/embed/XfELJU1mRMg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Rick Astley - Never Gonna Give You Up (Official Music Video)"></iframe>

Wrap it in a {:safe, html} tuple or call Phoenix.HTML.raw/1 to render it in Phoenix templates.

Summary

Functions

Attach the oEmbed plugin into Req.

Phoenix Component to render oEmbed content.

Render the oEmbed content as HTML.

Functions

attach(request, options \\ [])

@spec attach(
  Req.Request.t(),
  keyword()
) :: Req.Request.t()

Attach the oEmbed plugin into Req.

Options

  • :query (map/0) (optional, default: %{}) - The query parameters to be sent to the oEmbed endpoint, like :maxwidth, :maxheight, and others supported by the provider. The parameters :url and :format are managed by the plugin, you can't override them. See section 2.2 Consumer Request for more info.

  • :discover (boolean/0) (optional, default: true) - When enabled, it will first attempt to auto-discover the oEmbed endpoint by looking for the link tag in the HTML response. If no link tag is found, it will fallback to searching for a known provider endpoint. When disabled, it will skip the HTML parsing step and only use the known provider endpoints.

Examples

iex> req = Req.new() |> ReqEmbed.attach()
iex> Req.get!(req, url: "https://x.com/ThinkingElixir/status/1848702455313318251").body
%ReqEmbed.Rich{
  type: "rich",
  version: "1.0",
  author_name: "ThinkingElixir",
  author_url: "https://twitter.com/ThinkingElixir",
  html: "<blockquote class="twitter-tweet"><p lang="en" dir="ltr">News includes upcoming Elixir v1.18 ...
  ...
}

Supports redirects too:

iex> req = Req.new() |> ReqEmbed.attach()
iex> Req.get!(req, url: "https://flic.kr/p/SHA4VC").body
%ReqEmbed.Photo{
  type: "photo",
  version: "1.0",
  title: "Above the cloud",
  author_name: "tomms",
  author_url: "https://www.flickr.com/photos/tomms/",
  thumbnail_url: "https://live.staticflickr.com/665/33288461746_67348617ea_q.jpg",
  url: "https://live.staticflickr.com/665/33288461746_67348617ea_b.jpg",
  ...
}

embed(assigns)

Phoenix Component to render oEmbed content.

Requires phoenix_live_view to be installed, otherwise you can use html/2 directly. This component is essentially a wrapper for html/2.

Examples

<ReqEmbed.embed url="https://www.youtube.com/watch?v=XfELJU1mRMg" />

<ReqEmbed.embed
  url="https://x.com/josevalim/status/1793946517390458957"
  class={@embed_class}
/>

<ReqEmbed.embed
  url="https://www.flickr.com/photos/example/123456789"
  include_caption={true}
/>

Attributes

  • url (String.t/0) (required) - URL of the resource to be embedded.
  • class (String.t/0) (optional) - CSS class to be added into the <iframe> tag. Note that when used, it removes both width and height attributes.
  • include_caption (boolean/0) (optional, default: true) - When enabled, it will include the photo title in <figcaption>.

html(url, opts \\ [])

Render the oEmbed content as HTML.

Options

  • :class (String.t/0) (optional, default: nil) - CSS class to be added into the <iframe> tag, if used it removes both width and height attributes.
  • :include_caption (boolean/0) (optional, default: true) - When enabled, it will include the photo title in <figcaption>.

Examples

iex> ReqEmbed.html("https://www.youtube.com/watch?v=XfELJU1mRMg")
<iframe width="200" height="113" src="https://www.youtube.com/embed/XfELJU1mRMg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Rick Astley - Never Gonna Give You Up (Official Music Video)"></iframe>

Replace the width and height attributes with a CSS class:

iex> ReqEmbed.html("https://www.youtube.com/watch?v=XfELJU1mRMg", class: "aspect-video")
<iframe class="aspect-video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/XfELJU1mRMg?feature=oembed" title="Rick Astley - Never Gonna Give You Up (Official Music Video)"></iframe>

Wrap it in a {:safe, html} tuple or call Phoenix.HTML.raw/1 to render it in Phoenix templates.