1.0.0-beta • Published 1 year ago

@hyperfov/link-previews v1.0.0-beta

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Link Preview Web Component

This is the frontend portion of the Hyperfov Link Preview library. It provides a function linkPreview that allows you to add a link preview web component to any a tag:

<html>
  <body>
    <!-- page markup here with some a tags: -->
    <a id="myLink" href="https://example.com">A cool link</a>
    <!-- Insert the link preview script at the end of the body -->
    <script src="https://unpkg.com/@hyperfov/link-previews@latest/dist/index.js"></script>
    <script>
      // now we can call `linkPreview` to add a preview
      linkPreview("#myLink", {
        worker: "https://link-to-worker.workers.dev",
      });
    </script>
  </body>
</html>

Install

Make sure you've set up the worker and have it's url.

Install via NPM

npm i @hyperfov/link-previews
import { linkPreview } from "@hyperfov/link-previews";

Install via a CDN

<script src="https://unpkg.com/@hyperfov/link-previews@latest/dist/index.js"></script>

Initialize

Add the script to the end of your site's body.

Create link previews by passing through a selector, element, or list of elements and configuration props to the global linkPreview constructor:

linkPreview("#myLink", {
  worker: "https://link-to-worker.workers.dev",
});

You can also customize the previews' styling. For example:

<style>
  link-preview {
    --lp-border: 1px dashed rebeccapurple;
    --lp-title-color: rebeccapurple;
  }
</style>

For more on styling and custom templates, see custom previews.

Props

You can configure the preview element by passing through props in the constructor:

linkPreview("#myLink", {
  // props get passed through here
});

Valid props:

worker

The URL of the deployed worker. See the worker's docs for deployment information.

template

The selector of the template element used to render the preview. See custom previews for more on templates. If nothing is passed, a default template is used.

fetch

Should the worker be called to get information for this link? Defaults to true. You may want to set this to false if you're pregenerating a page and don't want to make calls to the worker at runtime.

fetchOnHover

Should the link preview content be fetched when the user hovers on the link? Defaults to true. When set to false, the preview content is fetched immediately when the preview component is initialized.

content

The data passed through to the template's slots. This object can include props such as title, description, href, and image:

linkPreview(elt, {
  content: {
    href: "https://example.com/",
    description: "Some interesting description",
    title: "Example link",
  },
});

Note that passing through data in content will override any data that's returned by the worker.

Any of the keys in content can also be specified on the element with attributes prefixed with lp-:

<a
  href="https://example.com/"
  lp-description="Some interesting description"
  lp-title="Example link"
  >example</a
>

tippy

Props that are passed through to tippy.js, the library used for the preview popups. These can allow you to modify the positioning of the preview and provide options such as an offset, delay, and animation:

linkPreview(elt, {
  tippy: {
    placement: "bottom-start",
    animation: "scale",
    offset: [0, 10],
    delay: 200,
  },
});

Find the full list of props on the tippy docs.

All of the props in tippy can also be specified on the element with attributes prefixed with tippy-data-:

<a
  href="https://example.com/"
  data-tippy-placement="bottom-start"
  data-tippy-animation="scale"
  data-tippy-offset="[0, 10]"
  data-tippy-delay="200"
  >example</a
>

Custom previews

Styling

You can style the basic template with CSS variables set in the link-preview selector:

link-preview {
  --lp-title-color: red;
  --lp-link-color: blue;
}

Variables are in the form --lp-[element]-[css property]. Here's all the variables the template accepts:

VariableDefault value
--lp-bordernone
--lp-padding0
--lp-backgroundwhite
--lp-box-shadow0px 5px 15px rgba(101, 101, 110, 0.3)
--lp-border-radius6px
--lp-max-width225px
--lp-font-familyinherit
--lp-font-weightnormal
--lp-link-padding0 10px
--lp-link-colorgrey
--lp-link-bordernone
--lp-link-font-size12px
--lp-link-font-familyinherit
--lp-link-font-weightnormal
--lp-title-padding0 10px 3px 10px
--lp-title-colorinherit
--lp-title-bordernone
--lp-title-font-size16px
--lp-title-font-familyinherit
--lp-title-font-weightbold
--lp-description-padding0 10px 3px 10px
--lp-description-colorinherit
--lp-description-bordernone
--lp-description-font-size16px
--lp-description-font-familyinherit
--lp-description-font-weightnormal
--lp-image-bordernone
--lp-image-border-radius3px 3px 0 0
--lp-image-object-fitcover
--lp-image-object-positioncenter center
--lp-image-max-height150px

Custom templates

For instances where the css variables aren't enough, the link preview is completely customizable through an html template with slots. The template that's used by default can be found at src/templates/basic.js.

Add a custom template to your page (the template element is invisible, so this can be anywhere in the document):

<template id="link-preview-template">
  <style>
    .wrapper {
      padding: 20px;
      background-color: lightsalmon;
    }
  </style>
  <div class="wrapper">
    <slot name="lp-title">my title</slot>
    <div><slot name="lp-description">my description</slot></div>
    <div><slot name="lp-href">my url</slot></div>
  </div>
</template>

The styling and markup is totally up to you, though you must ensure styles are either inline or included in a style tag in the template. The link preview component will look for a slots lp-title, lp-description, lp-url, lp-favicon, and lp-image to insert content. Data that doesn't have corresponding slot in the template won't be displayed, so for example if you don't specify an lp-image slot, no image will be inserted.

Once you've created a template, pass its id as an option when instantiating your link previews:

linkPreview("#myLink", {
  worker: "https://link-to-worker.workers.dev",
  template: "#link-preview-template",
});