{"id":19717665,"url":"https://github.com/haydenbleasel/react-glimpse","last_synced_at":"2025-04-28T10:42:19.181Z","repository":{"id":60470708,"uuid":"541226251","full_name":"haydenbleasel/react-glimpse","owner":"haydenbleasel","description":"Fast, unstyled link preview React component.","archived":false,"fork":false,"pushed_at":"2024-07-12T04:46:02.000Z","size":778,"stargazers_count":57,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-02T14:08:30.038Z","etag":null,"topics":["link","preview","react","tooltip"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haydenbleasel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["haydenbleasel"]}},"created_at":"2022-09-25T15:59:42.000Z","updated_at":"2024-12-28T10:41:53.000Z","dependencies_parsed_at":"2024-07-12T05:46:20.874Z","dependency_job_id":"4505054e-5698-411b-a05d-11aff7ac0c60","html_url":"https://github.com/haydenbleasel/react-glimpse","commit_stats":null,"previous_names":["haydenbleasel/glimpse","haydenbleasel/react-glimpse"],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenbleasel%2Freact-glimpse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenbleasel%2Freact-glimpse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenbleasel%2Freact-glimpse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenbleasel%2Freact-glimpse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haydenbleasel","download_url":"https://codeload.github.com/haydenbleasel/react-glimpse/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233215949,"owners_count":18643025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["link","preview","react","tooltip"],"created_at":"2024-11-11T22:50:10.711Z","updated_at":"2025-01-09T15:46:15.547Z","avatar_url":"https://github.com/haydenbleasel.png","language":"TypeScript","funding_links":["https://github.com/sponsors/haydenbleasel"],"categories":[],"sub_categories":[],"readme":"# Glimpse\n\nGlimpse is a fast, unstyled link preview React component. It uses a combination of server-side and client-side rendering to provide an interactive preview of a link. The server-side component fetches the link's metadata while the client-side component creates a local cache and renders the preview.\n\n![Example of Glimpse](/example.png)\n\n## Installation\n\n```bash\nyarn add react-glimpse\n```\n\n## Usage\n\n### Server\n\nHere's an example of the server code using Next.js' [Edge API Routes](https://nextjs.org/docs/api-routes/edge-api-routes):\n\n```ts\nimport type { NextRequest } from 'next/server';\nimport glimpse from 'react-glimpse/server';\n\nconst headers = {\n  'content-type': 'application/json',\n};\n\nexport const config = {\n  runtime: 'experimental-edge',\n};\n\nconst handler = async (req: NextRequest): Promise\u003cResponse\u003e =\u003e {\n  const { url } = (await req.json()) as { url?: string };\n\n  if (!url) {\n    return new Response(JSON.stringify({}), { status: 400, headers });\n  }\n\n  try {\n    const data = await glimpse(url);\n\n    return new Response(JSON.stringify(data), { status: 200, headers });\n  } catch () {\n    return new Response(JSON.stringify({}), { status: 500, headers });\n  }\n};\n\nexport default handler;\n```\n\n### Client\n\nHere's an example of the client code using Next.js' Link component:\n\n```tsx\n'use client';\n\nimport type { FC } from 'react';\nimport { Glimpse, useGlimpse } from 'react-glimpse/client';\nimport { ArrowUpRight } from 'lucide-react';\nimport Image from 'next/image';\n\nconst fetcher = async (url: string) =\u003e {\n  const response = await fetch('/api/glimpse', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({\n      url,\n    }),\n  });\n\n  return response.json();\n};\n\nconst LinkPreview: FC = () =\u003e {\n  const data = useGlimpse(fetcher);\n\n  if (!data?.image) {\n    return null;\n  }\n\n  return (\n    \u003cGlimpse className=\"pointer-events-none fixed z-20 flex w-[316px] translate-x-2 translate-y-2 flex-col rounded-lg bg-zinc-900/90 p-3 shadow-lg backdrop-blur-md transition-opacity group-hover:-translate-y-2 dark:bg-zinc-800 print:hidden\"\u003e\n      \u003cImage\n        className=\"m-0 h-[174px] w-full rounded-sm object-cover\"\n        src={data.image}\n        width={316}\n        height={174}\n        alt=\"\"\n        unoptimized\n      /\u003e\n      \u003cp\n        className={`text-md mt-2 block font-medium leading-normal text-white ${\n          data.description ? 'line-clamp-1' : 'line-clamp-3'\n        }`}\n      \u003e\n        {data.title}\n      \u003c/p\u003e\n      \u003cp className=\"line-clamp-2 block text-sm leading-normal text-zinc-300\"\u003e\n        {data.description}\n      \u003c/p\u003e\n      \u003cspan className=\"flex items-center gap-1\"\u003e\n        \u003cp className=\"line-clamp-1 block text-sm leading-normal text-zinc-400\"\u003e\n          {data.url}\n        \u003c/p\u003e\n        \u003cArrowUpRight width={12} height={12} className=\"text-zinc-400\" /\u003e\n      \u003c/span\u003e\n    \u003c/Glimpse\u003e\n  );\n};\n\nexport default LinkPreview;\n```\n\nThen you can just import the `LinkPreview` component into your higher-level component with:\n\n```tsx\n\u003cLinkPreview /\u003e\n```\n\n## Styling\n\nGlimpse is unstyled by default. You can style it using the `className` prop on the `Glimpse` component.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaydenbleasel%2Freact-glimpse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaydenbleasel%2Freact-glimpse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaydenbleasel%2Freact-glimpse/lists"}