Welcome to this step-by-step guide on creating a blog generator using artificial intelligence! We'll be using Next.js, TypeScript, and OpenAI's GPT-4 model to build a web application that can generate blog posts on any topic, in any language. Don't worry if you're not familiar with all these terms – we'll explain everything as we go along!
You can access the codebase from the GitHub repository here.
First, we need to set up our development environment. This involves creating a new project and installing necessary tools.
Navigate to your Desktop (optional, but helps keep things organized) by running the below command:
cd Desktop
Run the following command to create a new project:
npx create-next-app@latest --typescript blog-generator
This command creates a new folder called "blog-generator" with all the necessary files for our project.
Open your terminal
The terminal will ask you some questions. Choose the following options:
Once the project is created, navigate into the new folder:
cd blog-generator
Install additional tools we'll need:
npm install react-markdown remark-gfm rehype-highlight
These tools will help us display the generated blog posts nicely on our webpage.
Now you can close the terminal, and open the project in VS Code
Now that our project is set up, we'll create the main parts of our application.
Replace the content in src/app/page.tsx
with the following code:
// src/app/page.tsx
import Link from "next/link";
import InputForm from "@/components/InputForm";
export default function Home() {
return (
<main>
<nav className="p-5">
<Link href="https://www.builderkit.ai" target="_blank">
<p className="text-xl font-bold">BuilderKit.ai</p>
</Link>
</nav>
<InputForm />
</main>
);
}
This code creates the main structure of our webpage. It includes a navigation bar at the top and a space for our input form.
Create a new file src/app/components/InputForm.tsx
and add the following code:
// src/components/InputForm.tsx
"use client";
import { useState } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import rehypeHighlight from "rehype-highlight";
// This component handles user input to generate a blog using the GPT-4 API
const InputForm = () => {
// State variables to manage the form input and the generated blog content
const [topic, setTopic] = useState("");
const [language, setLanguage] = useState("");
const [blog, setBlog] = useState("");
const [loading, setLoading] = useState(false);
// Handles form submission
const handleSubmit = async (e: any) => {
e.preventDefault(); // Prevents the browser from reloading the page on form submit
setLoading(true);
try {
// Sends a POST request to the API to generate the blog content
const response = await fetch("/api/gpt", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
topic,
language,
}),
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const data = await response.json();
setBlog(data.content);
} catch (error) {
console.error("Failed to generate blog:", error);
} finally {
setLoading(false);
}
};
return (
<div className="max-w-lg mx-auto w-full">
<div className="my-6 text-center">
<h1 className="text-4xl font-medium">AI Blog Generator</h1>
</div>
<form
onSubmit={handleSubmit}
className="flex flex-col gap-3 border p-5 rounded-md border-white/30 text-sm"
>
<h2 className="font-semibold text-lg mb-4">
Create a blog in any language
</h2>
<label className="mb-2">
Topic
<input
type="text"
placeholder="Enter the topic for the blog here"
className="border bg-transparent w-full border-white/30 rounded-md p-1.5 mt-1"
value={topic}
onChange={(e) => setTopic(e.target.value)}
/>
</label>
<label>
Language
<input
type="text"
placeholder="Enter the language you want to generate the blog in"
className="border bg-transparent w-full border-white/30 rounded-md p-1.5 mt-1"
value={language}
onChange={(e) => setLanguage(e.target.value)}
/>
</label>
<button
type="submit"
className="bg-white text-black p-2 mt-5 rounded-md"
disabled={loading}
>
{loading ? "Generating..." : "Generate"}
</button>
</form>
{/* Displays the generated blog content */}
{blog && (
<div className="border p-5 rounded-md border-white/30 mt-5 whitespace-pre-wrap">
<h2 className="font-semibold text-lg">Generated Blog</h2>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeHighlight]}
>
{blog}
</ReactMarkdown>
</div>
)}
</div>
);
};
export default InputForm;
This code creates the form where users can enter a topic and language for their blog. It also handles sending requests to the AI and displaying the generated blog post.
Let's break down what's happening in this component:
useState
to manage the user's input (topic and language) and the generated blog content.handleSubmit
function is called when the user clicks the "Generate" button. It sends a request to our API (which we'll create in the next step) with the topic and language.Now we need to create a way for our application to communicate with the GPT-4 AI. We do this by setting up an API route.
Create a new file src/app/api/gpt/route.ts
and add the following code:
// src/app/api/gpt/route.ts
import { NextRequest } from "next/server";
export async function POST(req: NextRequest) {
try {
// Parse the JSON body from the request to get the topic and language
const { topic, language } = await req.json();
// Retrieve the API key from environment variables
const apiKey = process.env.OPENAI_API_KEY;
// Make a POST request to the OpenAI API to generate the blog content
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
model: "gpt-4o", // Specify the model to use
messages: [
{
role: "system",
content: "Be short and concise.", // Instructions for the model
},
{
role: "user",
content: `Create a blog on the topic of ${topic} in the language ${language}.`, // User's request
},
],
}),
});
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}
// Parse the JSON response from the OpenAI API
const data = await response.json();
// Extract the generated content from the response
const assistantResponse = data.choices[0]?.message?.content;
// Return the generated content as a JSON response
return new Response(JSON.stringify({ content: assistantResponse }), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
} catch (error: any) {
// Return an error response with the error message if something goes wrong
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: {
"Content-Type": "application/json",
},
});
}
}
This code creates an API route that our application uses to communicate with the GPT-4 AI. Here's what it does:
To keep our OpenAI API key secure, we need to set it up as an environment variable.
.env.local
Add the following line to this file:
OPENAI_API_KEY=your_api_key_here
Replace "your_api_key_here" with your actual OpenAI API key.
Now that we have all our components in place, let's start our application:
In your terminal, run:
npm run dev
Open your web browser and go to http://localhost:3000
You should now see your blog generator application running!
It's time to test our blog generator:
After a short wait, you should see a generated blog post appear below the form.
To make our application available on the internet, we can deploy it to Vercel. Here's how:
Push your code to a GitHub repository. Follow the steps below to upload your code in GitHub:
git add .
git commit -m "[commit-message]"
git remote add origin [your-repository-url]
git branch -M main
git push -u origin main
OPENAI_API_KEY
.After a few minutes, Vercel will provide you with a URL where your blog generator is live on the internet!
Congratulations! You've just built a powerful blog generator using artificial intelligence. This application demonstrates how we can leverage advanced language models like GPT-4 to create useful tools.
For those interested in expanding this project, here are some ideas:
Remember, the world of AI and web development is constantly evolving. Keep learning, experimenting, and building!
BuilderKit