Integration of social media share buttons into Laravel
Giving a user the possibility to quickly share your site or interesting content from it, is crucial in today’s fast-moving world. Certain social media allow the site owners/developers this to be done through the mechanism of share buttons. Let’s talk about a possible implementation of this mechanism in a Laravel application.
The task of adding social media share buttons to a site can be accomplished using numerous services that offer easy integration. On the other hand, you, as a developer, lose some of the control over the behavior of these buttons. Since I encountered this task on several projects, I decided to adopt one of the open-source projects for my needs. That ended up writing my own custom Share Buttons package almost from scratch.
Here is an example of how to use this package and how to integrate it into a Laravel project in a flexible way. However, this package can be integrated into any PHP application (it is not Laravel specific; it just contains some things that make Laravel integration a little bit easier).
We will start the usage of the package from the installation (we’re going to use the composer dependency manager because it is an industry standard).
composer require kudashevs/laravel-share-buttons
The package requires some assets. We're not going very deep, let's just publish a config, scripts and styles:
// publish a `config/share-buttons.php` file
php artisan vendor:publish --provider="Kudashevs\ShareButtons\Providers\ShareButtonsServiceProvider" --tag=config
//publish a `resources/css/share-buttons.css` file
php artisan vendor:publish --provider="Kudashevs\ShareButtons\Providers\ShareButtonsServiceProvider" --tag=css
// publish a `resources/js/share-buttons.js` file
php artisan vendor:publish --provider="Kudashevs\ShareButtons\Providers\ShareButtonsServiceProvider" --tag=vanilla
, we are going to use them a little bit later.
Now, comes the most interesting part - code integration. When I use third-party libraries, I prefer wrapping them in a sort of service wrapper
. One might say this is a redundant abstraction (a level of indirect). For me, this pattern gives more control, flexibility and the possibility to substitute (or even disable) the third-party code, if something bad happens with the original libraries. This is an example of such a wrapper:
// app/Services/ShareButtonsService.php
<?php
namespace App\Services;
use Kudashevs\ShareButtons\ShareButtons;
class ShareButtonsService
{
private const DEFAULT_OPTIONS = ['rel' => 'nofollow'];
private ShareButtons $service;
public function __construct(ShareButtons $service)
{
$this->service = $service;
}
public function generate(string $title): string
{
return $this->service->currentPage(
$title,
self::DEFAULT_OPTIONS,
)
->reddit()
...
->copylink()
->getShareButtons();
}
}
This is a skeleton. It definitely can be elaborated, but let's keep things simple. When the service wrapper is created, there are different possibilities to use it. The obvious one, is to put it into the container by registering it in the AppServiceProvider
class and use it in a template. I consider any references to the container in templates as a bad practice. In this case, I will go with a View composer. I add this code to the boot
method:
app('view')->composer(['partials.share-buttons'], function ($view) {
$view->with('share_buttons', new ShareButtonsService(app('sharebuttons')));
});
, as you can see I provide an instance of the ShareButtonsService
to a partials.share-buttons
template. After the view composer is registered, it is just possible to use the service in the template:
// views/partials/share-buttons.blade.php
<div id="share">
<h4>Share this page:</h4>
{!! $share_buttons->generate($title) !!}
</div>
Now, the integration part is over and we should move back to the assets. We left them published.
Before, in Laravel community, the standard for bundling projects was the Laravel Mix. The current trend is to use Vite. With Vite, the integration of assets has become even easier. Let’s suppose that the default Laravel’s vite.config.js
is used. In this case, all you have to do is to import styles and scripts into the default files.
For styles, update the resources/css/styles.css
with an import:
@import 'share-buttons.css';
For scripts, update the resources/js/app.js
with an import:
import './share-buttons.js';
That's all. After the deployment, everything will work.