Weave 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

Shariff Laravel Package

heise/shariff

PHP backend for Shariff that fetches social share counts without client-side requests to social networks. Supports Buffer, Facebook, Pinterest, Reddit, Xing, VK and more, with domain whitelisting and configurable caching (filesystem or Laminas adapters).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the package via Composer:
    composer require heise/shariff
    
  2. Create a dedicated route in routes/web.php:
    Route::get('/shariff', [ShariffController::class, 'index']);
    
  3. Create a controller (ShariffController.php) with a minimal handler:
    use Heise\Shariff\Backend;
    
    class ShariffController extends Controller
    {
        public function index(Request $request)
        {
            $options = [
                'domains' => ['yourdomain.com'], // Whitelist allowed domains
                'services' => ['Facebook', 'Twitter', 'LinkedIn'], // Enable required services
                'cache' => ['ttl' => 3600] // Cache for 1 hour
            ];
    
            $shariff = new Backend($options);
            $url = $request->query('url', url()->current());
            $counts = $shariff->get($url);
    
            return response()->json($counts);
        }
    }
    
  4. Test the endpoint:
    curl "http://yourdomain.com/shariff?url=https://example.com"
    

First Use Case: Displaying Share Counts

Use the endpoint in Blade templates or frontend JS:

<div class="share-counts">
    <span data-service="facebook" data-url="{{ $articleUrl }}">0</span>
    <span data-service="twitter" data-url="{{ $articleUrl }}">0</span>
</div>

<script>
    document.querySelectorAll('[data-service]').forEach(el => {
        fetch(`/shariff?url=${encodeURIComponent(el.dataset.url)}`)
            .then(res => res.json())
            .then(data => {
                el.textContent = data[el.dataset.service] || '0';
            });
    });
</script>

Implementation Patterns

1. Service-Specific Configuration

Configure services individually in the Backend constructor:

$options = [
    'Facebook' => [
        'app_id' => env('FACEBOOK_APP_ID'),
        'secret' => env('FACEBOOK_APP_SECRET')
    ],
    'Twitter' => [
        'use_legacy_api' => false // Example: Disable legacy API for Twitter
    ]
];
$shariff = new Backend($options);

2. Caching Strategies

Leverage Laravel’s cache drivers (Redis, Memcached, etc.) by implementing CacheInterface:

use Heise\Shariff\CacheInterface;
use Illuminate\Cache\CacheManager;

class LaravelCache implements CacheInterface
{
    protected $cache;

    public function __construct(CacheManager $cache)
    {
        $this->cache = $cache->store('redis');
    }

    public function get($key) { /* ... */ }
    public function set($key, $value, $ttl) { /* ... */ }
    public function delete($key) { /* ... */ }
}

$options = [
    'cacheClass' => LaravelCache::class,
    'cache' => ['ttl' => 3600]
];

3. Rate Limiting and Error Handling

Wrap Shariff calls in Laravel’s try-catch or use middleware:

use Illuminate\Support\Facades\RateLimiter;

Route::middleware(['throttle:100,1'])->group(function () {
    Route::get('/shariff', [ShariffController::class, 'index']);
});

4. Dynamic Service Enablement

Enable/disable services based on config or user roles:

$services = config('shariff.services', ['Facebook', 'Twitter']);
$options = ['services' => $services];

5. Integration with Laravel Scout

Store share counts in a database and sync with Scout:

$counts = $shariff->get($url);
ShareCount::updateOrCreate(
    ['url' => $url],
    ['facebook' => $counts['facebook'] ?? 0]
);

Gotchas and Tips

Pitfalls

  1. Domain Whitelisting:

    • Forgetting to whitelist domains in domains will return empty results.
    • Fix: Always validate $request->query('url') against allowed domains:
      $url = parse_url($request->query('url'), PHP_URL_HOST);
      if (!in_array($url, config('shariff.domains'))) {
          abort(403, 'Domain not allowed');
      }
      
  2. Facebook Graph API Changes:

    • The package updates Facebook’s API version frequently (e.g., v25.0 in v11.0.0).
    • Fix: Monitor changelogs and test after updates. Use app_id/secret for accurate counts.
  3. Caching Quirks:

    • Default Filesystem cache may fill up /tmp. Use Laravel’s cache drivers instead.
    • Fix: Implement CacheInterface for Redis/Memcached:
      $options = [
          'cacheClass' => LaravelCache::class,
          'cache' => ['ttl' => 3600, 'store' => 'redis']
      ];
      
  4. Service Failures:

    • A failing service (e.g., Twitter API downtime) crashes the entire request.
    • Fix: Use try-catch in the controller:
      try {
          $counts = $shariff->get($url);
      } catch (\Exception $e) {
          Log::error($e);
          return response()->json(['error' => 'Service unavailable'], 503);
      }
      
  5. URL Encoding:

    • URLs with special characters (e.g., ?, #) may break parsing.
    • Fix: URL-encode the input:
      $url = rawurldecode($request->query('url'));
      

Debugging Tips

  1. Log Raw Responses: Add a logger to Backend or use Laravel’s logging:

    use Psr\Log\LoggerInterface;
    
    $shariff = new Backend($options, new Logger());
    

    Configure in config/shariff.php:

    'logger' => [
        'channel' => 'single',
        'level' => 'debug'
    ],
    
  2. Test with curl: Manually test endpoints to isolate issues:

    curl -v "http://yourdomain.com/shariff?url=https://example.com"
    
  3. Check HTTP Headers: Ensure User-Agent and Accept headers are set (default in Guzzle):

    $options['client'] = [
        'headers' => [
            'User-Agent' => 'Laravel-Shariff/1.0',
            'Accept' => 'application/json'
        ]
    ];
    

Extension Points

  1. Custom Services: Extend Heise\Shariff\Service\AbstractService to add new platforms (e.g., Mastodon):

    class MastodonService extends AbstractService
    {
        protected $name = 'Mastodon';
        protected $url = 'https://mastodon.social/api/v1/statuses';
    
        public function getCount($url) { /* ... */ }
    }
    
  2. Override Cache Logic: Replace LaminasCache with a Laravel-specific implementation:

    class LaravelCache implements CacheInterface
    {
        public function get($key) {
            return Cache::get('shariff_' . $key);
        }
        // ...
    }
    
  3. Modify Response Format: Transform raw counts into a Laravel-friendly structure:

    $counts = $shariff->get($url);
    return ShareCountResource::collection($counts);
    

Performance Optimizations

  1. Batch Requests: Use Laravel queues to fetch counts asynchronously:

    ShariffJob::dispatch($url)->onQueue('shariff');
    
    class ShariffJob implements ShouldQueue
    {
        public function handle() {
            $counts = $shariff->get($this->url);
            ShareCount::updateOrCreate([...], $counts);
        }
    }
    
  2. Cache Invalidation: Invalidate cache on content updates (e.g., ArticleUpdated event):

    Cache::forget('shariff_' . $article->url);
    
  3. Service Prioritization: Disable slower services (e.g., Pinterest) during peak traffic:

    $services = config('app.debug') ? ['Facebook', 'Twitter'] : ['Facebook'];
    
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator