AgentSkillsCN

iframely

利用 Iframely API 进行 URL 元数据提取与富媒体嵌入。当您需要实现链接预览、URL 展开、oEmbed 集成、富媒体嵌入,或从 URL 中提取元数据(如标题、描述、缩略图)时,此技能都能轻松胜任。它涵盖了 API 端点、React 集成、embed.js 的配置、查询参数、响应解析,以及批量获取等功能。

SKILL.md
--- frontmatter
name: iframely
description: URL metadata extraction and rich media embedding with the Iframely API. Use when implementing link previews, URL unfurling, oEmbed integration, rich media embeds, or extracting metadata (title, description, thumbnails) from URLs. Covers API endpoints, React integration, embed.js setup, query parameters, response parsing, and batch fetching.

Iframely API

Iframely extracts metadata and generates embed codes for URLs. It parses Open Graph, Twitter Cards, oEmbed, and structured data from 1900+ domains.

API Endpoints

Iframely API (primary)

code
GET https://iframe.ly/api/iframely?url={URL}&api_key={API_KEY}

oEmbed API

code
GET https://iframe.ly/api/oembed?url={URL}&api_key={API_KEY}

CDN endpoint (for client-side calls)

code
GET https://iframely.net/api/iframely?url={URL}&key={MD5_OF_API_KEY}

Use key (MD5 hash of API key) instead of api_key for client-side requests.

Required Parameters

ParamDescription
urlURL-encoded target URL
api_keyYour API key (server-side)
keyMD5 hash of API key (client-side)

Response Structure

json
{
  "meta": {
    "title": "Page Title",
    "description": "Page description",
    "author": "Author Name",
    "author_url": "https://...",
    "site": "Site Name",
    "canonical": "https://...",
    "duration": 120,
    "date": "2024-01-01",
    "medium": "video"
  },
  "links": {
    "player": [{ "href": "...", "type": "text/html", "rel": ["player"], "media": {"aspect-ratio": 1.778}, "html": "<div>...</div>" }],
    "thumbnail": [{ "href": "...", "type": "image/jpeg", "rel": ["thumbnail"] }],
    "icon": [{ "href": "...", "type": "image/png", "rel": ["icon"] }]
  },
  "html": "<div>recommended embed HTML</div>",
  "rel": ["player", "ssl"],
  "id": "content-id"
}

Link Rel Types

RelPurpose
playerVideo, audio, slideshow widgets
imageMain content photos/pictures
appGeneral embeds (Twitter, Maps, etc.)
thumbnailPreview images
readerLong-form text widgets
surveyPolls and questionnaires
summarySummary cards
fileDownloadable files
iconFavicons
logoSite logos

MIME Types

TypeRenders as
text/htmliframe
video/mp4<video> element
application/x-mpegURLStreaming video
audio/mp3, audio/mpeg<audio> element
image/*<img> element

Query Parameters

iFrame & Rendering

ParamDescription
iframe=1Activate async iFrames with delivery helper
iframe=0Disable iFrame helper and interactives
omit_script=1Put rich media into Iframely iFrame (for React)
omit_css=1Replace inline styles with CSS class names
lazy=1Lazy-load hosted iFrames
align=leftRemove default center alignment

Content Control

ParamDescription
media=1Return media instead of rich apps
media=0Disable media, force summary cards
ssl=1Return only HTTPS-compatible media
autoplay=1Enable player autoplay
card=1Place media in card layout
card=smallSmall card layout
click_to_play=1Load players only on user click
consent=1Activate consent management
theme=darkDark theme (light, auto also valid)

Sizing

ParamDescription
maxwidthMax width in pixels for responsive embeds
maxheightMax height in pixels or viewport percentage

Output Format

ParamDescription
id=1Include content ID in response
amp=1Format output for AMP framework
playerjs=1Enable Player.js event controls
title=1Add title attributes (a11y)
callbackJSONP function name
format=xmlXML response (oEmbed only)
languageAccept-Language header (ISO 639-1)

Batch Fetching

Fetch up to 100 content IDs in one request:

code
GET https://iframe.ly/{ID1}-{ID2}-...-{IDn}.json

Response keys are the IDs (order not guaranteed):

json
{
  "ID1": { "meta": {...}, "links": {...} },
  "ID2": { "meta": {...}, "links": {...} }
}

React / Next.js Integration

Key Constraints

  • React's innerHTML ignores <script> tags per HTML5 spec
  • Must use &omit_script=1 parameter to get iframe-only HTML
  • Must load embed.js manually on the page
  • Must call window.iframely.load() after rendering

embed.js Setup

Add to your layout or _document:

html
<script src="//cdn.iframe.ly/embed.js" async></script>

React Component

tsx
"use client";

import { useEffect, useState } from "react";

const IFRAMELY_KEY = process.env.NEXT_PUBLIC_IFRAMELY_KEY!; // MD5 hash of API key

interface IframelyEmbedProps {
  url: string;
}

export function IframelyEmbed({ url }: IframelyEmbedProps) {
  const [html, setHtml] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetch(
      `https://iframely.net/api/iframely?url=${encodeURIComponent(url)}&key=${IFRAMELY_KEY}&iframe=1&omit_script=1`
    )
      .then((res) => res.json())
      .then((data) => {
        if (data.html) {
          setHtml(data.html);
        } else if (data.error) {
          setError(`${data.error}: ${data.message}`);
        }
      })
      .catch((err) => setError(err.message));
  }, [url]);

  useEffect(() => {
    if (html) {
      window.iframely?.load();
    }
  }, [html]);

  if (error) return <div>Error: {error}</div>;
  if (!html) return null;

  // dangerouslySetInnerHTML is safe here because omit_script=1
  // ensures no third-party scripts are included
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

Server-Side Fetching (Recommended)

Fetch metadata server-side and cache results:

typescript
// Server action or API route
export async function getUrlMetadata(url: string) {
  const apiKey = process.env.IFRAMELY_API_KEY!;
  const res = await fetch(
    `https://iframe.ly/api/iframely?url=${encodeURIComponent(url)}&api_key=${apiKey}&omit_script=1`,
    { next: { revalidate: 3600 } } // Cache 1 hour
  );
  return res.json();
}

Extracting Metadata Only (No Embed)

typescript
// Get just title, description, thumbnail
const data = await getUrlMetadata(url);

const meta = {
  title: data.meta?.title,
  description: data.meta?.description,
  thumbnail: data.links?.thumbnail?.[0]?.href,
  icon: data.links?.icon?.[0]?.href,
  site: data.meta?.site,
};

Error Handling

The API returns HTTP error codes:

CodeMeaning
403Invalid or missing API key
404URL not found / not supported
408Timeout fetching the URL
417URL returned error to Iframely
429Rate limit exceeded

TypeScript Types

typescript
interface IframelyResponse {
  meta: {
    title?: string;
    description?: string;
    author?: string;
    author_url?: string;
    site?: string;
    canonical?: string;
    duration?: number;
    date?: string;
    medium?: string;
  };
  links: Record<string, IframelyLink[]>;
  html?: string;
  rel?: string[];
  id?: string;
}

interface IframelyLink {
  href: string;
  type: string;
  rel: string[];
  media?: {
    "aspect-ratio"?: number;
    width?: number;
    height?: number;
    "max-width"?: number;
    "max-height"?: number;
  };
  html?: string;
}

Common Patterns

Link Preview Card

Extract meta.title, meta.description, links.thumbnail[0].href, and links.icon[0].href to build a link preview card without embedding.

Rich Media Embed

Use the top-level html field for the recommended embed. Fall back to links.player[0].html or links.app[0].html.

Thumbnail Extraction

typescript
const thumbnail = data.links?.thumbnail?.[0]?.href
  ?? data.links?.image?.[0]?.href;

Check If URL Has Embed

typescript
const hasEmbed = !!data.html || data.links?.player?.length > 0 || data.links?.app?.length > 0;