API to offer OpenGraph meta or oEmbed media.
Important
Social oEmbed is now deprecated, you can use iframely with self-hosted solution.
OpenGraph protocol offer a way to get meta data from a website to display a nice preview in social media and oEmbed offer to display an iframe from another website like social network.
With OpenGraph, from JavaScript application, on client side, you can't crawl website to extract metadata, you have to call an API to get these data, some services offer this API, but mostly aren't open source. About these services, you can find opengraph.io (free with API limit requests) or iframely (with own hosted solution).
With oEmbed, it's really complicated, each social network have their own API, with some limitations, some services offer to get these data but you have to pay for it, and it's really expensive (smashballoon, embedsocial...). Only iframely offer a free plan with some limitations, with own hosted, but with some limitations with Instagram or Facebook cause by Meta*.
This project is an attempt to offer a free (with own hosted solution) and open source API to get OpenGraph and oEmbed data.
*: to get Instagram or Facebook data, with iframely or with Meta API, you have to register your application on Meta, with many validations. Social oEmbed offer another solution without any key from Meta.
You could check the React demo app to see how it works.
- OpenGraph
- Dark mode with
dark=true
query parameter - Twitter card query with
opengraph=twitter
query parameter - Opiniated HTML render
- Dark mode with
- oEmbed
- Social network providers
- Fallback on OpenGraph if no oEmbed provider
- HTML render
- Rebuilt HTML iframe from
url
query parameter (oembed=nofetch
) : use some rules to find media ID from URL and rebuild HTML iframe without external request - Get HTML and metadata from oEmbed API (
oembed=fetch
) : some API have request limit or API key limit, if request is rejected, fallback on OpenGraph - Get metadata from website (
oembed=opengraph
) : some social networks use a lot of JavaScript, crawl can be limited
- Rebuilt HTML iframe from
- Smart queries, customize render for each social network [ ]
- Host your own instance [ ]
- Docker [ ]
- Middleware
- auth with
api_key
query parameter orBearer token
url
query parameter
- auth with
- Dailymotion: regex
- Instagram: regex
- Facebook: regex
- Flickr
- Giphy
- Imgur
- Kickstarter
- Snapchat
- Soundcloud
- Spotify: regex, API
- Ted
- Tumblr
- Tiktok: regex, API
- Twitch
- Twitter: regex, API
- Vimeo
- Youtube: regex
- OpenGraph
-
og:title
,og:description
,og:image
,og:url
,og:type
,og:site_name
,og:locale
- Color
theme-color
- Fallback to
twitter:title
,twitter:description
,twitter:image
,twitter:url
,twitter:card
,twitter:site
,twitter:creator
- All meta
-
twitter
query for card - Opiniated render
-
- oEmbed
- Major social networks support
- Providers system
- smart queries for each social network
- queries for iframe
- fallback to OpenGraph if no oEmbed, no provider or oEmbed error
- oEmbed rebuilt with match
- add api key for each provider
- Host your own instance
- Auth middleware https://github.com/fastify/middie
- Domains allow
*
or*.domain.com
- API key as query or header
- Request limit
- helmet with https://github.com/fastify/fastify-helmet
- Domains allow
- Documentation
- Usage from JS client side with fetch
- Usage response example, typescript interfaces
- Usage oembed
- Social networks providers specs
- examples alpinejs/react/vuejs
- Deploy nginx and pm2 docs
- Vite with https://github.com/fastify/fastify-dx
- social providers like https://iframely.com/links
- meta crawler like https://debug.iframely.com and https://iframely.com/embed
- Use Mongo to cache data
- Use Bun when it will be stable
Demo instance: https://social-oembed.git-projects.xyz
.
On this instance,
api_key
is disabled and HTTP headerAccess-Control-Allow-Origin
uselocalhost:3000,127.0.0.1:3000,localhost:5173,127.0.0.1:5173
, so you can test it from your browser or from any localhost application with port3000
or5173
.
GET /api
Parameter | Type | Required | Description |
---|---|---|---|
url |
string |
true |
URL of website like https://github.com . |
format |
opengraph , oembed |
false |
Format of data, default is opengraph . |
api_key |
string |
Depend of .env API_KEY variable |
API key. |
GET /instance
Information about API.
curl --request GET \
--data-urlencode "format=opengraph" \
--data-urlencode "url=https://github.com" \
--get "https://social-oembed.git-projects.xyz/api" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
curl --request GET \
--data-urlencode "format=oembed" \
--data-urlencode "url=https://www.youtube.com/watch?v=fXmAurh012s" \
--get "https://social-oembed.git-projects.xyz/api" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
Social oEmbed will parse url
website with cheerio and extract OpenGraph data from meta tags. If open graph data are not found, it will try to extract Twitter data or meta tags. If no data are found, it won't return an error, will have just an empty result. The response will be available into data
, another metadata you will find an an opiniated HTML render into data.render
, you could just display this into your application.
All data about fetch are available into meta.fetch
object.
Social oEmbed will try to find a provider from url
, if exists, it will use it to get oEmbed data from social network API. The API have to return a correct response to display an iframe, but sometimes oEmbed API have limits. If the request failed, the provider will try to rebuild embed url to inject it into an iframe. Like OpenGraph, you will have some metadata (built on OpenGraph type) into data
and a data.render
with an iframe. If no provider exists, you will have a fallback to OpenGraph.
All data about fetch are available into meta.fetch
object.
Note: if Social oEmbed can't find a provider from url
, your social network could be not supported by Social oEmbed and you can contribute to add it. But if provider exists, it could be the url
parse bug, you can open an issue.
// TODO contribute and issue
title?: string
description?: string
image?: string
siteUrl?: string
type?: string
siteName?: string
locale?: string
audio?: string
video?: string
determiner?: string
article:author?: string
themeColor?: string
icon?: string
width?: string
height?: string
social: Social
embedUrl?: string # oEmbed only
render: string
url: string # original url
format: string # opengraph or oembed
message: string # error message
instance: string # documentation url
fetch:
message: string
status: number
ok: boolean
type: string # json, text or unknown
Download dependencies
pnpm i
Create .env
cp .env.example .env
Execute dev
pnpm dev
Server is available on http://localhost:3000.
Variable | Type | Default | Description |
---|---|---|---|
NODE_ENV |
development ,test ,production |
development |
Current environment. |
LOG_LEVEL |
debug ,error ,fatal ,info ,trace ,warn ,silent |
debug |
Log level for debug. |
API_PORT |
number |
3000 |
Port used by your application |
API_HOST |
string |
localhost |
Host of your application |
API_HTTPS |
boolean |
false |
Enable https for you application |
API_KEY |
string , undefined , false |
false |
API key if you want to set it, if undefined or false API key protection is disabled |
API_DOMAINS |
string |
localhost:3000,127.0.0.1:3000 |
Domains allowed to use the API, seperated by commans, use * to allow all domains |
Build application
pnpm build
Start application from build
pnpm start
You have to serve application with a manager like pm2. A command offer to start application with pm2.
pnpm pm2
But the best way is to use Nginx with pm2.
Show errors with ESLint.
pnpm lint
Automatically fix errors.
pnpm lint:fix
Based on Fastify and TypeScript, with ESBuild for bundling (ESM format).
From template fastify-esbuild by davipon.
node
>= 16.xpnpm
>= 7.xfastify
4.xreact
18.xesbuild
0.15.x