Unified social publishing for Laravel.
Socialize gives you one fluent API to share content to Facebook, Instagram, X, and LinkedIn, while still letting you use provider-specific features when needed.
- One shared fluent API across providers
- Provider-specific chaining for platform-only features
- URL and local file media support with automatic normalization
- Named profile support per provider (multi-account ready)
- Strict typing, custom exceptions, and high test coverage
- Built for modern Laravel (11/12) and PHP 8.4+
- Facebook (
facebook) - Instagram (
instagram) - X / Twitter (
twitterorx) - LinkedIn (
linkedin)
- PHP
^8.4 - Laravel
^11.0 | ^12.0
composer require draliragab/socializePublish configuration:
php artisan vendor:publish --tag="socialize-config"use DrAliRagab\Socialize\Facades\Socialize;
$result = Socialize::provider('facebook')
->message('New release is live')
->link('https://example.com/release')
->share();
$id = $result->id();
$url = $result->url();Comment on an existing post (all providers):
$comment = Socialize::provider('facebook')
->commentOn($id, 'Thanks everyone!');Share then immediately add a comment:
$comment = Socialize::provider('linkedin')
->message('New release is live')
->link('https://example.com/release')
->shareAndComment('Happy to answer questions below.');Switch provider with the same shared methods:
foreach (['facebook', 'instagram', 'twitter', 'linkedin'] as $provider) {
Socialize::provider($provider)
->message('Hello from Socialize')
->link('https://example.com')
->share();
}message(?string $message)link(?string $url, ?string $articleTitle = null)imageUrl(?string $url)videoUrl(?string $url)media(string $source, ?string $mediaType = null)mediaId(string $id)mediaIds(array $ids)metadata(array $metadata)option(string $key, mixed $value)share(): ShareResultcommentOn(string $postId, string $message): CommentResultshareAndComment(string $message): CommentResultdelete(string $postId): bool
Facebook:
published(bool $published = true)scheduledAt(string|int|DateTimeInterface $dateTime)targeting(array $targeting)
Instagram:
carousel(array $imageUrls)altText(string $text)reel()
X / Twitter:
replyTo(string $postId)quote(string $postId)poll(array $options, int $durationMinutes)
LinkedIn:
visibility(string $visibility)distribution(string $distribution)mediaUrn(string $mediaUrn)poll(array $options, int $durationMinutes)
Poll notes:
poll()is supported fortwitterandlinkedin.- For LinkedIn,
message()is used as the poll question (max 140 chars). - LinkedIn accepts only these poll durations (minutes):
1440,4320,10080,20160.
Socialize keeps the API fluent and provider-agnostic:
- If a provider expects a URL (for example Facebook/Instagram) and you pass a local file, Socialize stores a temporary public file URL, uses it, then cleans it up.
- If a provider expects uploaded media IDs/URNs (for example X/LinkedIn) and you pass a URL, Socialize downloads and uploads it automatically.
Examples:
// Local image -> temporary URL flow for URL-based providers
Socialize::provider('facebook')
->media('/absolute/path/banner.jpg', 'image')
->message('Local image test')
->share();
// URL image -> provider upload flow for upload-based providers
Socialize::provider('linkedin')
->media('https://picsum.photos/1200/800', 'image')
->message('URL image test')
->share();LinkedIn can require richer link content. You can pass an optional title using the second link() argument:
Socialize::provider('linkedin')
->message('Product update')
->link('https://example.com/post', 'Product update details')
->share();This argument is optional and safe to keep in cross-provider fluent code.
Socialize::provider('facebook', 'marketing')
->message('Campaign announcement')
->share();use DrAliRagab\Socialize\Exceptions\ApiException;
try {
Socialize::provider('twitter')->message('Hello X')->share();
} catch (ApiException $e) {
$provider = $e->provider()->value;
$status = $e->status();
$response = $e->responseBody();
}Use DrAliRagab\Socialize\Concerns\CanShareSocially to share directly from Eloquent models:
use DrAliRagab\Socialize\Concerns\CanShareSocially;
class Post extends Model
{
use CanShareSocially;
}
$post->shareToFacebook();
$post->shareTo('linkedin');The trait maps model fields using socialize.model_columns.
All settings live in config/socialize.php.
SOCIALIZE_DEFAULT_PROFILE(optional, default:default)SOCIALIZE_HTTP_TIMEOUT(optional, default:120)SOCIALIZE_HTTP_CONNECT_TIMEOUT(optional, default:30)SOCIALIZE_HTTP_RETRIES(optional, default:1)SOCIALIZE_HTTP_RETRY_SLEEP_MS(optional, default:150)SOCIALIZE_TEMP_MEDIA_DISK(optional, default:public)SOCIALIZE_TEMP_MEDIA_DIRECTORY(optional, default:socialize-temp)SOCIALIZE_TEMP_MEDIA_VISIBILITY(optional, default:public)
SOCIALIZE_FACEBOOK_PAGE_ID(required)SOCIALIZE_FACEBOOK_ACCESS_TOKEN(required)SOCIALIZE_FACEBOOK_GRAPH_VERSION(optional, default:v25.0)SOCIALIZE_FACEBOOK_BASE_URL(optional)
SOCIALIZE_INSTAGRAM_IG_ID(required)SOCIALIZE_INSTAGRAM_ACCESS_TOKEN(required)SOCIALIZE_INSTAGRAM_GRAPH_VERSION(optional, default:v25.0)SOCIALIZE_INSTAGRAM_BASE_URL(optional)SOCIALIZE_INSTAGRAM_PUBLISH_RETRY_ATTEMPTS(optional, default:20)SOCIALIZE_INSTAGRAM_PUBLISH_RETRY_SLEEP_SECONDS(optional, default:3)
SOCIALIZE_TWITTER_BEARER_TOKEN(required for runtime publishing)SOCIALIZE_TWITTER_BASE_URL(optional)SOCIALIZE_TWITTER_MEDIA_PROCESSING_POLL_ATTEMPTS(optional, default:15)
Token requirements:
- Use OAuth 2.0 User Context token, not app-only bearer token
- Required scopes:
tweet.read,tweet.write,users.read,media.write - Add
offline.accesswhen refresh tokens are needed
SOCIALIZE_LINKEDIN_AUTHOR(required, URN format likeurn:li:person:...)SOCIALIZE_LINKEDIN_ACCESS_TOKEN(required)SOCIALIZE_LINKEDIN_VERSION(optional, default:202602, format:YYYYMM)SOCIALIZE_LINKEDIN_BASE_URL(optional)
You can test real provider calls without creating a full Laravel app.
- Copy
.testing.env.exampleto.testing.env - Fill credentials
- Run:
php bin/local-tester.php --helpExamples:
php bin/local-tester.php share --provider=facebook --message="Hello" --link="https://example.com"
php bin/local-tester.php comment --provider=facebook --post-id="123_456" --comment="Nice post!"
php bin/local-tester.php share-and-comment --provider=linkedin --message="Launch" --link="https://example.com" --comment="Any feedback?"
php bin/local-tester.php share --provider=instagram --video-url="https://cdn.example.com/reel.mp4" --reel
php bin/local-tester.php share --provider=twitter --message="Launch day" --media-source="/absolute/path/image.jpg" --media-type=image
php bin/local-tester.php share --provider=linkedin --message="Professional update" --link="https://example.com" --link-title="Read more"
php bin/local-tester.php delete --provider=linkedin --post-id="urn:li:share:123"composer analyse
composer test
composer test-coverage
composer format
composer rector
composer checkMIT