make a Chatbot with laravel and Nextjs
I'll create a full-stack chatbot application with Laravel handling the backend API and Next.js for the frontend. This setup gives you the best of both worlds: Laravel's robust backend capabilities and Next.js's excellent frontend performance and developer experience.
Let's start by building the Next.js frontend with the chat interface:
Now, let's create the Laravel backend API for our chatbot:
<?php
// routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ChatController;
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
Route::post('/chat', [ChatController::class, 'sendMessage']);
Route::get('/chat/history', [ChatController::class, 'getHistory']);
});<?php
// app/Http/Controllers/AuthController.php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class AuthController extends Controller
{
public function register(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8|confirmed',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'user' => $user,
'token' => $token,
], 201);
}
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'user' => $user,
'token' => $token,
]);
}
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out successfully']);
}
}<?php
// app/Http/Controllers/ChatController.php
namespace App\Http\Controllers;
use App\Models\ChatMessage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
class ChatController extends Controller
{
public function sendMessage(Request $request)
{
$request->validate([
'message' => 'required|string',
]);
// Save user message to database
$userMessage = ChatMessage::create([
'user_id' => auth()->id(),
'content' => $request->message,
'is_from_user' => true,
]);
// Call OpenAI API for response
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . env('OPENAI_API_KEY'),
'Content-Type' => 'application/json',
])->post('https://api.openai.com/v1/chat/completions', [
'model' => 'gpt-4o',
'messages' => [
['role' => 'system', 'content' => 'You are a helpful assistant.'],
['role' => 'user', 'content' => $request->message],
],
'temperature' => 0.7,
]);
if ($response->successful()) {
$botResponse = $response->json()['choices'][0]['message']['content'];
// Save bot response to database
$botMessage = ChatMessage::create([
'user_id' => auth()->id(),
'content' => $botResponse,
'is_from_user' => false,
]);
return response()->json([
'response' => $botResponse,
]);
}
return response()->json([
'response' => 'Sorry, I could not process your request at this time.',
], 500);
}
public function getHistory(Request $request)
{
$messages = ChatMessage::where('user_id', auth()->id())
->orderBy('created_at', 'asc')
->get();
return response()->json([
'messages' => $messages,
]);
}
}<?php
// app/Models/ChatMessage.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ChatMessage extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'content',
'is_from_user',
];
protected $casts = [
'is_from_user' => 'boolean',
'created_at' => 'datetime',
];
public function user()
{
return $this->belongsTo(User::class);
}
}<?php
// database/migrations/xxxx_xx_xx_create_chat_messages_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('chat_messages', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->text('content');
$table->boolean('is_from_user');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('chat_messages');
}
};Create a new Laravel project:
composer create-project laravel/laravel chatbot-api
cd chatbot-apiSet up the database in .env:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=chatbot
DB_USERNAME=root
DB_PASSWORD=
OPENAI_API_KEY=your_openai_api_key_hereInstall Laravel Sanctum for API authentication:
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"Run migrations:
php artisan migrateConfigure CORS in config/cors.php:
'paths' => ['api/*'],
'allowed_origins' => ['http://localhost:3000'],
'allowed_methods' => ['*'],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,Start the Laravel server:
php artisan serveCreate a new Next.js project:
npx create-next-app@latest chatbot-frontend
cd chatbot-frontendInstall dependencies:
npm install ai @ai-sdk/openai next-authStart the Next.js development server:
npm run devAuthentication Flow:
Chat Flow:
Data Storage:
This architecture gives you a robust, scalable chatbot application with a clean separation of concerns between the frontend and backend.
Please make sure to add the following environment variables to your project: