Laravel is a PHP framework with expressive, elegant syntax that strives to provide an amazing developer experience while providing powerful features.
In this article, we will build a LinkedIn Bio Generator in Laravel using the REST API of OpenAI. The Tailwind CSS and Livewire part will be for a nice graphical user interface. ✨
At the end, you’ll have a web page where the user will provide one or more keywords that will be sent to OpenAI's API. The API will generate a bio containing those keywords and it will be shown to the user. This web page will look like this :
So let's dive in ! 🚀🚀
Prerequisites
We will create our project using the latest version of Laravel (v10.3 by the time of writing this article). And for this, you should ensure that your local machine has PHP 8.1 or above and Composer installed. In addition, Node and NPM should be installed too.
Project Setup
Let’s create a new project with the following command :
composer create-project laravel/laravel linkedin-bio-generator
Once the project has been created, move to its root directory and run the below command to install the livewire package :
composer require livewire/livewire
Livewire is a full-stack framework that makes building dynamic interfaces simple, without leaving the comfort of Laravel. It simplifies the complexity that Vue or React brings up. 🤩
Next, you can install your application's frontend dependencies via NPM :
npm install
Also, let’s use the OpenAI PHP library to work with the REST API of OpenAI. This library is a supercharged community-maintained PHP API client that allows you to interact with OpenAI API. We have to install it via composer :
composer require openai-php/client
You need to have an API key from OpenAI platform to be able to communicate with their API. If you don’t already have an API key follow this short tutorial to create an account and get it.
Finally, we need to work with Tailwind CSS in our project for a good looking user interface. 😉 Follow this link to know every steps you need for setting up.
Great ! We can now start building our LinkedIn Bio Generator.
Create the user interface
We just need a single input to capture the keywords the AI should include into the LinkedIn Bio and a place where we can show the result.
So, inside the directory resources/views
let’s create a new directory named layouts
which will contain a file named app.blade.php
.
Here’s the content for the resources/views/layouts/app.blade.php
file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>LinkedIn Bio Generator</title>
@vite('resources/css/app.css')
@livewireStyles
</head>
<body>
<nav class="bg-gray-600 px-2 sm:px-4 py-2.5">
<div class="container flex flex-wrap items-center justify-between mx-auto">
<a href="/" class="flex items-center text-white text-2xl">
LinkedIn Bio Generator
</a>
</div>
</nav>
<div class="mx-auto max-w-2xl">
@livewire('show-form')
</div>
@livewireScripts
</body>
</html>
In the code above, we are adding two blade directives (@livewireStyles
and @livewireScripts
) to include the Livewire styles and scripts on the page.
We are also rendering a Livewire component using this instruction: @livewire('show-form')
.
Don't worry, we will create this component right after 😉.
Finally, we are including in the <head>
Tailwind’s utility classes to style our content with this instruction : @vite('resources/css/app.css')
We can now run the following command to generate our Livewire component called showForm
:
php artisan make:livewire showForm
Running this command will generate the following two files :
app/Http/Livewire/ShowForm.php
resources/views/livewire/show-form.blade.php
Let’s update the resources/views/livewire/show-form.blade.php
file by the following content :
<div class="mt-8">
<h1 class="text-4xl font-bold tracking-tight text-zinc-800 sm:text-5xl">
LinkedIn Bio Generator
</h1>
<p class="mt-6 text-base text-zinc-60">
Save time. ⏳
Generate a LinkedIn bio by Artificial Intelligence ! 😋
</p>
<form class="mt-12" wire:submit.prevent="getBio">
<div class="sm:flex sm:w-full sm:max-w-lg">
<div class="min-w-0 flex-1">
<div>
<div class="relative rounded-md shadow-sm">
<input type="text" wire:model.defer="keywords" name="keywords" id="keywords"
class="block w-full rounded-md border
border-gray-300 px-5 py-3 text-base
text-gray-900 placeholder-gray-700
shadow-sm focus:border-teal-500
focus:ring-teal-500 "
placeholder="Type keywords (PHP, Developer, ...)"
>
</div>
<p class="mt-2 text-sm text-red-600" id="keywords-error"></p>
</div>
</div>
<div class="mt-4 sm:mt-0 sm:ml-3">
<button type="submit" class="block w-full rounded-md border border-transparent
bg-gray-600 px-5 py-3 text-base font-medium text-white shadow
hover:bg-emerald-500 focus:outline-none focus:ring-2 focus:ring-teal-500
focus:ring-offset-2 sm:px-10"
>
Get my biooo 🍾 🍾
</button>
</div>
</div>
</form>
<div>
@if ($bio)
<h2 class="mt-4 mb-1 text-2xl font-medium">Your awesome bio!</h2>
<div class="mb-12 bg-gray-100 text-grey-900 p-4 rounded-lg">
{{$bio}}
</div>
@endif
<div wire:loading.flex class="hidden p-6 justify-center">
<div role="status">
<svg class="inline mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-gray-600 dark:fill-gray-300" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"></path>
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"></path>
</svg>
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
</div>
In the above code, we just created a single input to capture the keywords the AI should include into the LinkedIn Bio and a place where we can show the result.
Finally, add a resources/views/home.blade.php
file with this content : @extends('layouts.app')
Use the AI power
Open the app/Http/Livewire/ShowForm.php
file and update it with the following code :
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use OpenAI;
class ShowForm extends Component
{
public $bio;
public $keywords;
public function render()
{
return view('livewire.show-form');
}
public function getBio()
{
$key = config('services.open_ai.api_key');
$client = OpenAI::client($key);
$result = $client->completions()->create([
'model' => 'text-davinci-003',
'prompt' => 'Write a LinkedIn bio including the keywords: ' . $this->keywords,
'max_tokens' => 256,
'temperature' => 1
]);
$this->bio = $result->choices[0]->text;
}
}
As you can see in this file, we added the getBio()
method to our component and here are the explanations :
1. Get the value of the API key
$key = config('services.open_ai.api_key');
For this, let’s add in the .env
file a new line providing the OpenAI API key :
OPENAI_API_KEY="xxxxxxxxxxxx"
Then, in the config/services.php
we also need some new lines :
'open_ai' => [
'api_key' => env('OPENAI_API_KEY')
],
2. Create a client that will interact with the OpenAI API
$client = OpenAI::client($key);
3. Call the OpenAI completions endpoint
$result = $client->completions()->create([
'model' => 'text-davinci-003',
'prompt' => 'Write a LinkedIn bio including the keywords: ' . $this->keywords,
'max_tokens' => 256,
'temperature' => 1
]);
We create a completion for the provided prompt and parameters.
model
parameter specifies the ID of the model to use.
The OpenAI API is powered by a diverse set of models with different capabilities. Here, we are using davinci
which is the most capable GPT-3 model.
Then we create a prompt
which we pass to the AI to complete.
max_tokens
is the maximum number of tokens to generate in the completion. 256 tokens lead to a maximal length of around 1000 characters. To learn more about the tokens see the documentation.
temperature
provides the sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random/creative, while lower values like 0.2 will make it more focused and deterministic.
4. Get the result
$this->bio = $result->choices[0]->text;
We finally get our LinkedIn bio text generated by OpenAI API. 🚀
Running the project
Before running the project, let’s register a web route to our nice page. So, open the /routes/web.php
and add the following lines of code :
Route::get('/get-bio', function () {
return view('home');
});
Great! Everything is finally ready to run our application.🥳
Then start the server with the following command :
php artisan serve
And run npm run dev
for the Tailwind CSS build process.
Now, we can access our application in the browser at http://127.0.0.1:8000/get-bio
.
Summary
In this article, we’ve learned how to build a LinkedIn Bio Generator in Laravel using the REST API of OpenAI, Livewire and Tailwind CSS.
And as every article can be made better so your suggestions or questions are welcome in the comment section. 😉
Check the code of this tutorial here.
Top comments (0)