Link previewer in Next.js
7/9/2023, Published in Medium, DevTo and HashNode
Write API route in nextjs for getting the link preview
import mql from "@microlink/mql";
export default async function handler(req, res) {
try {
let { url } = req.query;
const { data } = await mql(url, {
screenshot: true,
// apiKey: process.env.NEXT_MICROLINK_API_KEY,
// @ts-ignore
overlay: {
background:
"linear-gradient(225deg, #8ef472 0%, #4267ec 50%, #26F0C0 100%)",
browser: "dark",
},
});
res.status(200).json({
image: data?.screenshot?.url,
});
} catch (error) {
res.status(500).json({
error: JSON.stringify(error),
});
}
}
Now, create the Link Previewer component.
import React, { useCallback, useEffect } from "react";
import Image from "next/image";
import Link from "next/link";
type Props = {
children: any;
href: string;
};
export default function LinkPreview({ children, href }: Props) {
let [imagePreview, setImagePreview] = React.useState("");
let [isHovering, setIsHovering] = React.useState(false);
let inLink = false;
let handleMouseEnterLink = () => {
inLink = true;
setIsHovering(true);
};
let handleMouseLeaveLink = () => {
inLink = false;
setIsHovering(false);
};
let handleFetchImage = useCallback(async (url: string) => {
const res = await fetch(`/api/link-preview?url=${url}`);
const data = await res.json();
setImagePreview(data.image);
}, []);
useEffect(() => {
handleFetchImage(href);
}, []);
return (
<span>
<span className="relative z-10 hidden md:inline-block">
{/* Link itself */}
<Link
href={href}
className={`${isHovering && "underline"}`}
onMouseEnter={handleMouseEnterLink}
onMouseLeave={handleMouseLeaveLink}
onFocus={handleMouseEnterLink}
onBlur={handleMouseLeaveLink}
>
{children}
</Link>
{/* Image Preview */}
{isHovering && (
<Link href={href} passHref>
<span className="w-56 h-44 absolute top-[-255px] left-1/2 transform -translate-x-[7rem] translate-y-8 flex items-start justify-center">
{imagePreview ? (
<Image
fill
className="object-cover object-top w-56 h-40 bg-white rounded-md shadow-lg hover:ring-4 hover:ring-emerald-400"
src={imagePreview}
alt={children}
/>
) : (
<span className="flex items-center justify-center w-56 h-40 bg-white rounded-md shadow-lg">
Loading...
</span>
)}
</span>
</Link>
)}
</span>
{/* For mobile devices */}
<a href={href} className={`${isHovering && "underline"} md:hidden`}>
{children}
</a>
</span>
);
}
Sandeep Yaramchitti
- Bringing my ideas into life through Code.
ALL SYSTEMS ONLINE