Create Beautiful Link Previews Using Vuejs and Tailwindcss

Create Beautiful Link Previews Using Vuejs and Tailwindcss

Mar 25, 2022 4:00 PM (a month ago)

Link Preview

Today I'll walk you through how I created dynamic link previews like linked-in or twitter like the one bellow 👇

<UrlPreview url="https://twitter.com/nagiworks" />

# Design the layout

Twitter link preview looks simple and appealing to me, so in this part I'll try to make something like it

Twitter Link Preview

# Sketch something quick on play.tailwindcss.com

When prototyping on a design idea I prefere to sketch something quick using tailwindcss's official playground (opens new window)

Sketch Preview

			<div class="relative w-full mx-auto overflow-hidden bg-gray-200 rounded-md shadow sm:max-w-lg ring-1">
				<div class="flex flex-col space-y-2">
					<a href="#" class="w-full">
                        <img
                            class="object-cover w-full h-60"
                            src="https://opengraph.githubassets.com/97458523a208a357ce6682e4e0d609c409b7250d348cff3d774716d54fa4edfe/LeonardoCardoso/Facebook-Link-Preview"
                            alt="Preview" />
                    </a>

					<div class="flex flex-col p-3 space-y-1">
						<a href="#" class="m-0 text-lg leading-tight text-gray-900 no-underline hover:no-underline hover:text-gray-900 sm:text-xl">LeonardoCardoso/Facebook-Link-Preview</a>
						<p class="text-gray-500">github.com</p>
						<p class="text-sm">
                        Example Description here
                        </p>
					</div>
				</div>
			</div>

# Functionality

That's great design now we need to way to extract the metadata (title, description, image) from the url and for this I'm using a npm package called vue-link-preview (opens new window).

Under the hood it uses express server heroku that will receive the link and parse the metadata out of it. This package also validate the url for you and have some options you can view it's documentation on github (opens new window)

# Create wrapping component

Generally I stick to create a wrapping component for most of the "packaged" componets.

<template>
	<vue-link-preview dir="ltr" class="my-5" :url="url">
		<template v-slot:default="preview">
			<!-- Tailwindcss component goes here -->
		</template>
	</vue-link-preview>
</template>

<script>
	import VueLinkPreview from '@ashwamegh/vue-link-preview';

	export default {
		name: 'UrlPreview',
		components: {
			VueLinkPreview,
		},
		props: {
			url: {
				type: String,
				required: true,
			},
		},
		methods: {
            // helper function to limit excessive description
			limit(string, length) {
				return string.length > length ? string.substring(0, length) + '...' : string;
			},
		},
	};
</script>

# Full code snippet

<template>
	<vue-link-preview dir="ltr" class="my-5" :url="url">
		<template v-slot:default="preview">
			<div class="relative w-full mx-auto overflow-hidden rounded-md shadow bg-secondary sm:max-w-lg ring-1">
				<div class="flex flex-col space-y-2">
					<a :href="url" class="w-full"><img class="object-cover w-full h-60" :src="preview.img" :alt="preview.title" /></a>

					<div class="flex flex-col p-3 space-y-1">
						<a :href="url" class="m-0 text-lg leading-tight no-underline text-primary hover:no-underline hover:text-primary sm:text-xl">{{ limit(preview.title, 100) }}</a>
						<p class="text-gray-500">{{ preview.domain }}</p>
						<p v-text="limit(preview.description, 245)" class="text-sm"></p>
					</div>
				</div>
			</div>
		</template>
	</vue-link-preview>
</template>

<script>
	import VueLinkPreview from '@ashwamegh/vue-link-preview';

	export default {
		name: 'UrlPreview',
		components: {
			VueLinkPreview,
		},
		props: {
			url: {
				type: String,
				required: true,
			},
		},
		methods: {
			limit(string, length) {
				return string.length > length ? string.substring(0, length) + '...' : string;
			},
		},
	};
</script>

My Newsletter

I send out an email every so often about cool stuff I'm working on or launching. If you dig, go ahead and sign up!

No spam, only goldden nuggets 💎

Comments

Ahmed Nagi - Powerd By Vuepress . Hosted with GitHub and Netlify .