Laravel Integration

Add an AI chatbot to your Laravel app. This guide shows you how to integrate the LILA widget in Laravel with proper JWT authentication. Your users can ask natural language questions about your database directly from your application.

Prerequisites

  • Laravel 10.x or 11.x
  • Composer
  • LILA project with JWT authentication enabled

Installation

composer require firebase/php-jwt

Step 1: Environment Variables

Add to your .env file:

LILA_API_KEY=pk_live_abc123...
LILA_JWT_SECRET=your-32-char-secret-from-dashboard

Get these from LILA Dashboard → Settings → Setup & Integration.

Step 2: Configuration

Add to config/services.php:

<?php

return [
    // ... other services

    'lila' => [
        'api_key' => env('LILA_API_KEY'),
        'jwt_secret' => env('LILA_JWT_SECRET'),
    ],
];

Step 3: Create LILA Service

Generate JWT tokens for LILA in Laravel with a service class. Create app/Services/LilaService.php:

<?php

namespace App\Services;

use Firebase\JWT\JWT;
use Carbon\Carbon;

class LilaService
{
    /**
     * Generate JWT token for user
     */
    public static function generateToken($user): string
    {
        $jwtSecret = config('services.lila.jwt_secret');

        if (!$jwtSecret) {
            throw new \Exception('LILA JWT secret not configured');
        }

        $payload = [
            'user_id' => (string) $user->id,  // Must be string
            'email' => $user->email,
            'name' => $user->name,
            'iat' => Carbon::now()->timestamp,
            'exp' => Carbon::now()->addHours(2)->timestamp,
        ];

        return JWT::encode($payload, $jwtSecret, 'HS256');
    }

    /**
     * Get LILA configuration array for Blade
     */
    public static function getConfig($user): array
    {
        if (!$user) {
            return [];
        }

        return [
            'api_key' => config('services.lila.api_key'),
            'jwt_token' => self::generateToken($user),
        ];
    }
}

Step 4: Blade Integration

Add to your layout resources/views/layouts/app.blade.php:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ config('app.name') }}</title>

    <!-- LILA Widget -->
    <script type="module" src="https://embed.getlila.one/loader.js"></script>
</head>
<body>
    @yield('content')

    @auth
        <lila-widget
            api-key="{{ config('services.lila.api_key') }}"
            jwt-token="{{ \App\Services\LilaService::generateToken(auth()->user()) }}">
        </lila-widget>
    @endauth
</body>
</html>

Blade Component (Optional)

Create reusable component resources/views/components/lila.blade.php:

@auth
    @php
        $config = \App\Services\LilaService::getConfig(auth()->user());
    @endphp

    <lila-widget
        api-key="{{ $config['api_key'] }}"
        jwt-token="{{ $config['jwt_token'] }}"
        {{ $attributes }}>
    </lila-widget>
@endauth

Use anywhere:

<x-lila theme="dark" />

Token Refresh Endpoint

Handle JWT token expiration in Laravel by creating an API endpoint for refreshing expired tokens:

// routes/api.php
use App\Services\LilaService;

Route::middleware('auth:sanctum')->post('/lila/refresh-token', function () {
    return response()->json([
        'token' => LilaService::generateToken(auth()->user()),
        'expires_in' => 7200,
    ]);
});

Production Checklist

  • LILA_JWT_SECRET in .env (never commit to git)
  • Secret is 32+ characters, randomly generated
  • Token expiration set to 2 hours
  • HTTPS enabled in production
  • Clear config cache after changes: php artisan config:clear

Troubleshooting

LILA widget troubleshooting for Laravel. Check these common issues.

”Invalid signature” Error

  1. Verify LILA_JWT_SECRET matches Dashboard
  2. Clear config cache:
php artisan config:clear
php artisan cache:clear

“user_id claim missing” Error

Ensure user ID is cast to string:

'user_id' => (string) $user->id, // NOT just $user->id

Widget Not Loading

Debug in Blade:

@auth
    <script>
        console.log('LILA Config:', @json(\App\Services\LilaService::getConfig(auth()->user())));
    </script>
@endauth

Next Steps