frontend-shorts-how-to-create-link-content-previewer-with-react-vue-and-vanilla-javascript-1pm1

Original address: https://dev.to/ilonacodes/frontend-shorts-how-to-create-link-content-previewer-with-react-vue-and-vanilla-javascript-1pm1

Link Content Previewer

Not only do I love blogging, I love reading blogs too! Traditionally, when bloggers mention some science-based fact or quote another post, they have to add a link to the source.

For the reader, the question is, is it worth stopping to read the post and switching to the reading source?

Because along with the post, we may have up to 10 links from different sources. So which ones can we skip?

That’s why now, link content previewer is a must-have feature for blogs and even chats. You’ve seen them on Facebook, LinkedIn, Twitter, WhatsApp, etc.

The main benefit of a link content previewer is that readers can have an idea of what they will read later before following the link.

Typically, a link content previewer contains the domain name (URL), title, text, and image. You can also create a more informative linked content previewer by providing more data for its content.

In this article I will show you

How to quickly develop a link content previewer feature for your blog using React, Vue, and pure JavaScript.

From simple to complex concepts, let’s start with a pure JavaScript implementation:

// index.js
const card = document.querySelector(".card");

const hideLinkPreview = () => {<!-- -->
  return card.style.display = 'none';
};

const showLinkPreview = event => {<!-- -->
  const image = event.currentTarget.getAttribute("data-image");
  card.querySelector('img').setAttribute("src", image);

  const title = event.currentTarget.getAttribute("data-title");
  card.querySelector('h5').textContent = title;

  const text = event.currentTarget.getAttribute("data-text");
  card.querySelector('p').textContent = text;

  event.currentTarget.appendChild(card);

  return card.style.display = 'inline-block';
};

document.querySelectorAll(".link-with-preview").forEach(el => {<!-- -->
  el.addEventListener("mouseover", showLinkPreview);
  el.addEventListener("mouseleave", hideLinkPreview)
});

First, add direct text content to
index.html:

<!--index.html-->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Link Content Previewer</title>
</head>
<body>
<div class="wrapper">
<p>Hi there! </p>
<p>I would like to share some frontend tips and tricks that
I have already applied to some of my projects.</p>
<p>Happily coming back with <br/> my
<a href="https://dev.to/ilonacodes/frontend-shorts-vue-js-vanilla-js-digital-dices-og"
class="link-with-preview"
>
frontend shorts
</a>
series on
<a href="https://dev.to"
class="link-with-preview"
>
dev.to.
</a>
Let me show you how...
</p>
</div>
</body>
</html>

Next, you need a
card element, which will contain and preview the information of the reference source:

<!--index.html-->
...
<div class="card">
<img src="" class="card-img-top">
<div class="card-body">
<h5 class="card-title"></h5>
<p class="card-text"></p>
</div>
</div>

So far you can see that I’ve used
Bootstrap 4 and custom CSS classes to style the card. They should also be in
Import in head:

<!--index.html-->
...
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="index.css">
...

Thanks to the power of Bootstrap 4, the positioning of elements and some basic styles are automatically applied to the library. therefore,
The index.css file is not very large, so you can find all the styles you need for the link content previewer functionality below:

/*index.css*/
body {<!-- -->
  font-size: 24px;
}

.wrapper {<!-- -->
  width: 500px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  position: absolute;
}

.card {<!-- -->
  width: 150px;
  display: none;
  font-size: 10px;
  color: black;
  position: absolute;
  z-index: 100;
  bottom: 30px;
  left: 50%;
  transform: translateX(-50%);
}

.link-with-preview {<!-- -->
  position: relative;
}

.card img {<!-- -->
  width: 150px;
}

.card-title {<!-- -->
  font-size: 14px;
}

To make the Linked Content Previewer work, we have to write JavaScript code. Hope you didn’t forget to add the script to
At the end of body in index.html:

<!--index.html-->
...
<script src="index.js"></script>

Get ready to start coding in JavaScript:

// index.js
const card = document.querySelector(".card");

const hideLinkPreview = () => {<!-- -->
  return card.style.display = 'none';
};

const showLinkPreview = event => {<!-- -->
  const image = event.currentTarget.getAttribute("data-image");
  card.querySelector('img').setAttribute("src", image);

  const title = event.currentTarget.getAttribute("data-title");
  card.querySelector('h5').textContent = title;

  const text = event.currentTarget.getAttribute("data-text");
  card.querySelector('p').textContent = text;

  event.currentTarget.appendChild(card);

  return card.style.display = 'inline-block';
};

document.querySelectorAll(".link-with-preview").forEach(el => {<!-- -->
  el.addEventListener("mouseover", showLinkPreview);
  el.addEventListener("mouseleave", hideLinkPreview)
});

statement
card and implements two functions hideLinkPreview(event) and showLinkPreview(event), and the event is event. In our case it’s the onmouseover and onmouseleave events for links.

The hideLinkPreview(event) function is very simple. It just hides the content preview (a card) on mouse away event.

For the showLinkPreview(event) function, it is important to obtain data-image, data-title< from the link /code> and data-text attributes, set them to the card instance to display and preview the content of the referenced resource on hover events.

event.currentTarget.appendChild(card) helps us to append the card to the linked content previewer and position/center the card appropriately.

Pass all required data to index.html to preview non-empty cards in the browser on hover:

<!--index.html-->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Link Content Previewer</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="wrapper">
<p>Hi there! </p>
<p>I would like to share some frontend tips and tricks that
I have already applied to some of my projects.</p>
<p>Happily coming back with <br/> my
<a href="https://dev.to/ilonacodes/frontend-shorts-vue-js-vanilla-js-digital-dices-og"
onmouseover="showLinkPreview()"
onmouseleave="hideLinkPreview()"
class="link-with-preview"
data-image="https://dev-to-uploads.s3.amazonaws.com/i/3zp478dfafzy1mgfaevn.jpg"
data-title="Frontend Shorts: Vue.js + Vanilla.js - Digital Dices"
data-text="Let me show you how you can implement a dice-rolling simulator in less than 30 minutes of your time on the front-end."
>frontend shorts</a>
series on
<a href="https://dev.to"
onmouseover="showLinkPreview()"
onmouseleave="hideLinkPreview()"
class="link-with-preview"
data-image="https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png"
data-title="DEV Community "
data-text="Where programmers share ideas and help each other grow-A constructive and inclusive social network."
>
dev.to.
</a>
Let me show you how...
</p>
</div>
<div class="card">
<img src="" class="card-img-top">
<div class="card-body">
<h5 class="card-title"></h5>
<p class="card-text"></p>
</div>
</div>
<script src="index.js"></script>
</body>
</html>

The complete source code of the VanillaJS implementation can be found here:

<!--index.html-->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Link Content Previewer</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="wrapper">
<p>Hi there! </p>
<p>I would like to share some frontend tips and tricks that
I have already applied to some of my projects.</p>
<p>Happily coming back with <br/> my
<a href="https://dev.to/ilonacodes/frontend-shorts-vue-js-vanilla-js-digital-dices-og"
onmouseover="showLinkPreview()"
onmouseleave="hideLinkPreview()"
class="link-with-preview"
data-image="https://dev-to-uploads.s3.amazonaws.com/i/3zp478dfafzy1mgfaevn.jpg"
data-title="Frontend Shorts: Vue.js + Vanilla.js - Digital Dices"
data-text="Let me show you how you can implement a dice-rolling simulator in less than 30 minutes of your time on the front-end."
>frontend shorts</a>
series on
<a href="https://dev.to"
onmouseover="showLinkPreview()"
onmouseleave="hideLinkPreview()"
class="link-with-preview"
data-image="https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png"
data-title="DEV Community "
data-text="Where programmers share ideas and help each other grow-A constructive and inclusive social network."
>
dev.to.
</a>
Let me show you how...
</p>
</div>
<div class="card">
<img src="" class="card-img-top">
<div class="card-body">
<h5 class="card-title"></h5>
<p class="card-text"></p>
</div>
</div>
<script src="index.js"></script>
</body>
</html>

Click me to view the complete Vue.js implementation code.

Part 2: Link content preview using Vue.js

As you might guess, index.html and index.css are the same as index.html and index.css< implemented via VanillaJS /code> Almost the same:

<div id="app">
<div class="wrapper">
<p>Hi there! </p>
<p>I would like to share some frontend tips and tricks that
I have already applied to some of my projects.</p>
<p>Happily coming back with <br/> my
<link-previewer
href="https://dev.to/ilonacodes/frontend-shorts-vue-js-vanilla-js-digital-dices-og"
text="frontend shorts"
preview-img="https://dev-to-uploads.s3.amazonaws.com/i/3zp478dfafzy1mgfaevn.jpg"
preview-title="Frontend Shorts: Vue.js + Vanilla.js - Digital Dices"
preview-text="Let me show you how you can implement a dice-rolling simulator in less than 30 minutes of your time on the front-end."
></link-previewer>
series on
<link-previewer
href="https://dev.to"
text="dev.to."
preview-img="https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png"
preview-title="DEV Community ?"
preview-text="Where programmers share ideas and help each other grow-A constructive and inclusive social network."
></link-previewer>
Let me show you how...
</p>
</div>
</div>

To use the Vue.js framework, you need to add the Vue.js script:

<!--index.html-->
...
<script src="//i2.wp.com/cdn.jsdelivr.net/npm/[email protected]"></script>

According to index.html, we are still missing the link-previewer component with the corresponding attributes:

href, text, previewTitle, previewImg and previewText. Let's create this link-previewer component in index.html:

...
<script>
Vue.component('link-previewer', {<!-- -->
props: ['href', 'text', 'previewTitle', 'previewImg', 'previewText'],
data() {<!-- -->
return {<!-- -->
shown: false
};
},
methods: {<!-- -->
show() {<!-- -->
this.show = true;
},
hide() {<!-- -->
this.show = false;
}
},
// this enables proper syntax highlighting and auto-completion in the IDE for the HTML code snippet below:
//language=HTML
template: `
<a v-bind:href="href"
v-on:mouseover="show"
v-on:mouseleave="hide"
class="link-with-preview"
>
{<!-- -->{ text }}
<div class="card"
v-bind:class="{'card-show': shown}">
<img v-bind:src="previewImg" alt=""
class="card-img-top">
<div class="card-body">
<h5 class="card-title">{<!-- -->{ previewTitle }}</h5>
<div class="card-text">
{<!-- -->{ previewText }}
</div>
</div>
</div>
</a>
`
});
const app = new Vue({<!-- -->
el: '#app'
});
</script>

The only data passed to link-previewer`` is shown: falseChanging the state of this component in data() depends on show () and hide()``` method calls.

In the case of Vue.js implementation, build the card component with the required properties in the form of a template.

Data is passed from link-previewer to card via v-bind and events via v-on.

Click here to view the complete solution implemented in Vue.js.

Part 3: Link content preview using React.js

The HTML structure of the App.js component is almost the same as the index.html implemented in VanillaJS:

//App.js
import React from "react";
import "./styles.css";
import {<!-- --> LinkPreviewer } from "./LinkPreviewer";
export default function App() {<!-- -->
return (
<div className="App">
<div>
<p>Hi there! </p>
<p>
I would like to share some frontend tips and tricks that I have
already applied to some of my projects.
</p>
<p>
Happily coming back with <br /> my
<LinkPreviewer
href="https://dev.to/ilonacodes/frontend-shorts-vue-js-vanilla-js-digital-dices-og"
image="https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png"
title="Frontend Shorts: Vue.js + Vanilla.js - Digital Dices"
text="Let me show you how you can implement a dice-rolling simulator in less than 30 minutes of your time on the front-end."
>
frontend shorts
</LinkPreviewer>
series on
<LinkPreviewer
href="https://dev.to"
image="https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png"
title="DEV Community"
text="Where programmers share ideas and help each other grow-A constructive and inclusive social network."
>
dev.to
</LinkPreviewer>
</p>
</div>
</div>
);
}

The only difference is that we need to create the LinkPreviewer component and use it to render the correct data for the link content preview:

// LinkPreviewer
import React, {<!-- --> useState } from "react";
import "./styles.css";
export const LinkPreviewer = props => {<!-- -->
const [isShown, setIsShown] = useState(false);
return (
<a
href={<!-- -->props.href}
className="link-with-preview"
onMouseEnter={<!-- -->() => setIsShown(true)}
onMouseLeave={<!-- -->() => setIsShown(false)}
>
<span> {<!-- -->props.children} </span>
{<!-- -->isShown & amp; & amp; (
<Card image={<!-- -->props.image} title={<!-- -->props.title} text={<!-- -->props.text} />
)}
</a>
);
};
const Card = props => {<!-- -->
return (
<div className="card">
<img src={<!-- -->props.image} className="card-img-top" alt="" />
<div className="card-body">
<h5 className="card-title">{<!-- -->props.title}</h5>
<p className="card-text">{<!-- -->props.text}</p>
</div>
</div>
);
};

LinkPreviewer will return a containing the required properties, events, and style classes for the content preview feature to render correctly in the browser.

When isShown is true, the Card component renders the image, title, and text referencing the source.

Due to the use of React hook const [isShown, setIsShown] = useState(false), it is easy to handle LinkPrevieweronMouseEnter and onMouseLeave events Hide and show link content previewer for /code>.

The Card component renders a content preview of the linked source's image, title, and text.

Thanks to the React hook const [isShown, setIsShown] = useState(false), mouse entry and exit events on LinkPreviewer are easily handled to hide and show the link content previewer.

The CSS class is the same as index.css implemented by VanillaJS.

Click here to view the code containing the React implementation.

in conclusion

As you can see, creating a linked content previewer feature is very simple, no matter which JavaScript framework or library you will use. Because no implementation will be too different from other implementations. The method is the same.

If you are a developer or a tech-savvy person with your own blog, then you will not need to rely on third-party libraries to have such functionality. You can develop it yourself.

Thank you for reading!

I hope you'll find this little front-end trick useful and help me spread the word around the internet, for example via Twitter.

come on!
Ilona Codes.

Image by Matteo Catanese on Unsplash

syntaxbug.com © 2021 All Rights Reserved.