Link Preview

PreviousNext

A component to display a link preview for URLs included in Lens posts, showing the title, description, and image.

Docs
lens-blockscomponent

Preview

Loading preview…
registry/new-york/components/feed/link-preview.tsx
import { useEffect, useState } from "react";
import { UrlMetadata } from "@/registry/new-york/lib/get-meta-from-url";
import getFavicon from "@/registry/new-york/lib/get-favicon";
import { truncateUrl } from "@/registry/new-york/lib/lens-utils";

type Props = {
  url: string;
};

export const LinkPreview = (props: Props) => {
  const { url } = props;

  const [urlMetadata, setUrlMetadata] = useState<UrlMetadata | null>(null);

  const favicon = getFavicon(url);

  useEffect(() => {
    if (!url) return;
    fetch(`/api/url-meta?url=${encodeURIComponent(url)}`)
      .then(r => r.json())
      .then(setUrlMetadata);
  }, [url]);

  if (!urlMetadata) {
    return null;
  }

  return (
    <div onClick={event => event.stopPropagation()}>
      <a
        href={url}
        className="w-full max-w-sm flex flex-col bg-card text-card-foreground border rounded-lg mb-4 cursor-pointer hover:!no-underline"
        target="_blank"
        rel="noopener noreferrer"
      >
        <div className="flex flex-col p-2 flex-1 min-w-0 gap-0.5 overflow-hidden">
          <div className="flex gap-1 items-center text-xs font-normal">
            <img
              src={urlMetadata.icon ?? favicon}
              width={24}
              height={24}
              alt={`${url} favicon`}
              className="w-4 h-4 p-0.5"
            />
            {urlMetadata.siteName && <div className="line-clamp-1 opacity-60">{urlMetadata.siteName + " • "}</div>}
            <div className="flex-none opacity-60">{truncateUrl(urlMetadata.url)}</div>
          </div>
          {urlMetadata.title && <div className="line-clamp-1 !font-bold text-sm">{urlMetadata.title}</div>}
          {urlMetadata.description && (
            <div className="line-clamp-2 text-xs !font-normal">{urlMetadata.description}</div>
          )}
        </div>
      </a>
    </div>
  );
};

Installation

npx shadcn@latest add @lens-blocks/link-preview

Usage

import { LinkPreview } from "@/components/link-preview"
<LinkPreview />