Quer aprender como integrar a API Gemini da Google em um projeto real? Vamos construir um gerador de bios para Instagram com Next.js e IA generativa — simples, útil e divertido!

🧰 O que você vai usar:

  • Next.js (App Router)
  • Google AI SDK
  • Gemini 2.0 Flash
  • Tailwind CSS
  • Shadcn

🚀 Resultado final

Um formulário onde a usuária preenche nome e profissão, e recebe bios criativas para usar no Instagram, geradas por IA. Cada bio aparece em um card estilizado.

Image description

📦 Pré-requisitos

  • Conta Google
  • Acesso ao Google AI Studio
  • Chave da API Gemini
  • Projeto Next.js já configurado (pode usar npx create-next-app@latest)

Crie um arquivo .env.local com:

GEMINI_API_KEY=sua-chave-aqui

Instale o SDK:

npm install @google/genai

🧠 Criando a rota API com Gemini

Crie o arquivo app/api/generate-bio/route.ts:

import { NextRequest, NextResponse } from "next/server";
import { GoogleGenAI } from "@google/genai";

const ERROR_MESSAGE_500 = {
  error: "Erro ao gerar bio. Verifique sua chave ou modelo.",
};
const MODEL = "gemini-2.0-flash";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

export async function POST(req: NextRequest) {
  const { name, profession } = await req.json();

  try {
    const prompt = `Crie algumas bios criativa para Instagram com:
    - Nome: ${name}
    - Profissão: ${profession}
    Limite de 150 caracteres. E cada uma em um paragrafo separado.`;

    const result = await ai.models.generateContent({
      model: MODEL,
      contents: prompt,
    });

    const text = result.text?.split("\n").filter((bio) => bio.trim() !== "");

    return NextResponse.json({ bio: text });
  } catch (err) {
    return NextResponse.json(ERROR_MESSAGE_500, { status: 500 });
  }
}

🧾 Formulário para entrada de dados

Crie um componente Form.tsx:

"use client";

import { useRef } from "react";
import { Button } from "./ui/button";
import { Input } from "./ui/input";

interface FormProps {
  handleGeneratedBios: (bios: string[]) => void;
}

export default function Form({ handleGeneratedBios }: FormProps) {
  const nameInputRef = useRef<HTMLInputElement>(null);
  const professionInputRef = useRef<HTMLInputElement>(null);

  const fetchBios = async () => {
    const response = await fetch("/api/generate-bio", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        name: nameInputRef.current?.value || "",
        profession: professionInputRef.current?.value || "",
      }),
    });

    if (!response.ok) {
      console.error("Error generating bio");
      return;
    }

    const { bio } = await response.json();

    handleGeneratedBios(bio);
    if (nameInputRef.current) nameInputRef.current.value = "";
    if (professionInputRef.current) professionInputRef.current.value = "";
  };

  return (
    <form
      className="flex flex-col gap-4"
      onSubmit={(e) => {
        e.preventDefault();
        fetchBios();
      }}
    >
      <Input placeholder="Nome" ref={nameInputRef} />
      <Input placeholder="Profissão" ref={professionInputRef} />
      <Button type="submit">Gerar bio</Button>
    </form>
  );
}

🧠 Renderizando as bios em cards

Crie um componente GeneratedBios.tsx:

import { Card, CardContent } from "@/components/ui/card";

interface Props {
  generatedBios: string[];
}

export default function GeneratedBios({ generatedBios }: Props) {
  return (
    <div className="flex flex-col gap-10 w-full max-w-3xl">
      <div>
        <h2 className="text-xl font-semibold mb-4">Bios Geradas</h2>
        <div className="grid gap-4 md:grid-cols-2">
          {generatedBios.map((bio, index) => (
            <Card key={index}>
              <CardContent className="p-4">{bio}</CardContent>
            </Card>
          ))}
        </div>
      </div>
    </div>
  );
}

🏠 Página principal (app/page.tsx)

"use client";

import Form from "@/components/Form";
import GeneratedBios from "@/components/GeneratedBios";
import { useState } from "react";

export default function Home() {
  const [generatedBios, setGeneratedBios] = useState<string[]>([]);

  const handleGeneratedBios = (bios: string[]) => {
    setGeneratedBios(bios);
  };

  return (
    <main className="flex flex-col min-h-screen justify-between px-6 py-10 sm:px-20 font-sans bg-white text-gray-900">
      <section className="flex flex-col items-center gap-6">
        <h1 className="text-2xl font-semibold text-center">
          Gere sua nova bio do Instagram!
        </h1>

        <Form handleGeneratedBios={handleGeneratedBios} />

        {!!generatedBios.length && (
          <GeneratedBios generatedBios={generatedBios} />
        )}
      </section>

      <footer className="text-sm text-gray-500 text-center mt-12">
        &copy; 2025 Gerador de Bio para Instagram. Todos os direitos reservados.
      </footer>
    </main>
  );
}

💡 Melhorias possíveis

  • Adicionar botão "Copiar"
  • Permitir escolher estilo de bio: profissional, divertida, minimalista…
  • Salvar as favoritas localmente
  • Adicionar animações

🗒️ Notas:

Você pode ter percebido que eu utilizei o componente Button, Card e Input diretamente do shadcn, para fazer isso tem o passo a passo na documentação: https://ui.shadcn.com/docs/components/card

👩🏻‍💻 Link do repo: https://github.com/analiseburtet/gerador-bio-instagram

✨ Conclusão

Você acabou de criar sua primeira integração com Gemini em um projeto Next.js! Um passo simples, mas poderoso, pra explorar as possibilidades da IA generativa nos seus apps.

Curtiu? Salva esse post, compartilha e comenta aqui o que você criaria com Gemini! 🚀