"use client"; import { useMemo, useState } from 'react'; import { LinkedInContainer } from './embed-container'; import { LinkedinIcon } from '../icons-v2-generated/brand-logos/linkedin-icon'; import { ExternalLink } from 'lucide-react'; /** * Derive LinkedIn's official embed URL from any post URL or URN. * LinkedIn renders public posts at /embed/feed/update/. Returns '' when no * URN can be derived, so the component falls back to a link instead of a broken * (X-Frame-blocked) iframe. */ function toLinkedInEmbedUrl(url: string): string { if (!url) return ''; if (url.includes('linkedin.com/embed/')) return url.split('?')[0]; let m = url.match(/urn:li:(activity|share|ugcPost):(\d+)/i); if (m) return `https://www.linkedin.com/embed/feed/update/urn:li:${m[1]}:${m[2]}`; m = url.match(/activity[-:](\d{15,25})/i); if (m) return `https://www.linkedin.com/embed/feed/update/urn:li:activity:${m[1]}`; m = url.match(/-(\d{15,25})(?:-[A-Za-z0-9_-]+)?\/?(?:\?.*)?$/); if (m) return `https://www.linkedin.com/embed/feed/update/urn:li:activity:${m[1]}`; return ''; } interface LinkedInEmbedProps { url: string; /** Fixed iframe height — LinkedIn embeds don't auto-resize. */ height?: number; } export function LinkedInEmbedClient({ url, height = 600 }: LinkedInEmbedProps) { const embedUrl = useMemo(() => toLinkedInEmbedUrl(url), [url]); const [loaded, setLoaded] = useState(false); // No derivable URN → graceful fallback card with a link (mirrors reddit's error state) if (!embedUrl) { return (
LinkedIn post
View on LinkedIn
); } return (
{!loaded && (
)}