Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Twitter Oembed Laravel Package

spatie/twitter-oembed

Fetch Twitter (X) tweet embed HTML via the public oEmbed API—no developer account needed. Lightweight utility for turning tweet URLs into embeddable HTML for blogs, markdown, editors, or emails, without relying on Twitter’s heavy JavaScript widget.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/twitter-oembed
    

    No additional configuration is required—just autoload.

  2. First Use Case: Fetch a tweet by its URL or ID:

    use Spatie\TwitterOEmbed\TwitterOEmbed;
    
    $tweet = TwitterOEmbed::create('https://twitter.com/user/status/123456789');
    // or by ID:
    $tweet = TwitterOEmbed::create('123456789');
    

    Outputs a Spatie\TwitterOEmbed\TwitterOEmbed object with embedded HTML.

  3. Where to Look First:

    • README for basic usage.
    • src/TwitterOEmbed.php for core logic (e.g., how URLs/IDs are parsed).
    • Tests (tests/) for edge cases (e.g., invalid URLs, rate limits).

Implementation Patterns

Core Workflows

  1. Embedding Tweets in Markdown/HTML: Use the package to generate static HTML for tweets, then parse it into your CMS or markdown processor:

    $html = TwitterOEmbed::create($tweetUrl)->html();
    // Inject `$html` into a markdown template or rich-text field.
    
  2. Caching Responses: Cache responses to avoid hitting Twitter’s rate limits (unofficial but recommended):

    $cacheKey = 'tweet_'.$tweetId;
    $html = cache()->remember($cacheKey, now()->addHours(1), function() use ($tweetUrl) {
        return TwitterOEmbed::create($tweetUrl)->html();
    });
    
  3. Integration with Laravel Blade: Create a custom Blade directive or helper:

    // app/Helpers/TweetHelper.php
    function tweet($urlOrId) {
        return TwitterOEmbed::create($urlOrId)->html();
    }
    

    Usage in Blade:

    {!! tweet('https://twitter.com/user/status/12345') !!}
    
  4. Batch Processing: Fetch multiple tweets in a loop (respect rate limits!):

    $tweetUrls = ['url1', 'url2', 'url3'];
    foreach ($tweetUrls as $url) {
        $html = TwitterOEmbed::create($url)->html();
        // Process or store $html
    }
    
  5. Rich Text Editors (e.g., TinyMCE, CKEditor): Use the package to generate embeddable HTML snippets for pasting into editors:

    $editorPlugin = new TinyMCEPlugin();
    $editorPlugin->addEmbedButton('Tweet', function($url) {
        return TwitterOEmbed::create($url)->html();
    });
    

Advanced Patterns

  • Customizing Output: Extend the TwitterOEmbed class to modify the HTML structure:

    class CustomTwitterOEmbed extends \Spatie\TwitterOEmbed\TwitterOEmbed {
        public function html() {
            $html = parent::html();
            return str_replace('class="tweet"', 'class="custom-tweet"', $html);
        }
    }
    
  • Fallback for Invalid Tweets: Handle missing/blocked tweets gracefully:

    try {
        $tweet = TwitterOEmbed::create($url);
    } catch (\Spatie\TwitterOEmbed\Exceptions\InvalidTweetException $e) {
        return '<p>Tweet not found or inaccessible.</p>';
    }
    

Gotchas and Tips

Pitfalls

  1. Rate Limiting:

    • Twitter’s oEmbed API has unofficial rate limits (~100 requests/hour/IP). Exceeding this may return empty responses or errors.
    • Solution: Cache aggressively or use a queue (e.g., Laravel Queues) to space out requests.
  2. URL/ID Parsing:

    • The package accepts URLs (twitter.com/user/status/123) or raw IDs (123456789), but malformed inputs (e.g., missing status/) will fail silently or return invalid HTML.
    • Solution: Validate inputs:
      if (!TwitterOEmbed::isValidUrlOrId($urlOrId)) {
          throw new \InvalidArgumentException('Invalid tweet URL or ID.');
      }
      
  3. Deprecated API:

    • Twitter’s oEmbed API is not officially documented and may change or break without notice.
    • Solution: Monitor the package for updates or wrap calls in a feature flag.
  4. HTML Sanitization:

    • The returned HTML is not sanitized by default. Embedding it directly in user-generated content (e.g., comments) risks XSS.
    • Solution: Sanitize with Laravel’s Str::of($html)->markdown() or a library like htmlpurifier.
  5. Missing Metadata:

    • The API returns minimal data (no author details, limited text). For richer data, consider Twitter API v2 (requires developer account).

Debugging Tips

  • Check Raw Response: Inspect the underlying API response for debugging:

    $response = TwitterOEmbed::create($url)->getResponse();
    // $response contains the raw JSON from Twitter.
    
  • Log Failed Requests: Wrap calls in a try-catch to log errors:

    try {
        $tweet = TwitterOEmbed::create($url);
    } catch (\Exception $e) {
        \Log::error("Failed to fetch tweet {$url}: " . $e->getMessage());
    }
    

Extension Points

  1. Custom API Endpoint: Override the default endpoint (e.g., for a self-hosted proxy):

    TwitterOEmbed::setApiEndpoint('https://your-proxy.com/oembed');
    
  2. Add Headers: Inject custom headers (e.g., for authentication if using a proxy):

    TwitterOEmbed::setClient(new \GuzzleHttp\Client([
        'headers' => ['X-Custom-Header' => 'value'],
    ]));
    
  3. Mocking for Tests: Use the TwitterOEmbed facade’s fake() method to mock responses:

    TwitterOEmbed::fake([
        'https://twitter.com/user/status/123' => '<div>Mock HTML</div>',
    ]);
    
  4. Event Listeners: Extend the package by listening to its events (e.g., CreatingTwitterOEmbed):

    TwitterOEmbed::creating(function ($tweet) {
        // Log or modify the tweet before embedding
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport