O lançamento da família de modelos **Gemini 1.5** pelo Google trouxe avanços significativos para desenvolvedores de software, com destaque para uma janela de contexto gigante de até 2 milhões de tokens e suporte nativo a análises multimodais (leitura de áudio, vídeo, imagens e PDFs).
Neste artigo, vamos construir uma integração profissional utilizando o **Next.js App Router** e o SDK oficial do Google Generative AI para Node.js, mostrando como configurar rotas de API, tratar respostas de forma segura e implementar a renderização de streaming palavra por palavra para melhorar a UX.
1. Configuração do Ambiente e Instalação
Primeiro, você precisará obter uma chave de acesso (API Key) gratuita no **Google AI Studio**. Com a chave em mãos, adicione-a ao seu arquivo de configuração de ambiente local .env.local:
GEMINI_API_KEY=sua_chave_aquiNo diretório do seu projeto Next.js, instale o pacote do SDK oficial da Google:
npm install @google/generative-ai2. Criando o Endpoint de API no Next.js (Route Handler)
Para manter sua chave de API protegida e evitar expô-la no navegador do cliente, todas as chamadas à API do Gemini devem ser feitas através do servidor. Vamos criar um Route Handler no Next.js que retorna as respostas via streaming utilizando Server-Sent Events (SSE).
Crie o arquivo app/api/chat/route.ts:
import { GoogleGenerativeAI } from "@google/generative-ai";
import { NextResponse } from "next/server";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY || "");
export async function POST(req: Request) {
try {
const { prompt } = await req.json();
// Inicializa o modelo Gemini 1.5 Pro
const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro" });
// Executa a chamada gerando stream
const result = await model.generateContentStream(prompt);
// Configura o stream de resposta
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
for await (const chunk of result.stream) {
const text = chunk.text();
controller.enqueue(encoder.encode(text));
}
controller.close();
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/plain; charset=utf-8",
"Transfer-Encoding": "chunked",
},
});
} catch (error) {
return NextResponse.json({ error: "Erro interno do servidor" }, { status: 500 });
}
}3. Consumindo o Stream de IA no Componente React (Client-Side)
No frontend, vamos ler o corpo da resposta como um stream de leitura (ReadableStream) para atualizar o estado da tela progressivamente, garantindo que o usuário veja a IA digitando em tempo real.
Veja a implementação básica do componente de chat:
"use client";
import { useState } from "react";
export default function ChatWindow() {
const [prompt, setPrompt] = useState("");
const [response, setResponse] = useState("");
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setResponse("");
setLoading(true);
try {
const res = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt }),
});
if (!res.body) return;
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
setResponse((prev) => prev + chunk);
}
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}
};
return (
<div className="chat-container">
<form onSubmit={handleSubmit}>
<input
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Escreva sua pergunta..."
/>
<button type="submit" disabled={loading}>Enviar</button>
</form>
<div className="output">{response}</div>
</div>
);
}4. Chamadas Multimodais: Enviando Imagens
Para analisar mídias (como fotos ou capturas de tela), precisamos converter o arquivo enviado em um buffer do tipo Base64 e passá-lo como parte do array de conteúdo do SDK do Gemini:
// Função auxiliar para estruturar arquivos de imagem para o Gemini
function fileToGenerativePart(buffer: Buffer, mimeType: string) {
return {
inlineData: {
data: buffer.toString("base64"),
mimeType
},
};
}
// Executando chamada multimodal no servidor
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const imagePart = fileToGenerativePart(imageBuffer, "image/png");
const result = await model.generateContent([
"Descreva o que você enxerga nesta imagem e liste possíveis bugs de UI.",
imagePart
]);
console.log(result.response.text());Conclusão
Integrar o Gemini 1.5 Pro no Next.js permite que você construa soluções de inteligência artificial de ponta com excelente performance de carregamento no servidor e interfaces interativas no navegador. A combinação de rotas de API seguras, streaming de conteúdo SSE e recursos multimodais nativos abre um leque imenso de aplicações para otimizar os fluxos da sua aplicação web.