DEV Community

Cover image for Build a LinkedIn Bio Generator in Laravel using the REST API of OpenAI, Livewire and Tailwind CSS.
Newton Boco
Newton Boco

Posted on

Build a LinkedIn Bio Generator in Laravel using the REST API of OpenAI, Livewire and Tailwind CSS.

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 :

Image description

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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. &#9203;
        Generate a LinkedIn bio by Artificial Intelligence ! &#128523;
    </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 &#127870; &#127870;
                </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>
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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');
Enter fullscreen mode Exit fullscreen mode

For this, let’s add in the .env file a new line providing the OpenAI API key :

OPENAI_API_KEY="xxxxxxxxxxxx"
Enter fullscreen mode Exit fullscreen mode

Then, in the config/services.php we also need some new lines :

'open_ai' => [
        'api_key' => env('OPENAI_API_KEY')
],
Enter fullscreen mode Exit fullscreen mode

2. Create a client that will interact with the OpenAI API

$client = OpenAI::client($key);
Enter fullscreen mode Exit fullscreen mode

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 
        ]);
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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');
});

Enter fullscreen mode Exit fullscreen mode

Great! Everything is finally ready to run our application.🥳

Then start the server with the following command :

php artisan serve  
Enter fullscreen mode Exit fullscreen mode

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.

Image description

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)