jorenvanhocht/laravel-share
Laravel Share is a package for generating social media share links in Laravel applications. It provides a simple API to create share URLs for Facebook, Twitter, LinkedIn, Reddit, WhatsApp, and more, with support for custom URLs, titles, and images.
Install with Composer and let Laravel's package discovery do the rest:
composer require jorenvanhocht/laravel-share
The service provider and the Share facade alias are auto-registered on Laravel 5.5+. There is no migration, no config file you must publish, and no Artisan command to run — the package is a thin URL builder plus an HTML renderer.
First use case — a share bar on an article page:
{{-- resources/views/posts/show.blade.php --}}
{!! Share::page($post->url, $post->title)
->facebook()
->twitter()
->linkedin($post->excerpt)
->whatsapp() !!}
Note {!! !!} — the package returns an HTML string, and it will be escaped into visible markup if you use {{ }}.
Where to look first
src/Share.php — every network is one small method building a URL; reading it takes five minutes and answers most questions (what parameters each network accepts, what the default markup looks like).<a> tags with target="_blank"), which is usually the point where you decide to either style it or replace it.Use Share::currentPage('Title') instead of Share::page(...) when the page URL is simply the current request URL. That is fine for simple cases but see the gotchas on query strings and proxies.
Each call appends a link; chaining is order-independent and each network method accepts an optional attribute array that is merged into that anchor:
{!! Share::currentPage('Hello world')
->facebook(['class' => 'share-btn', 'aria-label' => 'Share on Facebook'])
->twitter(['class' => 'share-btn', 'aria-label' => 'Share on X'])
->linkedin(['class' => 'share-btn'])
->telegram(['class' => 'share-btn']) !!}
Rather than post-processing the string, wrap the whole generated block so it drops into your markup as a list:
{!! Share::page($post->url, $post->title)
->facebook()
->twitter()
->linkedin()
->prefix('<ul class="share-bar">')
->suffix('</ul>') !!}
The default anchors rarely match a design system. Use getRawLinks() / getRawLink('facebook') to get just the URLs, then render your own Blade partial with your own icons, rel, and tracking hooks:
// app/View/Components/ShareBar.php
public function render()
{
$links = Share::page($this->url, $this->title)
->facebook()
->twitter()
->linkedin()
->whatsapp()
->getRawLinks();
return view('components.share-bar', ['links' => $links]);
}
{{-- resources/views/components/share-bar.blade.php --}}
<nav class="share-bar" aria-label="Share this article">
@foreach ($links as $network => $url)
<a href="{{ $url }}"
target="_blank"
rel="noopener noreferrer nofollow"
data-network="{{ $network }}">
@include("icons.{$network}")
</a>
@endforeach
</nav>
This keeps the package as a URL-generation library (its real value) and leaves styling, accessibility, and analytics entirely to you.
Because you control the anchor when using raw links, add click handlers or data-* attributes for your analytics stack, or open a centered popup instead of a tab:
<a href="{{ $links['twitter'] }}"
onclick="window.open(this.href, 'share', 'width=600,height=500'); return false;">
currentPage() uses the request URL. For paginated, filtered, or AMP variants it is usually better to pass the canonical URL explicitly, so shares always resolve to the same page:
{!! Share::page($post->canonical_url, $post->title)->facebook()->twitter() !!}
The generated links are plain URLs, so they work in emails and RSS. Just make sure everything is absolute (https://…) — social networks will not accept relative URLs, and there is no JS fallback in an email client.
Assert on URLs, not HTML, to keep tests resilient to markup changes:
$links = Share::page('https://example.com/a', 'A')->facebook()->getRawLinks();
$this->assertStringContainsString('facebook.com/sharer', $links['facebook']);
$this->assertStringContainsString(urlencode('https://example.com/a'), $links['facebook']);
{!! !!} in Blade for the HTML output. When you pass your own attribute values, escape anything user-supplied yourself with e() — do not hand raw user input to the attribute array.route()/url() output, not '/posts/1'.currentPage() picks up query strings. UTM parameters and pagination get baked into the shared URL and can fragment analytics. Prefer an explicit canonical URL when it matters.APP_URL. Behind a load balancer, currentPage() can generate http:// or an internal host. Configure TrustProxies/APP_URL before blaming the package.og:* meta tags are what actually render in the post.->linkedin($summary) still builds the URL, but LinkedIn largely ignores the summary and pulls OG data from the page instead. Don't rely on it for messaging.target="_blank". Add rel="noopener" and icons yourself. If your design needs SVG icons, getRawLinks() is the cleaner route.wa.me; on mobile it deep-links into the app. Expect different behavior per platform when testing.Share::page(...) / Share::currentPage(...) per render rather than stashing a half-built chain in a singleton or view composer cache.x() method — ->twitter() still emits the twitter.com/intent/tweet endpoint, which continues to redirect to X.How can I help you explore Laravel packages today?