Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Renders a preview of a URL based on extracted metadata


apostrophe-link-preview-widgets lets you paste a link to an external URL and have scraped meta data returned to a template. You can customize that template and use it to display a preview of the external website within your Apostrophe site. All previews are AJAXed in after page load and the module leverages apostrophe-caches for fastest delivery.


By default, the widget scrapes the given website and returns an object of all <meta> key/values in the site's <head> as well as any information that is part of microdata spec.

Example response object

Your template will receive an object that could look like:

  status: 'ok',
  body: '<div class="apos-link-preview-widgets"> ...', // HTML blob that replaces loading interface
  data: {
    metaTags: {
      ogDescription: 'It may be hard to imagine liking an airline enough to buy its old silverware and service carts, but at a monthly sale, lovers of Delta Air Lines snap up decommissioned items.',
      ogImage: '',
      ogTitle: 'Stocking Up at an Airline’s Garage Sale',
      ogType: 'article',
      ogUrl: '',
      twitterCard: 'summary_large_image',
      twitterImage: '',
      twitterImageAlt: 'From left, Alex Lee and Anthony Segreto check out an old issue of the Delta Digest.',
      twitterTitle: 'Stocking Up at an Airline’s Garage Sale',
      twitterUrl: ''
    '': [
        name: ""
        properties: {
          articleBody: 'ImageAviation enthusiast Bill McDaniel with two of the items he ...' // full article body
          articleSection: 'Travel',
          author: 'By Jackie Snow'

Adding your own scrapers

At project level configuration you can specifiy additional scraping methods to employ on the returned document.

// ... in app.js / lib/modules/apostrophe-link-preview-widgets/index.js
'apostrophe-link-preview-widgets': {
  addScrapers: [
      name: 'headings',
      // scraper function is passed a cheerio object ($) that can be traversed using jQuery syntax.
      // it also includes a text blob of the response (body) if you want to parse it another way.
      scraper: function ($, body) {
        const data = {
          h1: [],
          h2: []
        $('h1').each(function () {

        $('h2').each(function () {

        return data;

Your /views/indexAjax.html's data object would now include a property headings with corresponding h1 and h2 arrays with those text values

Removing default scrapers

Not going to need data? Save yourself the parsing

// ... in app.js / lib/modules/apostrophe-link-preview-widgets/index.js
'apostrophe-link-preview-widgets': {
  removeScrapers: ['']


A widget that renders a preview of a URL



Code of conduct

Security policy





No packages published