Skip to content

Fix TikTok link preview (use video thumbnail)#3451

Open
bikalsiwakoti wants to merge 1 commit intodubinc:mainfrom
bikalsiwakoti:fix/tiktok-preview
Open

Fix TikTok link preview (use video thumbnail)#3451
bikalsiwakoti wants to merge 1 commit intodubinc:mainfrom
bikalsiwakoti:fix/tiktok-preview

Conversation

@bikalsiwakoti
Copy link

@bikalsiwakoti bikalsiwakoti commented Feb 10, 2026

Fixes: #425

Issue
TikTok links showed favicon or no image instead of the video thumbnail.

Before :-
Screenshot 2026-02-10 231045

For a TikTok short URL, ogImage / twitterImage / icon were undefined and finalImage was null.

What I did
For TikTok URLs only: follow short-link redirects, ignore favicon as preview, and use TikTok’s oEmbed API to get the video thumbnail when the page has no image. Other sites unchanged.
Testing
TikTok short and full video URLs show the thumbnail; other links (e.g. dub.co) behave as before.

After fixes:-
Screenshot 2026-02-10 232901

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved TikTok link handling with enhanced URL resolution
    • Enhanced thumbnail and image extraction for TikTok content previews
    • Strengthened fallback mechanisms for metadata generation

@vercel
Copy link
Contributor

vercel bot commented Feb 10, 2026

@bikalsiwakoti is attempting to deploy a commit to the Dub Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

📝 Walkthrough

Walkthrough

Enhanced the metatags API to handle TikTok links by detecting short links, following redirects to resolve final URLs, and prioritizing TikTok oEmbed thumbnails over favicons when extracting image metadata for link previews.

Changes

Cohort / File(s) Summary
TikTok Metatag Processing
apps/web/app/api/links/metatags/utils.ts
Added isTikTokShortLink and isTikTokVideoPage validators. Modified getMetaTags to resolve TikTok short link redirects, compute a context-aware imageUrl, reject favicon-like images for TikTok, fetch oEmbed thumbnails as fallback, and return metadata using the resolved image URL instead of the raw input.

Sequence Diagram

sequenceDiagram
    participant Client
    participant getMetaTags as getMetaTags()
    participant Fetch as Fetch & Redirect
    participant TikTok as TikTok oEmbed
    participant Meta as Metadata Return

    Client->>getMetaTags: Request metadata for URL
    alt TikTok Short Link Detected
        getMetaTags->>Fetch: fetchWithTimeout(url, redirect: follow)
        Fetch-->>getMetaTags: Resolved final URL
        getMetaTags->>getMetaTags: Extract image from HTML
        alt Image is favicon-like
            getMetaTags->>TikTok: Fetch oEmbed thumbnail
            TikTok-->>getMetaTags: Video thumbnail
        else Image is valid
            getMetaTags->>getMetaTags: Use extracted image
        end
    else Non-TikTok URL
        getMetaTags->>getMetaTags: Use standard image extraction
    end
    getMetaTags->>Meta: Return metadata with final imageUrl
    Meta-->>Client: Link preview data
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A TikTok hop and redirect too,
No more favicons in our preview queue,
The thumbnail shines where it's due,
Short links resolved through and through! 📹✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: fixing TikTok link previews by using video thumbnails instead of favicons.
Linked Issues check ✅ Passed The code changes directly address all requirements from issue #425: following TikTok short-link redirects, rejecting favicons, and fetching video thumbnails via TikTok's oEmbed API.
Out of Scope Changes check ✅ Passed All changes are narrowly scoped to TikTok URL handling within the metatags utility and preserve existing behavior for non-TikTok sites as required.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
apps/web/app/api/links/metatags/utils.ts (2)

124-132: Double fetch for TikTok short links — response body leaked and URL fetched twice.

Two concerns:

  1. Redundant request: The redirect-resolving fetch (line 127) downloads the full TikTok page body only to discard it. Then getHtml(fetchUrl) on line 132 fetches the same resolved URL again. This doubles latency and bandwidth for every TikTok short link.

  2. Unconsumed response body: The Response from line 127 is never consumed (res.text(), res.json()) or cancelled (res.body?.cancel()). In Node.js/undici this can delay connection release back to the pool.

Consider refactoring to reuse the response body from the redirect-resolving fetch:

♻️ Proposed refactor — resolve URL and get HTML in one fetch
-  let fetchUrl = url;
-  if (isTikTokShortLink(url)) {
-    try {
-      const res = await fetchWithTimeout(url, { redirect: "follow" });
-      if (res.url) fetchUrl = res.url;
-    } catch {}
-  }
-
-  const html = await getHtml(fetchUrl);
+  let fetchUrl = url;
+  let html: string | null = null;
+
+  if (isTikTokShortLink(url)) {
+    try {
+      const res = await fetchWithTimeout(url, { redirect: "follow" });
+      if (res.url) fetchUrl = res.url;
+      if (res.ok) {
+        const text = await res.text();
+        // Check for Cloudflare challenge
+        if (
+          !text.includes("challenge-platform") &&
+          !text.includes("cf-browser-verification")
+        ) {
+          html = text;
+        }
+      }
+    } catch {
+      // Fall through to normal getHtml path
+    }
+  }
+
+  if (!html) {
+    html = await getHtml(fetchUrl);
+  }

129-129: Silent catch {} blocks hinder debugging.

Both the redirect-resolution (line 129) and oEmbed fetch (line 188) silently swallow all errors. The fallback behavior is fine, but a console.warn would help diagnose production failures (e.g., TikTok rate-limiting, DNS issues, timeouts).

💡 Add minimal logging

Line 129:

-    } catch {}
+    } catch (e) {
+      console.warn(`Failed to resolve TikTok short link: ${url}`, e);
+    }

Line 188:

-      } catch {}
+      } catch (e) {
+        console.warn(`Failed to fetch TikTok oEmbed for: ${fetchUrl}`, e);
+      }

Also applies to: 188-188

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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 and usage tips.

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.

Metatags - Edge case: TikTok's video preview ignored

1 participant