Installation:
composer require teners/laravel-link-preview
Publish the config file:
php artisan vendor:publish --provider="Teners\LinkPreview\LinkPreviewServiceProvider" --tag="config"
Basic Usage: Fetch a preview for a URL in a controller or service:
use Teners\LinkPreview\Facades\LinkPreview;
$preview = LinkPreview::get('https://example.com');
Output will include structured data like:
{
"url": "https://example.com",
"title": "Example Domain",
"description": "This domain is for use in illustrative examples...",
"image": "https://example.com/image.jpg",
"favicon": "https://example.com/favicon.ico",
"site_name": "Example Inc.",
"type": "website"
}
First Use Case: Display rich previews in a comment system:
@foreach($comments as $comment)
<div class="comment">
<a href="{{ $comment->url }}" target="_blank">
<img src="{{ $comment->preview->image ?? asset('fallback.png') }}" width="100">
<h4>{{ $comment->preview->title ?? $comment->url }}</h4>
<p>{{ Str::limit($comment->preview->description, 100) }}</p>
</a>
</div>
@endforeach
Service Layer Integration: Create a dedicated service class to encapsulate preview logic:
namespace App\Services;
use Teners\LinkPreview\Facades\LinkPreview;
class LinkPreviewService
{
public function getPreview(string $url, bool $forceRefresh = false): array
{
return LinkPreview::get($url, ['refresh' => $forceRefresh]);
}
public function getCachedPreview(string $url): ?array
{
return LinkPreview::get($url, ['cache_only' => true]);
}
}
Queue-Based Processing (for async operations):
LinkPreview::get('https://slow-site.com')->queue();
// Later, in a job:
$preview = LinkPreview::getQueued('job-id')->get();
Platform-Specific Handling:
$preview = LinkPreview::get('https://twitter.com/user/status/12345');
if ($preview->type === 'twitter') {
// Custom Twitter-specific UI
}
Validation:
use Teners\LinkPreview\Exceptions\PreviewException;
try {
$preview = LinkPreview::get($url);
} catch (PreviewException $e) {
// Handle invalid URLs or failed requests
}
Fallback Logic:
$preview = LinkPreview::get($url, [
'fallback' => [
'title' => 'Untitled',
'description' => 'No preview available',
'image' => asset('fallback.png')
]
]);
Custom Parsers: Extend the base parser for niche platforms:
namespace App\Parsers;
use Teners\LinkPreview\Contracts\ParserInterface;
class CustomParser implements ParserInterface
{
public function parse(string $html, string $url): array
{
// Custom logic
}
}
Register in config/link-preview.php:
'parsers' => [
'custom' => \App\Parsers\CustomParser::class,
],
Caching Quirks:
LinkPreview::get($url, ['cache_key' => 'custom_key']) for consistent keys.LinkPreview::clearCache($url);
// Or globally:
LinkPreview::clearAllCache();
Rate Limiting:
LinkPreview::get($url, ['delay' => 2]) to add delays between requests.SSL Verification:
LinkPreview::get($url, ['verify_ssl' => false]);
Redirect Handling:
LinkPreview::get($url, ['follow_redirects' => false]);
Memory Limits:
LinkPreview::get($url, ['memory_limit' => '256M']);
Enable Verbose Logging:
LinkPreview::get($url, ['verbose' => true]);
Check logs for raw HTTP responses and parsing steps.
Inspect Raw HTML:
$preview = LinkPreview::get($url, ['return_html' => true]);
// $preview['html'] contains the raw response body
Test with Known URLs: Use these for validation:
// Twitter/X
LinkPreview::get('https://twitter.com/TenersNet');
// YouTube
LinkPreview::get('https://youtube.com/watch?v=dQw4w9WgXcQ');
// Generic HTML
LinkPreview::get('https://example.com');
Custom Metadata Extraction: Override the default metadata parser:
LinkPreview::get($url, [
'metadata_parser' => function ($html) {
// Return custom array of metadata
}
]);
Event Listeners:
Listen for preview events (e.g., preview.fetched):
LinkPreview::get($url)->then(function ($preview) {
// Post-processing
});
Queue Monitoring: Check queued jobs:
$queuedJobs = LinkPreview::queuedJobs();
foreach ($queuedJobs as $job) {
$job->refresh(); // Force refresh
}
Performance Tuning:
config/link-preview.php:
'timeout' => 10, // seconds
'connect_timeout' => 5,
LinkPreview::get($url, ['timeout' => 30]) for slow sites.Fallback Strategies: Implement a fallback chain:
$preview = LinkPreview::get($url, [
'fallbacks' => [
'https://via.placeholder.com/150', // Image fallback
'No description available', // Description fallback
]
]);
How can I help you explore Laravel packages today?