'use client'; import * as React from 'react'; import { useEffect, useState, useRef } from 'react'; interface LinkedInEmbedProps { /** The post URL, e.g. "https://www.linkedin.com/posts/xyz" or raw URN */ url: string; className?: string; width?: string | number; } export function LinkedInEmbed({ url, className = "", width = 504 }: LinkedInEmbedProps) { const [isMounted, setIsMounted] = useState(false); const [hasError, setHasError] = useState(false); const iframeRef = useRef(null); // Extract the 19-digit ID from the URL or URN const match = url.match(/(\d{19})/); const embedId = match ? match[1] : null; useEffect(() => { setIsMounted(true); }, []); if (!isMounted || !embedId) return null; // LinkedIn technically supports share, ugcPost, and activity. We start with share and natively cycle. const initialSrc = `https://www.linkedin.com/embed/feed/update/urn:li:share:${embedId}`; const handleError = () => { if (!iframeRef.current) return; const currentSrc = iframeRef.current.src; // If the 'share' URN 404s (e.g., restricted post type), fallback to 'activity', then 'ugcPost' if (currentSrc.includes('urn:li:share:')) { iframeRef.current.src = `https://www.linkedin.com/embed/feed/update/urn:li:activity:${embedId}`; } else if (currentSrc.includes('urn:li:activity:')) { iframeRef.current.src = `https://www.linkedin.com/embed/feed/update/urn:li:ugcPost:${embedId}`; } else { // All fallbacks exhausted. The post is truly dead or private. setHasError(true); } }; if (hasError) { return (
Beitrag nicht verfügbar Dieser LinkedIn-Post wurde gelöscht oder die Privatsphäre-Einstellungen verhindern eine Einbettung.
); } return (
{/* We use onLoad to detect successful rendering, relying on onError for explicit iframe load crashes */}