Gemini API Laravel Vue Integration
March 2, 2025 ยท AI Conversations
—
### **1. Get Gemini API Key**
1. Go to [Google AI Studio](https://aistudio.google.com/) and create an API key for Gemini.
—
### **2. Setup Backend in Laravel**
#### **Install Guzzle (If not installed)**
composer require guzzlehttp/guzzle
#### **Configure API Key in .env**
GEMINI_API_KEY=your_api_key_here
#### **Create a Service to Handle API Requests**
Create a new service class for Gemini API:
<?php
namespace AppServices;
use GuzzleHttpClient;
class GeminiService
{
protected $client;
protected $apiKey;
protected $baseUrl;
public function __construct()
{
$this->client = new Client();
$this->apiKey = env('GEMINI_API_KEY');
$this->baseUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent';
}
public function generateResponse($prompt)
{
try {
$response = $this->client->post("{$this->baseUrl}?key={$this->apiKey}", [
'json' => [
'contents' => [
['parts' => [['text' => $prompt]]]
]
]
]);
$body = json_decode($response->getBody(), true);
return $body['candidates'][0]['content']['parts'][0]['text'] ?? 'No response';
} catch (Exception $e) {
return 'Error: ' . $e->getMessage();
}
}
}
#### **Create a Controller to Handle Requests**
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppServicesGeminiService;
class GeminiController extends Controller
{
protected $geminiService;
public function __construct(GeminiService $geminiService)
{
$this->geminiService = $geminiService;
}
public function generate(Request $request)
{
$request->validate([
'prompt' => 'required|string',
]);
$response = $this->geminiService->generateResponse($request->prompt);
return response()->json(['response' => $response]);
}
}
#### **Define Route in API Routes**
use AppHttpControllersGeminiController;
Route::post('/gemini/generate', [GeminiController::class, 'generate']);
—
### **3. Setup Frontend in Vue.js**
#### **Create a Component for User Input**
`resources/js/Components/GeminiChat.vue`
<template>
<div class="chat-container">
<textarea v-model="prompt" placeholder="Enter your question..."></textarea>
<button @click="generateResponse" :disabled="loading">Send</button>
<p v-if="loading">Generating response...</p>
<p v-if="response" class="response">{{ response }}</p>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
prompt: "",
response: "",
loading: false,
};
},
methods: {
async generateResponse() {
if (!this.prompt.trim()) return;
this.loading = true;
this.response = "";
try {
const res = await axios.post("/api/gemini/generate", { prompt: this.prompt });
this.response = res.data.response;
} catch (error) {
console.error("Error fetching response:", error);
this.response = "Failed to generate response.";
} finally {
this.loading = false;
}
},
},
};
</script>
<style scoped>
.chat-container {
max-width: 600px;
margin: auto;
text-align: center;
}
textarea {
width: 100%;
height: 100px;
padding: 10px;
}
button {
margin-top: 10px;
padding: 10px;
cursor: pointer;
}
.response {
margin-top: 15px;
font-weight: bold;
}
</style>
—
### **4. Register Component in Vue Application**
Edit `resources/js/app.js`:
import { createApp } from 'vue';
import GeminiChat from './Components/GeminiChat.vue';
const app = createApp({});
app.component('gemini-chat', GeminiChat);
app.mount('#app');
—
### **5. Use the Component in a Blade File**
Edit `resources/views/app.blade.php`:
@extends('layouts.app')
@section('content')
<div id="app">
<gemini-chat></gemini-chat>
</div>
@endsection
—
### **6. Run the Laravel and Vue App**
1. **Start Laravel Backend**
php artisan serve
2. **Run Vue Frontend (If using Vite)**
yarn dev
—
### **Summary**
โ
**Laravel Backend**
– Created an API service for Gemini AI.
– Set up a route and controller.
โ
**Vue.js Frontend**
– Created a chat component.
– Sent API requests to Laravel.
– Displayed responses.
Now, your Laravel-Vue app can generate AI responses using Google's Gemini API! ๐
### **1. Tailwind's `container` Class Doesn't Include Padding by Default**
The `container` class in Tailwind only **applies a max-width** based on the screen size but does not include padding by default. You need to add padding manually.
#### **Solution: Add `px-4` or `px-6`**
<div class="container mx-auto px-4">
<p>This is inside a Tailwind container.</p>
</div>
๐ `px-4` adds padding on the left and right.
—
### **2. Ensure Tailwind is Configured Properly**
Check if Tailwind is installed correctly and included in your project. Open `tailwind.config.js` and verify:
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.vue",
"./resources/**/*.js",
],
theme: {
extend: {},
},
plugins: [],
};
Then, restart your development server.
—
### **3. Check for Conflicting Styles**
If you're using **custom CSS or another framework (like Bootstrap)**, check if they are overriding Tailwind styles. Use the **`!important`** flag if needed:
<div class="container mx-auto px-4 !important">
Tailwind container
</div>
Or check conflicting styles using **DevTools (F12 โ Elements โ Styles).**
—
### **4. Use `@apply` for Global Padding (Optional)**
If you want to apply padding globally to all containers, add this in your `app.css`:
.container {
@apply px-4;
}
—
### **5. Add Custom Padding in `tailwind.config.js`**
If you want Tailwind to **always** include padding in the `container` class, extend it in `tailwind.config.js`:
module.exports = {
theme: {
container: {
center: true,
padding: '2rem', // Default padding for all containers
},
},
};
Then, restart your server.
—
### **Final Working Example**
<div class="container mx-auto px-4 lg:px-8">
<p>Tailwind container with padding applied</p>
</div>
—
### **โ
Summary**
โ๏ธ Add `px-4` or `px-6` manually.
โ๏ธ Check Tailwind installation and `tailwind.config.js`.
โ๏ธ Inspect for conflicting styles.
โ๏ธ Customize padding in `tailwind.config.js`.
Let me know if the issue persists! ๐
Login
make above stack on mobile
### **Solution**
Modify your `content-class` inside “ by adding `flex-col` for small screens and `md:flex-row` for larger screens:
<SiteLayout content-class="flex flex-col md:flex-row justify-center items-center mt-4 gap-4">
<div class="flex-1 bg-gray-500 h-12">Youtube</div>
<div class="flex-1 bg-gray-400 h-12">Login</div>
</SiteLayout>
### **Explanation**
– `flex-col`: Stacks the elements vertically (default for mobile).
– `md:flex-row`: Changes layout to horizontal (`flex-row`) when the screen size is **`md` (768px)** or larger.
– `gap-4`: Ensures spacing between stacked items.
– **Fixing the color issue:** `bg-white-400` is incorrect; changed to `bg-gray-400`.
—
### **Final Behavior**
โ
**Mobile:** Elements stack on top of each other.
โ
**Desktop (`md` and up):** Elements are side-by-side.
Let me know if you need further tweaks! ๐