Laravel 13 - How to Integrate OpenRouter API Using Prism.
Laravel 13 - How to Integrate OpenRouter API Using Prism.
In this tutorial, we will learn how to build a real-time AI chat app in Laravel 13 using Prism and OpenRouter. We will set up the project, configure API keys, create controller and routes, and build a Tailwind chat UI with live AI responses.
Quick Overview
This guide walks you through building a real-time AI chat application in Laravel 13 using the Prism package with OpenRouter. You start by creating a fresh Laravel project, then install and configure Prism, and connect it to OpenRouter using an API key stored in your .env file. After setup, you create a controller to handle user prompts, define routes for processing requests, and build a modern chat interface using Tailwind CSS. The frontend sends messages via AJAX to Laravel, where Prism forwards the request to OpenRouter and returns AI-generated responses. These responses are then displayed instantly in the chat window with a smooth loading state, creating a fully interactive AI chat experience inside your Laravel application.
Step # 1 : Install Laravel 13 for Your OpenRouter Project.
To get started with OpenRouter using Prism, you’ll first need a fresh Laravel 13 installation. Make sure Composer is already installed on your system, and it’s a good idea to also have the Laravel Installer globally available to simplify project creation. You can install the Installer with.
composer global require laravel/installer
Once that’s done, create a new Laravel project by running.
laravel new openrouter
During the setup process, you’ll be prompted to choose a few options. Use the following configuration.
- Starter kit: Choose None to keep the project clean and minimal.
- Testing framework: Select Pest for a modern and expressive testing setup.
- Laravel Boost: Select No since it’s not required for this project.
- Database: Pick SQLite as it’s lightweight and perfect for local development.
- Run npm install and build assets: Choose Yes so dependencies are installed and assets are compiled automatically.
After the installation completes, you’ll have a clean Laravel 13 project ready. This will serve as the foundation for integrating OpenRouter.
Step # 2 : Move Into the OpenRouter Project Directory.
After the project is created, you simply need to switch into its directory so you can continue working on it.
cd c:/xampp/htdocs/openrouter
Now that you’re inside the project directory, you can move forward with installing Prism and connecting OpenRouter to your Laravel application.
Step # 3 : Install Laravel Prism Package.
Prism is a Laravel AI package that makes it easy to integrate AI models into your application. It supports multiple providers such as OpenAI, OpenRouter, and Google Gemini, while providing a clean and consistent API for handling chats, text generation, streaming responses, and other AI-powered features. Install the Prism package using Composer.
composer require prism-php/prism
The package will now be added to your project dependencies and can be used throughout your Laravel application.
Step # 4 : Publish the Prism Configuration File.
Prism includes a dedicated configuration file where you can manage AI providers, API keys, default models, and other package settings for your Laravel application. Run the following Artisan command to publish the Prism configuration file.
php artisan vendor:publish --tag=prism-config
This will add a prism.php file inside your config folder, where Prism settings can be managed.
Step # 5 : Generate Your OpenRouter API Key.
To connect Prism with AI models, you’ll need an API key from OpenRouter. Follow the steps below to generate one.
- Go to https://openrouter.ai and create an account or sign in.
- Click on Get API Key section.
- Then click on + New Key.
- Add a name for your key, set a credit limit and expiration, then click on Create.
- Copy the key immediately, as it won’t be shown again.
Next, open your .env file and add your key.
OPENROUTER_API_KEY=your_openrouter_api_key_here
Once added, save the .env file to apply the changes.
Step # 6 : Create AI Controller.
To handle AI requests, create a controller that will connect your frontend with OpenRouter.
php artisan make:controller AIController
Next, open app/Http/Controllers/AIController.php and replace its contents with the following code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Prism\Prism\Facades\Prism;
use Prism\Prism\Enums\Provider;
class AIController extends Controller
{
// Display chat interface
public function index()
{
return view('openrouter');
}
// Handle AJAX request
public function ask(Request $request)
{
// Validate input
$request->validate([
'prompt' => 'required|string'
]);
// Send prompt to OpenRouter
$response = Prism::text()
// OpenRouter auto model (routes to best available model)
->using(Provider::OpenRouter, 'openrouter/auto')
// Attach user prompt
->withPrompt($request->prompt)
// Return text response
->asText();
// Return JSON response
return response()->json([
'answer' => $response->text
]);
}
}
This controller acts as the bridge between your Laravel frontend and OpenRouter through Prism. The index() method loads the chat interface view, while the ask() method handles the incoming user input, validates it, sends the prompt to the AI model, and returns the generated response back to the frontend in JSON format.
Step # 7 : Define Application Routes.
Open routes/web.php and import the controller at the top.
use App\Http\Controllers\AIController;
Now add the following routes.
// Show the OpenRouter chat interface
Route::get('/openrouter', [AIController::class, 'index']);
// Handle AI requests
Route::post('/openrouter', [AIController::class, 'ask']);
The GET route displays the chat interface in the browser, while the POST route handles user input and returns the AI-generated response.
Step # 8 : Create the OpenRouter Chat Interface.
Inside resources/views, create a new file named: openrouter.blade.php and paste the following code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Code Shotcut - Laravel 13 Integrating OpenRouter Using Prism</title>
<script src="https://cdn.tailwindcss.com"></script>
<meta name="csrf-token" content="{{ csrf_token() }}">
<style>
#chatBox::-webkit-scrollbar {
width: 6px;
}
#chatBox::-webkit-scrollbar-thumb {
background: #6d28d9;
border-radius: 10px;
}
#chatBox::-webkit-scrollbar-track {
background: transparent;
}
</style>
</head>
<body class="bg-gradient-to-br from-[#0b0616] via-[#140a2a] to-[#070510] text-white">
<div class="h-screen flex items-center justify-center p-4">
<div class="w-full max-w-4xl h-full flex flex-col rounded-2xl overflow-hidden
border border-purple-500/20 bg-white/5 backdrop-blur-xl shadow-2xl">
<!-- HEADER -->
<div class="px-6 py-4 flex items-center justify-between
border-b border-purple-500/20 bg-[#120a24]/80">
<div>
<h1 class="text-lg font-semibold text-white">Code Shotcut</h1>
<p class="text-xs text-white/70">
Laravel 13 integrating OpenRouter using Prism
</p>
</div>
<div class="w-3 h-3 rounded-full bg-purple-400 shadow-[0_0_12px_#a855f7]"></div>
</div>
<!-- CHAT -->
<div id="chatBox" class="flex-1 overflow-y-auto px-6 py-6 space-y-5 bg-[#0b0616]/60">
<div class="text-center text-white font-medium text-sm mt-10">
👋 Start chatting with AI
</div>
</div>
<!-- INPUT -->
<div class="p-4 border-t border-purple-500/20 bg-[#120a24]/80">
<div class="flex items-end gap-3">
<textarea id="prompt"
rows="1"
class="flex-1 bg-[#0f0a1f]/80 border border-purple-500/20 rounded-xl px-4 py-3 text-sm
text-white placeholder:text-white/60
focus:outline-none focus:ring-2 focus:ring-purple-500
resize-none overflow-hidden"
placeholder="Ask OpenRouter AI..."></textarea>
<button onclick="sendMessage()"
class="bg-gradient-to-r from-purple-600 to-indigo-600
hover:from-purple-500 hover:to-indigo-500
px-6 py-3 rounded-xl text-sm font-medium
text-white shadow-lg shadow-purple-500/20 transition">
Send
</button>
</div>
</div>
</div>
</div>
<script>
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const promptInput = document.getElementById('prompt');
/* ===== ENTER KEY SEND MESSAGE ===== */
promptInput.addEventListener('keydown', function (e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
/* ===== AUTO RESIZE INPUT ===== */
promptInput.addEventListener('input', function () {
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
});
/* ===== APPEND MESSAGE ===== */
function appendMessage(html) {
let chatBox = document.getElementById('chatBox');
chatBox.innerHTML += html;
chatBox.scrollTop = chatBox.scrollHeight;
}
/* ===== OPENROUTER ICON ===== */
function aiIcon() {
return `
<div class="w-9 h-9 rounded-full bg-white flex items-center justify-center shadow-lg overflow-hidden">
<img src="https://openrouter.ai/favicon.ico"
class="w-6 h-6"
alt="OpenRouter">
</div>
`;
}
/* ===== SEND MESSAGE FUNCTION ===== */
async function sendMessage() {
let prompt = promptInput.value.trim();
if (!prompt) return;
/* ===== USER MESSAGE UI ===== */
appendMessage(`
<div class="flex justify-end items-start gap-3">
<div class="bg-purple-600/80 text-white px-4 py-3 rounded-2xl max-w-[75%] text-sm shadow-md">
${prompt}
</div>
<div class="w-9 h-9 rounded-md overflow-hidden border border-white/10 flex-shrink-0">
<img src="https://www.google.com/s2/favicons?domain=codeshotcut.com&sz=128"
class="w-full h-full object-cover"
alt="CodeShotcut Logo">
</div>
</div>
`);
/* ===== RESET INPUT ===== */
promptInput.value = '';
promptInput.style.height = 'auto';
/* ===== LOADING STATE ===== */
let loaderId = Date.now();
appendMessage(`
<div id="${loaderId}" class="flex items-start gap-3">
${aiIcon()}
<div class="bg-purple-500/10 border border-purple-400/10 px-4 py-3 rounded-2xl text-sm text-white animate-pulse">
Generating response...
</div>
</div>
`);
try {
/* ===== API CALL ===== */
let response = await fetch('/openrouter', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({ prompt })
});
let data = await response.json();
/* ===== REMOVE LOADER ===== */
document.getElementById(loaderId).remove();
/* ===== AI RESPONSE UI ===== */
appendMessage(`
<div class="flex justify-start items-start gap-3">
${aiIcon()}
<div class="bg-purple-500/10 border border-purple-400/10 px-4 py-3 rounded-2xl
max-w-[75%] text-sm text-white leading-relaxed">
${data.answer}
</div>
</div>
`);
} catch (error) {
/* ===== ERROR STATE ===== */
document.getElementById(loaderId).remove();
appendMessage(`
<div class="flex items-start gap-3">
<div class="w-9 h-9 rounded-full bg-red-500 flex items-center justify-center text-white text-xs font-bold">
!
</div>
<div class="bg-red-500/10 border border-red-400/20 px-4 py-3 rounded-2xl text-sm text-white">
Failed to connect with OpenRouter API.
</div>
</div>
`);
}
}
</script>
</body>
</html>
The view uses Tailwind CSS to build a modern real-time chat interface with a chat window, a textarea for user input, and a send button that submits messages without reloading the page. When a user sends a message, it is sent via AJAX to the Laravel /openrouter route, where the prompt is processed using the Prism package with OpenRouter AI. The response is then returned as JSON and dynamically displayed inside the chat window. A loading state is shown while waiting for the AI response, and both user and AI messages are appended in real time to create a smooth interactive chat experience inside the Laravel application.
Step # 9 : Run and Test the OpenRouter Integration.
Start your Laravel development server using.
php artisan serve
Now open your browser and visit: http://127.0.0.1:8000/openrouter. You should see your OpenRouter AI chat interface running inside the browser.
Try sending a message to test the flow, your prompt will be sent to Laravel, processed through Prism with OpenRouter, and the AI response will be returned and displayed instantly in the chat window.
Conclusion
By following this guide, you have successfully built an AI-powered chat application in Laravel 13 using the Prism package with OpenRouter. From setting up a fresh Laravel project and configuring Prism with your OpenRouter API key to creating the controller, defining routes, and building a modern real-time chat interface with Blade and Tailwind CSS, you’ve completed a full end-to-end integration. You also implemented AJAX-based communication to send user prompts and display AI-generated responses dynamically with a smooth loading state, giving you a solid foundation to extend this into more advanced AI features like chat assistants, automation tools, or content generation systems.
For more details, refer to the official Prism documentation: https://github.com/prism-php/prism.
Share this with friends!
To engage in commentary, kindly proceed by logging in or registering
Subscribe to Our Newsletter
Stay ahead of the curve! Join our newsletter to see what everyone’s talking about.
0 Comments