vinkla/facebook
A Laravel bridge for the official Facebook SDK for PHP. It wires the Facebook service into Laravel's container and facades, letting you manage app credentials, generate login URLs, and call the Graph API through a clean, testable interface.
Install the bridge and publish its config:
composer require vinkla/facebook
php artisan vendor:publish --provider="Vinkla\Facebook\FacebookServiceProvider"
On Laravel 5.5+ the service provider is auto-discovered. On older versions, register Vinkla\Facebook\FacebookServiceProvider::class in config/app.php and optionally add the facade alias:
'Facebook' => Vinkla\Facebook\Facades\Facebook::class,
Set credentials in .env (names may vary slightly by package version):
FACEBOOK_APP_ID=your-app-id
FACEBOOK_APP_SECRET=your-app-secret
FACEBOOK_DEFAULT_GRAPH_VERSION=v2.10
Look here first:
config/facebook.php — the published config is passed almost verbatim to the underlying Facebook\Facebook constructor (app_id, app_secret, default_graph_version, handlers, etc.).vendor/vinkla/facebook/src/ — the package is thin; check the service provider and manager/facade to see exactly what the facebook container binding resolves to.facebook/graph-sdk (Facebook\Facebook), not this package. Its README is the actual usage documentation.First use case — read a profile with a token obtained from Socialite:
use Vinkla\Facebook\Facades\Facebook;
$response = Facebook::get('/me?fields=id,name,email', $socialiteUser->token);
$profile = $response->getGraphUser()->asArray();
Depending on the installed version, the facade may return the SDK instance directly or a manager proxying to the default connection; either way you end up calling Facebook\Facebook methods (get, post, sendRequest, sendBatchRequest).
Wrap the SDK behind your own service. This package gives you container wiring, not application abstractions. Keep controllers free of Graph API details:
final class FacebookClient
{
public function __construct(private \Facebook\Facebook $facebook) {}
public function profile(string $token): array
{
return $this->facebook
->get('/me?fields=id,name,email', $token)
->getGraphUser()
->asArray();
}
public function publishToPage(string $pageId, string $pageToken, string $message): string
{
$response = $this->facebook->post("/{$pageId}/feed", ['message' => $message], $pageToken);
return $response->getGraphNode()['id'];
}
}
Bind it in a service provider using the package binding:
$this->app->bind(FacebookClient::class, fn ($app) => new FacebookClient($app->make('facebook')));
Token strategy. The bridge does not manage OAuth or token refresh — handle that explicitly:
$socialiteUser->token from Laravel Socialite, ideally a long-lived token obtained by exchanging the short-lived one.app_id|app_secret for debug/inspection calls only, never for user data.Queued work. Never serialize SDK objects or responses into jobs. Persist the token and endpoint parameters, then resolve FacebookClient inside handle(). This keeps retries and token rotation manageable.
Batches and pagination. For feeds and large edges use the SDK directly:
$edge = $facebook->get('/me/feed', $token)->getGraphEdge();
while ($edge) {
foreach ($edge as $post) {
// ...
}
$edge = $facebook->next($edge);
}
Use sendBatchRequest() for multiple independent calls; it saves round-trips and is the main reason to keep the SDK rather than hand-rolling HTTP.
Multi-app / multi-tenant. If the package's manager only exposes one configured connection, instantiate the SDK yourself from per-tenant credentials:
$facebook = new \Facebook\Facebook([
'app_id' => $tenant->fb_app_id,
'app_secret' => $tenant->fb_app_secret,
'default_graph_version' => config('facebook.default_graph_version'),
]);
Then inject that instance into your service instead of the container binding.
Testing. Mock at your own service boundary (FacebookClient) rather than trying to fake the SDK's HTTP layer — the SDK does not use Laravel's HTTP client, so Http::fake() will not intercept it. If you must test through the facade, use Facebook::shouldReceive(...) and return stub FacebookResponse objects, or bind a fake manager into the container before resolution.
Webhooks. Register a route, verify X-Hub-Signature-256 against the raw request body using the app secret, respond 200 quickly, and dispatch a job for processing. Do not rely on the bridge for any of this.
facebook/graph-sdk, which is also unmaintained. PHP and Laravel version constraints are likely to conflict on modern projects. Pin versions and plan a migration to direct Graph API calls or a maintained client.default_graph_version explicitly to a currently supported version and treat it as a dependency to review quarterly.FACEBOOK_* values are read into config/facebook.php; after changing .env run php artisan config:cache (and config:clear when debugging “wrong credentials” issues).Facebook alias. If Class 'Facebook' not found appears, add the alias manually or import the FQCN.Facebook\Exceptions\FacebookResponseException (API errors, inspect getResult() for code/subcode) separately from FacebookSDKException (transport/config errors). Map both to domain exceptions so Graph error text does not leak to users.FacebookResponse retains the originating request, which includes the access token. Never log or dump responses; redact before storing.session, state such as the OAuth redirect helper depends on the Laravel session. Behind load balancers or proxies, ensure trusted proxy configuration so generated redirect URLs are correct.Facebook\Facebook instead.extend(), you can register custom drivers; otherwise the practical extension point is to bind your own facebook instance or your own client wrapper before the package resolves it./{token} against the debug endpoint or the SDK's debugToken() path to inspect scopes and expiry before blaming the bridge — most “it doesn't work” reports are expired or under-scoped tokens.How can I help you explore Laravel packages today?