NextJS + GPT-3: Build a cover letter generator
Tags: gpt3, nextjs, javascript, tutorial
Published: 2023-01-07 07:29:02

Learn how to build a cover letter generator. This app would generate a cover letter based on your skills and experience.


### Overview
In this article, we will learn how to use GPT-3 (short for "Generative Pre-trained Transformer 3") in a simple way to create cover letters. OpenAI has developed a powerful language processing tool. It can be used to generate human-like text by predicting the next word in a sequence based on the context of the input.
To use GPT-3 for cover letter generation, you will need to provide it with some input. This can include information about the job you are applying for, your experience and skills, and any other information you want to include. Based on this input, the GPT-3 model will generate a cover letter.
One benefit of GPT-3 for cover letter generation is that it can save you time and effort. Instead of spending hours writing the perfect cover letter, you can use GPT-3 and let it do the work for you. Additionally, GPT-3 can produce highly personalized and professional-sounding cover letters that are tailored to the specific job you are applying for.
Overall, using GPT-3 for cover letter generation can be a valuable tool to increase your chances of landing an interview and streamline the job application.


###What we’ll cover
- Creating the NextJs app.
- Getting GPT-3 API keys from OpenAI
- Adding GPT-3 API functionality on our React app
- Writing optimal GPT-3 prompts.

The source code for the final version can be found [here](https://github.com/orlando70/cover-letter-generator). You can also check out the live [demo](https://cover-letter-generator-alpha.vercel.app/)!


###Setup

The easiest way to get started with a NextJS project is to use the create-next-app template. It allows you to start building a new NextJS app quickly, without having to set up a build configuration yourself.

To get started, open your command line and run the code below

```
npx create-next-app cover-letter-generator
```
The _cover-letter-generator_ in the command above is the folder name of our project. You can choose any name of your choice.

Alternatively, You can use yarn by running

```
yarn create-next-app
```
This will create a modern structure for a NextJS application and install all necessary dependencies to get your simple app ready.

After the setup is complete, you will navigate to the newly created folder by running

```
cd cover-letter-generator
```
Ensure you replace _cover-letter-generator_ with the folder name you used.

Now you have to run the command below to check if the setup is successful

```
npm run dev
```
Your app should start on a URL in this form http://localhost:3000

Open it with your browser and you will see a page similar to this

![NextJs project home page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6g03x7ilk1n2904xc1t.png)

###Get your API key from OpenAI

To build an app powered by GPT-3, you need access to an API Key from OpenAI.


1. To get started with OpenAI, open this [link](https://openai.com/api/).
2. Click on _Signup _and complete the signup process.
3. Next, you will be redirected to the dashboard.
4. Click on _Personal _and then _View API Keys_.
5. On the API Keys section, click on _Create new secret key_ and copy it.

To prevent the secret key for calling the OpenAI GPT-3 API from being exposed in the browser, we will create our own API endpoint which will make the actual call to the GPT-3 endpoint.

To use your OpenAI API key in your project:

Create a file called `.env` in the project directory

Add the following line to the file, replacing "your-api-key" with your actual API key this way

```
OPEN_AI_KEY=your-api-key
```
Make sure to include `.env` in your `.gitignore` file before committing your code to a git repository. This will prevent your API key from being publicly exposed, which could lead to misuse and potentially result in your API key being suspended by OpenAI.


###Add dependencies

To continue, you must install the dependencies required for this app. This can be done using the following command

```
npm i openai axios
```
Now, we create a file called `generate.js` in the pages/api directory. Then, add the following code to the file.

```

import { Configuration, OpenAIApi } from 'openai';

export default async function handler(req, res) {
  const { company, experience, skills, name, position } = req.body;

  const configuration = new Configuration({
    apiKey: process.env.OPEN_AI_KEY,
  });

  const openai = new OpenAIApi(configuration);

  const prompt = `Hello, AI! I'm a cover letter writer and I need your help crafting a perfect letter for a job seeker named ${name}. They're applying to work at ${company} as a ${position}, and they have ${experience} years of experience and the following skills: ${skills}. Can you please write a cover letter that highlights their relevant experience and skills, and explains why they're a great fit for the position? Make it engaging and persuasive, but keep it professional. Thanks!`

    const response = await openai.createCompletion({
      prompt,
      temperature: 0.7,
      max_tokens: 1024,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      model: 'text-davinci-003',
    });
  
    res.status(200).send(response.data.choices[0].text)
}
```
Here's a step by step explanation of the code:

1. We start by importing the Configuration and OpenAIApi components from the openai library.
2. Next, we create a new Configuration object and pass in an object containing the API key from our `.env` file.
3. We use the Configuration object to create a new instance of the OpenAIApi class.
4. We define a prompt string that includes placeholders for the name, company, position, experience, and skills variables. This prompt is a request for the AI to write a cover letter for a job seeker with the provided information.
5. We use the createCompletion method from the OpenAIApi instance to generate a response based on the prompt. We pass in an object containing various configuration options such as temperature, max_tokens, and model.


Then, we include code in the user interface that will call this API when necessary. The API's output will be displayed to the user through the interface.

Replace the code from the `pages/index.js` with this.
```

import { useState, React } from 'react';
import axios from 'axios';
import Head from 'next/Head';
import styles from "../styles/Home.module.css";

const App = () => {
  const [formData, setFormData] = useState({
    company: '',
    name: '',
    skills: '',
    position: '',
    experience: ''
  });
  const [result, setResult] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  const handleChange = (e) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  }

  const handleSubmit = async (e) => {
    e.preventDefault();
    setIsLoading(true);
    try {
      const result = await axios.post('/api/generate', formData);
      setResult(result.data);
    } catch (err) {
      setError(err);
    }
    setIsLoading(false);
  }

  const handleCopy = () => {
    navigator.clipboard.writeText(result);
  }
  return (
    <>
      <Head>
        <title>Generate Cover Letter</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </Head>
      <div className={styles.container}>
        <div className={styles.wrapper}>
          <header className={styles.header}>
            <p>Generate a <span>Cover Letter</span> in seconds.</p>
          </header>
          <form className={styles.form} onSubmit={handleSubmit}>
            <label>
              Company:
              <input type="text" name="company" value={formData.company} onChange={handleChange} />
            </label>
            <br />
            <label>
              Name:
              <input type="text" name="name" value={formData.name} onChange={handleChange} />
            </label>
            <br />
            <label>
              Position:
              <input type="text" name="position" value={formData.position} onChange={handleChange} />
            </label>
            <br />
            <label>
              Skills:
              <textarea name="skills" value={formData.skills} onChange={handleChange} />
            </label>
            <br />
            <label>
              Years of Experience:
              <input type="number" name="experience" value={formData.experience} onChange={handleChange} />
            </label>
            <br />
            <button className={styles.button} type="submit">Generate Cover Letter</button>
            {result && <button className={styles.button} onClick={handleCopy}>Copy to Clipboard</button>}
            {isLoading && <p>Generating cover letter...</p>}
            {error && <p>An error occurred: {error.message}</p>}
            <br />
            <br />
            {result && <p className={styles.result}> {result}</p>}
          </form>
        </div>
      </div>
    </>
  )
}

export default App;
```
Start the development server by running _npm run dev_ and this would appear
![Homepage of cover-letter-generator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igesjx750b799ndgq54y.png)

Checkout the complete code on [Github](https://github.com/orlando70/cover-letter-generator)

To quickly generate a cover letter, fill up the form appropriately and click _Generate Cover Letter_

## **Conclusion**
In this article, we have learnt how the integration of Next.js and GPT-3 has resulted in a powerful and user-friendly cover letter generator. By leveraging the advanced language generation capabilities of GPT-3, this tool is able to provide highly personalized cover letter suggestions that can help job seekers stand out in a competitive job market. Overall, this innovative solution has the potential to revolutionize the way that job seekers approach the cover letter writing process, making it easier than ever before to craft a compelling and effective document.