Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Klaviyo Bundle Laravel Package

driveop/klaviyo-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require driveop/klaviyo-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Driveop\KlaviyoBundle\KlaviyoBundle::class => ['all' => true],
    ];
    
  2. Configuration Publish the default config:

    php bin/console config:dump-reference Driveop\KlaviyoBundle\DependencyInjection\Configuration
    

    Update config/packages/klaviyo.yaml with your Klaviyo API credentials:

    klaviyo:
        api_key: '%env(KLAVIYO_API_KEY)%'
        private_app_id: '%env(KLAVIYO_PRIVATE_APP_ID)%'
    
  3. First Use Case Trigger a profile track event for a user:

    use Driveop\KlaviyoBundle\Service\KlaviyoClient;
    
    class UserController
    {
        public function __construct(private KlaviyoClient $klaviyo)
        {
        }
    
        public function trackUserAction(User $user)
        {
            $this->klaviyo->trackProfile($user->email, [
                'properties' => [
                    'First Name' => $user->firstName,
                    'Last Name' => $user->lastName,
                    'Lifetime Value' => $user->lifetimeValue,
                ],
                'events' => [
                    'Signed Up' => true,
                ],
            ]);
        }
    }
    

Implementation Patterns

Common Workflows

  1. Event Tracking Use trackProfile() for user actions (e.g., sign-up, purchases):

    $this->klaviyo->trackProfile($email, [
        'properties' => ['Custom Property' => $value],
        'events' => ['Event Name' => true],
    ]);
    
  2. List Management Add/remove users from Klaviyo lists:

    // Add to list
    $this->klaviyo->addToList($listId, [$user1Email, $user2Email]);
    
    // Remove from list
    $this->klaviyo->removeFromList($listId, [$userEmail]);
    
  3. Segmentation Sync custom properties for segmentation:

    $this->klaviyo->syncProperties($email, [
        'Custom Property 1' => $value1,
        'Custom Property 2' => $value2,
    ]);
    
  4. Campaign Integration Trigger campaigns via API:

    $this->klaviyo->triggerCampaign($campaignId, $email);
    

Integration Tips

  • Dependency Injection Inject KlaviyoClient into services/controllers where Klaviyo actions are needed. Example:

    public function __construct(private KlaviyoClient $klaviyo) {}
    
  • Environment Variables Store KLAVIYO_API_KEY and KLAVIYO_PRIVATE_APP_ID in .env:

    KLAVIYO_API_KEY=your_api_key_here
    KLAVIYO_PRIVATE_APP_ID=your_private_app_id
    
  • Batch Processing Use bulk methods (e.g., addToList()) for large datasets to reduce API calls:

    $this->klaviyo->addToList($listId, array_keys($userEmails));
    
  • Error Handling Wrap Klaviyo calls in try-catch blocks to handle API failures gracefully:

    try {
        $this->klaviyo->trackProfile($email, $data);
    } catch (\Exception $e) {
        $this->logger->error('Klaviyo error: ' . $e->getMessage());
    }
    

Gotchas and Tips

Pitfalls

  1. API Rate Limits Klaviyo enforces rate limits (e.g., 10 requests/second). Implement retries with exponential backoff:

    use Symfony\Component\Stopwatch\Stopwatch;
    
    $stopwatch = new Stopwatch();
    $event = $stopwatch->start('klaviyo_request');
    
    try {
        $this->klaviyo->trackProfile($email, $data);
    } catch (\Exception $e) {
        if ($stopwatch->getEvent('klaviyo_request')->getDuration() < 1000) {
            sleep(1); // Simple backoff
            retry();
        }
        throw $e;
    }
    
  2. Profile Sync Delays Klaviyo may take up to 5 minutes to sync profile data. Avoid relying on real-time updates for critical logic.

  3. List IDs Ensure listId is correct (found in Klaviyo dashboard under "Lists"). Hardcoding IDs is fragile; fetch dynamically if possible:

    $listId = $this->klaviyo->getListIdByName('Your List Name');
    
  4. Data Validation Klaviyo rejects malformed payloads. Validate inputs before sending:

    if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new \InvalidArgumentException('Invalid email');
    }
    

Debugging

  • Enable Debug Mode Set debug: true in klaviyo.yaml to log API requests/responses:

    klaviyo:
        debug: true
    
  • Check Logs API errors and responses are logged to var/log/dev.log (or prod.log in production).

  • Test with Sandbox Use Klaviyo’s sandbox environment for testing:

    klaviyo:
        api_key: '%env(KLAVIYO_SANDBOX_API_KEY)%'
        private_app_id: '%env(KLAVIYO_SANDBOX_PRIVATE_APP_ID)%'
    

Extension Points

  1. Custom Events Extend the bundle to support custom Klaviyo events by creating a decorator:

    use Driveop\KlaviyoBundle\Service\KlaviyoClientInterface;
    
    class CustomKlaviyoClient implements KlaviyoClientInterface
    {
        public function __construct(private KlaviyoClient $decorated) {}
    
        public function customEvent($email, array $data)
        {
            $this->decorated->trackProfile($email, [
                'events' => ['Custom Event' => true],
                'properties' => $data,
            ]);
        }
    }
    
  2. Async Processing Offload Klaviyo calls to a message queue (e.g., Symfony Messenger) for performance:

    use Symfony\Component\Messenger\MessageBusInterface;
    
    class KlaviyoMessage
    {
        public function __construct(
            public string $email,
            public array $data,
        ) {}
    }
    
    // In a controller:
    $bus->dispatch(new KlaviyoMessage($email, $data));
    
  3. Webhook Handling Integrate Klaviyo webhooks (e.g., for campaign events) by creating a controller:

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class KlaviyoWebhookController
    {
        public function handle(Request $request): Response
        {
            $payload = json_decode($request->getContent(), true);
            // Process webhook (e.g., update local DB)
            return new Response('OK');
        }
    }
    
  4. Configuration Overrides Override bundle config per environment (e.g., klaviyo.yaml in config/packages/dev/klaviyo.yaml):

    klaviyo:
        debug: true
        api_key: '%env(KLAVIYO_DEV_API_KEY)%'
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium