Skip to content

refactor(link-preview): split the 747-line hook into lib/link-preview modules - #380

Merged
PastaPastaPasta merged 2 commits into
stagingfrom
refactor/link-preview-split
Sep 7, 2026
Merged

refactor(link-preview): split the 747-line hook into lib/link-preview modules#380
PastaPastaPasta merged 2 commits into
stagingfrom
refactor/link-preview-split

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Owner

Summary

hooks/use-link-preview.ts was six things in one file. It is now:

  • lib/link-preview/urls.ts: YouTube id, Yappr post id, direct-image and skip detection, extractFirstUrl / stripTrailingPunctuation. Pure; Vitest spec alongside (15 cases).
  • lib/link-preview/parse-html.ts: Open Graph / Twitter / <title> extraction. Per-tag regex lists are generated from the tag name instead of copied out by hand.
  • lib/link-preview/fetch.ts: the proxy / direct / IPFS-gateway fetch layer, with CORS_PROXY_INFO next to the proxy list it documents. One timeout wrapper and one first-success loop replace the three hand-rolled copies.
  • lib/link-preview/preview.ts: builds the preview, owns the module cache and in-flight dedupe, never rejects.
  • lib/link-preview/types.ts: LinkPreviewData (was declared in the presentational component).
  • hooks/use-link-preview.ts: the React hook, 66 lines.

Consumers (post-content, link-preview, blocknote-schema, use-yappr-post-reference, settings) import the helpers from lib rather than from a hook.

Behaviour preserved: meta-tag precedence, 8s timeout, 5 MB cap, gateway then proxy order, direct-fetch allow list, resolvedUrl for ipfs://, and the basic-preview fallback on any failure.

Part of the anti-slop cleanup series (after #370#379).

Test plan

  • npm run lint (zero warnings), tsc --noEmit, npm run test (110 specs incl. 15 new), npx knip, npm run build all green locally
  • CI
  • Manual: a post with a YouTube link, an image link, an ipfs:// link and an ordinary page; the "learn more" privacy modal on a preview; the proxy list in Settings

🤖 Generated with Claude Code

… modules

hooks/use-link-preview.ts held URL recognition, an HTML meta parser, the proxy/IPFS fetch layer, the preview builder and its cache, two text helpers and the React hook. Each is now its own module under lib/link-preview: urls (pure, with a Vitest spec), parse-html, fetch (owns CORS_PROXY_INFO next to the proxy list it describes), preview (cache + dedupe), types. The hook is 66 lines and consumers import the helpers from lib, not from a hook.

Behaviour kept: the same meta-tag precedence, timeouts, size cap, gateway/proxy order, direct-fetch allow list, and the never-rejecting preview fallback. The parser's regexes are generated from the tag name instead of listed out per tag, and the fetch layer has one timeout wrapper and one first-success loop instead of three copies.
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 99ff5f16-942d-4e44-abdd-e61ec9e8c04f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying yappr with  Cloudflare Pages  Cloudflare Pages

Latest commit: fc35ae8
Status: ✅  Deploy successful!
Preview URL: https://5ed6aaf3.yappr.pages.dev
Branch Preview URL: https://refactor-link-preview-split.yappr.pages.dev

View logs

shouldSkipPreview uses the shared case-insensitive isIpfsProtocol like fetch.ts does. firstSuccessful loses its dead all-failed message and generic (every error is swallowed into the basic preview anyway); basicPreview absorbs its one-caller helper; the hook hoists its repeated error reset; the public entry is getLinkPreview to sit beside getCachedPreview rather than beside the low-level fetcher; module docs sit above imports in all four files.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying yappr-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7e25dc4
Status:⚡️  Build in progress...

View logs

@PastaPastaPasta
PastaPastaPasta merged commit 9748925 into staging Sep 7, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant