spatie/laravel-support-bubble
Add a non-intrusive support chat bubble to any Laravel page. Opens a Tailwind-styled support form, auto-fills user info when logged in, includes URL/IP metadata, honeypot spam protection, and is easily customizable via views, translations, and events.
Installation:
composer require spatie/laravel-support-bubble
php artisan vendor:publish --provider="Spatie\SupportBubble\SupportBubbleServiceProvider" --tag="config"
php artisan migrate
Publish the config and run migrations to set up the database table for support requests.
Configuration:
Edit config/support-bubble.php to customize:
chat_bubble (enabled/disabled, position, styling)support_form (fields, validation, honeypot settings)notifications (webhook or email settings for new requests)First Use Case:
Add the chat bubble to your layout (e.g., resources/views/layouts/app.blade.php):
@supportBubble
This renders the default bubble with TailwindCSS styling. Test by visiting any page—logged-out users will see the bubble.
Customizing the Bubble:
resources/views/vendor/support-bubble/chat-bubble.blade.php) to modify appearance.php artisan vendor:publish --provider="Spatie\SupportBubble\SupportBubbleServiceProvider" --tag="public"
Then override resources/js/support-bubble.js.Handling Support Requests:
SupportBubble\Events\SupportRequestReceived to process submissions:
use Spatie\SupportBubble\Events\SupportRequestReceived;
SupportRequestReceived::listen(function (SupportRequest $request) {
// Send to CRM, Slack, or queue for review
});
SupportRequest model to query or update submissions:
use Spatie\SupportBubble\Models\SupportRequest;
$recentRequests = SupportRequest::latest()->take(10)->get();
Conditional Display:
'chat_bubble' => [
'enabled' => true,
'except' => ['admin.*', 'support.*'],
'for_guests_only' => true, // Hide for logged-in users
],
@if(!auth()->check())
@supportBubble
@endif
Localization:
php artisan vendor:publish --provider="Spatie\SupportBubble\SupportBubbleServiceProvider" --tag="lang"
Override resources/lang/en/support-bubble.php for custom text.Integration with Frontend Frameworks:
@supportBubble directive in your root component and manage state locally if needed.<template>
<div>
@supportBubble
<button @click="toggleBubble">Toggle Support</button>
</div>
</template>
<script>
export default {
methods: {
toggleBubble() {
// Dispatch custom event to hide/show bubble
document.dispatchEvent(new CustomEvent('supportBubble:toggle'));
}
}
};
</script>
Honeypot Misconfiguration:
config/support-bubble.php matches the form:
'honeypot' => [
'field_name' => 'website', // Default; ensure this matches your form
],
<input type="text" name="website" style="display: none;">
CSRF Token Issues:
{!! csrf_field() !!} or the meta tag in your layout:
@csrf
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
}
Database Schema Conflicts:
SupportRequest model, run php artisan migrate after adding new fields to avoid schema errors.support_requests table before customizing migrations.TailwindCSS Conflicts:
!important sparingly:
.support-bubble {
@apply !important your-custom-classes;
}
Performance with Heavy Forms:
except in config to reduce render time.if (window.location.pathname !== '/checkout') {
// Load @supportBubble dynamically
}
Log Support Requests: Add a listener to debug submissions:
SupportRequestReceived::listen(function ($request) {
\Log::info('Support Request', ['data' => $request->toArray()]);
});
Check JavaScript Errors:
Inspect the browser console for errors like Uncaught ReferenceError: SupportBubble is not defined. Ensure:
@supportBubble directive is placed after jQuery (if used) and before </body>.Verify Webhook Notifications:
If using webhooks, test with curl or Postman to ensure the endpoint is reachable:
curl -X POST -H "Content-Type: application/json" -d '{}' http://your-app.test/api/support-bubble/webhook
Custom Validation:
Extend the SupportRequest model’s $fillable and add validation rules in AppServiceProvider:
use Spatie\SupportBubble\Models\SupportRequest;
SupportRequest::observe(SupportRequestObserver::class);
class SupportRequestObserver {
public function saving(SupportRequest $request) {
$request->validate([
'custom_field' => 'required|string',
]);
}
}
Add Attachments: Extend the form to include file uploads:
<input type="file" name="screenshot">
Update the SupportRequest model to handle files:
use Illuminate\Http\UploadedFile;
public function setScreenshotAttribute(UploadedFile $file) {
$this->attributes['screenshot'] = $file->store('support-bubble');
}
Multi-Language Support: Dynamically set the language based on user locale:
// In AppServiceProvider
SupportBubble::setLocale(app()->getLocale());
Analytics Integration: Track bubble interactions with Google Analytics or Mixpanel:
document.addEventListener('supportBubble:open', () => {
gtag('event', 'support_bubble_opened', { page_path: window.location.pathname });
});
Dark Mode Support:
Add a data-theme attribute to the bubble and toggle via JavaScript:
<div class="support-bubble" data-theme="light">
const bubble = document.querySelector('.support-bubble');
bubble.dataset.theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
How can I help you explore Laravel packages today?