JavaScript library that simplifies the extraction of HTML meta and Open Graph tags from HTML content or URLs. These tags provide structured metadata for webpages, useful for social media sharing and SEO purposes.
The library is compatible with both server and browser environments, supporting ES6 and CommonJS module systems. ES6 modules are suitable for modern browsers, while CommonJS modules are commonly used in server-side JavaScript environments like Node.js.
Features
- Lightning-fast performance for optimal efficiency.
- Versatile compatibility with both Node.js and web browsers.
- Effortlessly extract HTML meta and Open Graph tags from HTML code or URLs.
- Seamlessly parse and access metadata such as
og:title
,og:description
,og:image
,favicon
, and more. - Developed using TypeScript to ensure robust type safety.
- Simple integration into web applications for hassle-free implementation.
- Comprehensive support for error handling and customization options.
<!– Basic –>
<meta charset=”UTF-8″>
<meta name=”keywords” content=”your, tags”>
<meta name=”description” content=”150 words”>
<meta name=”subject” content=”your website’s subject”>
<meta name=”copyright” content=”company name”>
<meta name=”language” content=”ES”>
<meta name=”robots” content=”index,follow”>
<meta name=”revised” content=”Sunday, July 18th, 2010, 5:15 pm”>
<meta name=”abstract” content=””>
<meta name=”topic” content=””>
<meta name=”summary” content=””>
<meta name=”Classification” content=”Business”>
<meta name=”author” content=”name, email@hotmail.com”>
<meta name=”designer” content=””>
<meta name=”reply-to” content=”email@hotmail.com”>
<meta name=”owner” content=””>
<meta name=”url” content=”http://www.websiteaddrress.com”>
<meta name=”identifier-URL” content=”http://www.websiteaddress.com”>
<meta name=”directory” content=”submission”>
<meta name=”pagename” content=”jQuery Tools, Tutorials and Resources – O’Reilly Media”>
<meta name=”category” content=””>
<meta name=”coverage” content=”Worldwide”>
<meta name=”distribution” content=”Global”>
<meta name=”rating” content=”General”>
<meta name=”revisit-after” content=”7 days”>
<meta name=”subtitle” content=”This is my subtitle”>
<meta name=”target” content=”all”>
<meta name=”HandheldFriendly” content=”True”>
<meta name=”MobileOptimized” content=”320″>
<meta name=”date” content=”Sep. 27, 2010″>
<meta name=”search_date” content=”2010-09-27″>
<meta name=”DC.title” content=”Unstoppable Robot Ninja”>
<meta name=”ResourceLoaderDynamicStyles” content=””>
<meta name=”medium” content=”blog”>
<meta name=”syndication-source” content=”https://mashable.com/2008/12/24/free-brand-monitoring-tools/”>
<meta name=”original-source” content=”https://mashable.com/2008/12/24/free-brand-monitoring-tools/”>
<meta name=”verify-v1″ content=”dV1r/ZJJdDEI++fKJ6iDEl6o+TMNtSu0kv18ONeqM0I=”>
<meta name=”y_key” content=”1e39c508e0d87750″>
<meta name=”pageKey” content=”guest-home”>
<meta itemprop=”name” content=”jQTouch”>
<meta http-equiv=”Expires” content=”0″>
<meta http-equiv=”Pragma” content=”no-cache”>
<meta http-equiv=”Cache-Control” content=”no-cache”>
<meta http-equiv=”imagetoolbar” content=”no”>
<meta http-equiv=”x-dns-prefetch-control” content=”off”>
<!– Apple –>
<meta name=”apple-mobile-web-app-title” content=”My App”> <!– New in iOS6 –>
<meta name=”apple-mobile-web-app-capable” content=”yes”>
<meta name=”apple-touch-fullscreen” content=”yes”>
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”>
<meta name=”format-detection” content=”telephone=no”>
<meta name=”viewport” content=”width=device-width; content=”width = 320; initial-scale=1.0; maximum-scale=1.0; user-scalable=yes; target-densitydpi=160dpi”>
<link href=”/apple-touch-icon.png” rel=”apple-touch-icon” type=”image/png”>
<link href=”touch-icon-ipad.png” rel=”apple-touch-icon” sizes=”72×72″>
<link href=”touch-icon-iphone4.png” rel=”apple-touch-icon” sizes=”114×114″>
<link href=”/startup.png” rel=”apple-touch-startup-image”>
<link href=”http://github.com/images/touch-icon-iphone4.png” sizes=”114×114″ rel=”apple-touch-icon-precomposed”>
<link href=”http://github.com/images/touch-icon-ipad.png” sizes=”72×72″ rel=”apple-touch-icon-precomposed”>
<link href=”http://github.com/images/apple-touch-icon-57×57.png” sizes=”57×57″ rel=”apple-touch-icon-precomposed”>
<!– Safari 9 –>
<link rel=”mask-icon” href=”website_icon.svg” color=”red”>
<!– Internet Explorer –>
<meta http-equiv=”Page-Enter” content=”RevealTrans(Duration=2.0,Transition=2)”>
<meta http-equiv=”Page-Exit” content=”RevealTrans(Duration=3.0,Transition=12)”>
<meta name=”mssmarttagspreventparsing” content=”true”>
<meta content=”IE=edge,chrome=1″ http-equiv=”X-UA-Compatible”/>
<meta name=”msapplication-starturl” content=”http://blog.reybango.com/about/”>
<meta name=”msapplication-window” content=”width=800;height=600″>
<meta name=”msapplication-navbutton-color” content=”red”>
<meta name=”application-name” content=”Rey Bango Front-end Developer”>
<meta name=”msapplication-tooltip” content=”Launch Rey Bango”s Blog”>
<meta name=”msapplication-task” content=”name=About;action-uri=/about/;icon-uri=/images/about.ico”>
<meta name=”msapplication-task” content=”name=The Big List;action-uri=/the-big-list-of-javascript-css-and-html-development-tools-libraries-projects-and-books/;icon-uri=/images/list_links.ico”>
<meta name=”msapplication-task” content=”name=jQuery Posts;action-uri=/category/jquery/;icon-uri=/images/jquery.ico”>
<meta name=”msapplication-task” content=”name=Start Developing;action-uri=/category/javascript/;icon-uri=/images/script.ico”>
<meta name=”msvalidate.01″ content=”6E3AD52DC176461A3C81DD6E98003BC9″>
<meta http-equiv=”cleartype” content=”on”>
<!– Windows 8 –>
<meta name=”application-name” content=” Contoso” />
<meta name=”msapplication-TileColor” content=” #009900″ />
<meta name=”msapplication-square70x70logo” content=”images/smalltile.png” />
<meta name=”msapplication-square150x150logo” content=”images/mediumtile.png” />
<meta name=”msapplication-wide310x150logo” content=”images/widetile.png” />
<meta name=”msapplication-square310x310logo” content=”images/largetile.png” />
<meta name=”msapplication-notification” content=”frequency=30; polling-uri=notifications/contoso1.xml; polling-uri2=notifications/contoso2.xml; polling-uri3=notifications/contoso3.xml” />
<!– Blog Catalog –>
<meta name=”blogcatalog”>
<!– Rails –>
<meta name=”csrf-param” content=”authenticity_token”>
<meta name=”csrf-token” content=”/bZVwvomkAnwAI1Qd37lFeewvpOIiackk9121fFwWwc=”>
<!– HTML Link –>
<link rel=”alternate” type=”application/rss+xml” title=”RSS” href=”http://feeds.feedburner.com/martini”>
<link rel=”alternate” type=”application/atom+xml” title=”Atom 0.3″ href=”https://example.com/feed.atom”>
<link rel=”shortcut icon” type=”image/ico” href=”/favicon.ico”>
<link rel=”fluid-icon” type=”image/png” href=”/fluid-icon.png”>
<link rel=”me” type=”text/html” href=”http://google.com/profiles/thenextweb”>
<link rel=”shortlink” href=”http://blog.unto.net/?p=353″>
<link rel=”archives” title=”May 2003″ href=”http://blog.unto.net/2003/05/”>
<link rel=”index” title=”DeWitt Clinton” href=”http://blog.unto.net/”>
<link rel=”start” title=”Pattern Recognition 1″ href=”http://blog.unto.net/photos/pattern_recognition_1_about/”>
<link rel=”bookmark”title=”Styleguide” href=”http://paulrobertlloyd.com/about/styleguide/”>
<link rel=”search” href=”/search.xml” type=”application/opensearchdescription+xml” title=”Viatropos”>
<link rel=”self” type=”application/atom+xml” href=”http://www.syfyportal.com/atomFeed.php?page=3″>
<link rel=”first” href=”http://www.syfyportal.com/atomFeed.php”>
<link rel=”next” href=”http://www.syfyportal.com/atomFeed.php?page=4″>
<link rel=”previous” href=”http://www.syfyportal.com/atomFeed.php?page=2″>
<link rel=”last” href=”http://www.syfyportal.com/atomFeed.php?page=147″>
<link rel=”canonical” href=”http://smallbiztrends.com/2010/06/9-things-to-do-before-entering-social-media.html”>
<link rel=”EditURI” type=”application/rsd+xml” title=”RSD” href=”http://smallbiztrends.com/xmlrpc.php?rsd”>
<link rel=”pingback” href=”http://smallbiztrends.com/xmlrpc.php”>
<link rel=”stylesheet” media=”only screen and (max-device-width: 480px)” href=”http://wordpress.org/style/iphone.css” type=”text/css”>
<link rel=”wlwmanifest” href=”http://www.example.com/wp-includes/wlwmanifest.xml” type=”application/wlwmanifest+xml”>
<link rel=”help” title=”FAQ” href=”/faq”>
<link rel=”logo” type=”image/svg” href=”https://playfoursquare.s3.amazonaws.com/press/logo/foursquare-logo.svg”>
<link rel=”P3Pv1″ href=”/w3c/p3p.xml”>
<link rel=”publisher” href=”https://plus.google.com/115081025762845243709/”>
<link rel=”image_src” href=”http://du3itj18e4z0b.cloudfront.net/7b29fe/images/icon-facebook.gif” type=”image/jpeg”>
<link rel=”author” href=”humans.txt” type=”text/plain”>
<link href=”http://thenextweb.com/2009/01/08/how-to-snap-up-that-twitter-username-youve-always-wanted/” rel=”original-source”>
<link rel=”profile” title=”Microformats” href=”http://microformats.org/profile/specs/”>
<link rel=”profile” href=”http://gmpg.org/xfn/11″>
<meta name="keywords" content="your tags" />
<meta name="description" content="150 words" />
<meta name="subject" content="your website's subject">
<meta name="language" content="ES">
<meta name="robots" content="indexfollow" />
<meta name="revised" content="Friday August 26th 2018 5:55 pm" />
<meta name="abstract" content="">
<meta name="topic" content="">
<meta name="summary" content="">
<meta name="Classification" content="Business">
<meta name="author" content="name email@gmail.com">
<meta name="designer" content="">
<meta name="copyright" content="">
<meta name="reply-to" content="email@gmai.com">
<meta name="owner" content="">
<meta name="url" content="https://www.wwcelebrities.com">
<meta name="identifier-URL" content="http://www.websiteaddress.com">
<meta name="directory" content="submission">
<meta name="category" content="">
<meta name="coverage" content="Worldwide">
<meta name="distribution" content="Global">
<meta name="rating" content="General">
<meta name="revisit-after" content="7 days">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta name="og:title" content="The Rock" />
<meta name="og:type" content="fashion" />
<meta name="og:url" content="https://www.wwcelebrities.com/2018/10/8-tips-fashion-help.html" />
<meta name="og:image" content="http://tny.im/goh" />
<meta name="og:site_name" content="WWCelebrities" />
<meta name="og:description" content="......" />
<meta name="fb:page_id" content="YOUR ID In profile url after ID#" />
<meta name="og:email" content="me@example.com" />
<meta name="og:phone_number" content="650-123-4567" />
<meta name="og:fax_number" content="+1-415-123-4567" />
<meta name="og:latitude" content="37.416343" />
<meta name="og:longitude" content="-122.153013" />
<meta name="og:street-address" content="1601 S California Ave" />
<meta name="og:locality" content="Palo Alto" />
<meta name="og:region" content="CA" />
<meta name="og:postal-code" content="94304" />
<meta name="og:country-name" content="USA" />
<meta property="og:type" content="game.achievement" />
<meta property="og:points" content="POINTS_FOR_ACHIEVEMENT" />
<meta property="og:video" content="http://example.com/awesome.swf" />
<meta property="og:video:height" content="640" />
<meta property="og:video:width" content="385" />
<meta property="og:video:type" content="application/x-shockwave-flash" />
<meta property="og:video" content="http://example.com/html5.mp4" />
<meta property="og:video:type" content="video/mp4" />
<meta property="og:video" content="http://example.com/fallback.vid" />
<meta property="og:video:type" content="text/html" />
<meta property="og:audio" content="http://example.com/amazing.mp3" />
<meta property="og:audio:title" content="Best Song" />
<meta property="og:audio:artist" content="Best Band" />
<meta property="og:audio:album" content="Best Album" />
<meta property="og:audio:type" content="application/mp3" />
To circumvent CORS (Cross-Origin Resource Sharing) issues, one approach is to execute the extractFromUrl function from a server-side environment. Alternatively, if you are working in a browser-based setting, you can proxy the request through a free service such as allorigins.win.
For instance, you can use the following URL format to access the desired resource: https://api.allorigins.win/get?url=https://www.retool.com. This will allow you to retrieve the necessary data without running into CORS restrictions. By leveraging this method, you can effectively work around CORS limitations and access the desired information seamlessly.
The module utilizes the following third-party tools for testing and functionality:
- Vitest: Next-generation testing framework.
- Cheerio: A fast, flexible, and lean implementation of core jQuery designed for server-side Node.js.
- Markdwown-Badges: Badges for your personal developer branding, profile, and projects.
We welcome contributions to the @jcottam/html-metadata module! If you’d like to contribute, please follow these guidelines:
- Fork the repository and create a branch.
- Make your changes and ensure that the code style and tests pass.
- Submit a pull request with a detailed description of your changes.
Click on the “Fork” button in the top right corner of the repository page. This will create a copy of the repository under your GitHub account.
git clone https://github.com/your-username/@jcottam/html-metadata.git
Create a new branch to work on your changes:
git checkout -b feature-branch
Make your desired changes to the codebase, documentation, or any other relevant files.
npm install
npm run build
npm run test
- Stage the changes you have made:
git add .
- Commit the staged changes with a descriptive message:
git commit -m "Add feature XYZ"
git push origin feature-branch
- Visit your forked repository on GitHub.
- Click on the “New pull request” button next to the branch selection drop-down.
- Select the base branch (usually the main branch of the original repository) and the compare branch (your feature branch).
- Provide a descriptive title and detailed description of your changes in the pull request.
- Click on the “Create pull request” button to submit your pull request for review.
- The maintainers of the original repository will review your pull request.
- Any feedback or changes required will be communicated through comments on the pull request.
- Once the changes are approved, your pull request will be merged into the main repository.
In general, generator can make ~10k records per seconds and use ~80Mb memory for this. That’s mean meta tags generation not be bottleneck with up to 10k RPS. You can recheck in ./benchmark
directory.
Typescript
import { MetadataGenerator } from 'metatags-generator';
Pure Nodejs
const MetadataGenerator = require('metatags-generator');
const settings = {
structuredData: true,
androidChromeIcons: true,
msTags: true,
safariTags: true,
appleTags: true,
openGraphTags: true,
twitterTags: true,
facebookTags: true
};
const generator = new MetadataGenerator();
const preparedData = generator
.configure(settings)
.setRobots('index, follow')
.setShortLink('https://bit.ly/1ahy')
.setLocalVersion('en_US', 'https://example.com', true)
.setAlternateHandheld('https://m.example.com')
.setProjectMeta({
name: 'Example app',
url: 'https://example.com',
logo: '/path/logo.png',
primaryColor: '#333333',
backgroundColor: '#ffffff'
})
.setPageMeta({
title: 'Home',
description: 'This is home page',
url: 'https://example.com',
image: '/path/cover.jpg',
keywords: 'site, app, example, pug',
locale: 'en_US'
})
.openGraphData('video.movie')
.setCanonical('https://example.com')
.breadcrumb(data)
.setIcons(icons)
.setTwitterMeta({
card: 'summary_large_image',
site: '@nytimesbits',
creator: '@nickbilton'
})
.setFacebookMeta(5233)
.build();
Then you can use HTML output for inject in your page.
Install dependencies
npm i express pug metatags-generator
Create files:
index.js
const express = require('express');
const { MetadataGenerator } = require('metatags-generator');
const app = express();
const port = 3000;
app.set('views', `${__dirname}`);
app.set('view engine', 'pug');
const generator = new MetadataGenerator();
const data = [
{ title: 'Home', url: 'https://example.com' },
{ title: 'About', url: 'https://example.com/about' }
];
const icons = ['/path/icon-72x72.png', '/path/icon-180x180.png'];
const preparedData = generator
.setRobots('index')
.setRobots('index, follow')
.setShortLink('https://bit.ly/1ahy')
.setLocalVersion('en_US', 'https://example.com', true)
.setAlternateHandheld('https://m.example.com')
.setProjectMeta({
name: 'Example app',
url: 'https://example.com',
logo: '/path/logo.png',
primaryColor: '#333333',
backgroundColor: '#ffffff'
})
.setPageMeta({
title: 'Home',
description: 'This is home page',
url: 'https://example.com',
image: '/path/cover.jpg',
keywords: 'site, app, example, pug',
locale: 'en_US'
})
.openGraphData('video.movie')
.setCanonical('https://example.com')
.breadcrumb(data)
.setIcons(icons)
.setTwitterMeta({
card: 'summary_large_image',
site: '@nytimesbits',
creator: '@nickbilton'
})
.setFacebookMeta(5233)
.build();
app.get('/', (req, res) => {
res.render('index', { head: preparedData.head, body: preparedData.body });
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
The author
meta tag specifies the author of the web page.
<meta name="author" content="Author's Name">
<meta name="description" content="A concise description of the page">
The color-scheme
meta tag sets the preferred color scheme for the page.
<meta name="color-scheme" content="light dark">
The theme-color
meta tag defines the color of the browser’s UI elements when the page is active.
<meta name="theme-color" content="#f1c2d3">
The referrer
meta tag specifies the referrer policy for the page.
<meta name="referrer" content="no-referrer">
The content-security-policy
meta tag specifies the content security policy for the page.
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
The refresh
meta tag automatically refreshes the page after a specified time interval.
<meta http-equiv="refresh" content="5">
The rel="stylesheet"
link tag links an external stylesheet to the document for styling purposes.
<link rel="stylesheet" href="styles.css">
The rel="canonical"
link tag specifies the canonical URL for the document to avoid duplicate content issues.
<link rel="canonical" href="https://example.com/">
The rel="alternate"
link tag provides alternate versions of the current document in different languages.
<link rel="alternate" hreflang="es" href="alternate-language.html">
The rel="manifest"
link tag specifies the location of the web app’s manifest file.
<link rel="manifest" href="app.webmanifest">
The rel="alternate"
link tag can also be used to specify an RSS feed for the document.
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="rss-feed.xml">
Learn more: MDN rel=”alternate”
Icon-related link tags can be used to specify various icons for the document.
-
Favicon:
<link rel="icon" href="favicon.ico">
-
Apple Touch Icon:
<link rel="apple-touch-icon" href="apple-touch-icon.png">
Load stylesheets conditionally based on media queries.
<link rel="stylesheet" media="(max-width: 600px)" href="mobile.css">
<link rel="stylesheet" media="(min-width: 601px)" href="desktop.css">
Preload resources for improved performance.
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="image.webp" as="image">
Prefetch resources for upcoming navigations.
<link rel="prefetch" href="next-page.html">
Facebook Open Graph tags customize content appearance when shared on social media platforms like Facebook, while Twitter Card tags enhance previews on Twitter.
The type of the content, e.g., “website” or “article”.
<meta property="og:type" content="article">
The URL of the shared content.
<meta property="og:url" content="https://example.com/page">
The title of the shared content.
<meta property="og:title" content="Page Title">
The description of the shared content.
<meta property="og:description" content="Description of the content">
An image to display when the content is shared.
<meta property="og:image" content="image.jpg">
The name of the site or app.
<meta property="og:site_name" content="Site Name">
The locale for the content.
<meta property="og:locale" content="en_US">
The type of Twitter card to use.
<meta name="twitter:card" content="summary">
The Twitter handle of the site’s creator.
<meta name="twitter:site" content="@username">
The Twitter handle of the content creator.
<meta name="twitter:creator" content="@author">
When implementing social media tags, it’s important to note that Twitter Card tags (e.g., twitter:title
, twitter:description
, etc.) are often unnecessary when equivalent Open Graph tags (e.g., og:title
, og:description
, etc.) are present. Twitter will automatically use Open Graph tags as a fallback when generating previews on its platform. Therefore, you can simplify your implementation by focusing on the Open Graph tags and omitting their Twitter Card counterparts. Twitter Card Fallback Behavior