Build an AI Content Summarizer
Build a full-stack AI summarizer with Next.js, TypeScript, and Google Gemini.
Introduction
30 Second Summary
Every day, you encounter articles, reports, and documents that are too long to read in full. What if you could paste any text into a web app and get a perfect summary back instantly?
In this project, you will build an AI-powered content summarizer that streams responses in real-time, word by word. You'll deploy it live on the internet with a shareable URL for your portfolio.
What You'll Build
A full-stack web application built with Next.js, TypeScript, and Tailwind CSS that connects to Google's Gemini AI to generate streaming text summaries.
By the end of this project, you'll have:
- A Next.js 16 application with a streaming API endpoint powered by Google Gemini.
- A responsive React frontend that displays AI-generated summaries in real-time as they arrive.
- A live deployment on Vercel connected to your GitHub repository with automatic deployments on every push.
- Secret Mission: Add multiple summarization modes (brief, detailed, bullet points) with a mode selector UI.
Are there any prerequisites?
No prior experience with Next.js, TypeScript, or AI APIs is required. This guide walks you through setting up every tool from scratch, including VS Code, Node.js, and your free Google Gemini API key.
Set Up Your Development Environment
Every web application starts with a solid foundation. Before you can build the AI summarizer, you need a project structure, the right packages, and a version-controlled repository to track your work.
In this step, you will scaffold a Next.js 16 project, install the AI SDK packages that connect to Google's Gemini API, and push everything to GitHub.
In this step, get ready to:
- Create a Next.js project with TypeScript and Tailwind CSS.
- Install the AI SDK packages and configure your Gemini API key.
- Push your project to GitHub.
Create the Next.js project
Next.js is a React framework that gives you routing, server-side rendering, and API routes out of the box. You will use its scaffolding tool to generate a ready-to-go project in one command.
- Open your terminal. Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar, type Terminal (macOS) or PowerShell (Windows), and press Enter.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your Next.js project by running this command:
npx create-next-app@latest ai-summarizer
What will this command ask?
The create-next-app wizard will ask two questions:
- What is your project named? Press Enter to accept ai-summarizer (already filled in from the command).
- Would you like to use the recommended Next.js defaults? Select Yes, use recommended defaults and press Enter. This gives you TypeScript, ESLint, Tailwind CSS, and App Router.
- Move into your new project folder by running:
cd ai-summarizer
- Open the project in VS Code by running:
code .
Now update the default layout file so it matches what you need for this project.
- In the VS Code Explorer sidebar, open app/layout.tsx.
- Select all the existing code (Cmd+A on macOS, Ctrl+A on Windows) and replace it with the following:
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "AI Content Summarizer",
description: "Summarize any text using AI-powered streaming responses",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
What does this code do?
This is the root layout that wraps every page in your app. It sets the page title and description that appear in browser tabs and search results.
You removed the default font imports and extra classNames to keep things simple. The globals.css import brings in Tailwind CSS utilities that you will use for styling later.
- Save app/layout.tsx.
- Start the development server. Open the VS Code terminal panel with Ctrl+` and run:
npm run dev
- Open your browser and go to http://localhost:3000. You should see the default Next.js welcome page.
Don't see the welcome page?
- Make sure the terminal shows no errors. If you see a port conflict, stop any other local server and run npm run dev again.
- Check that you are inside the ai-summarizer folder before running the command.
Why isn't my Next.js dev server starting?
Install the AI SDK packages and configure your API key
The Vercel AI SDK provides a unified way to connect to AI models. You will install two packages: the core SDK and the Google provider that talks to Gemini.
- Stop the dev server by pressing Ctrl+C in the terminal.
- Install the AI SDK packages by running:
npm install ai @ai-sdk/google
- You should see the packages added to your package.json dependencies after the install finishes.
Install command failed?
- Make sure you are inside the ai-summarizer folder. Run pwd to check your current directory.
- If you see a permissions error, try running the command again. Temporary network issues can cause npm installs to fail.
Why is npm install failing in my Next.js project?
Now you need a Gemini API key. Google offers a free tier for the Gemini API, so this costs nothing.
- Open Google AI Studio in your browser.
- Sign in with your Google account if prompted.
- Click Create API Key.
- Copy the generated key. You will only see it once, so keep this tab open until you have pasted it.
Why is Gemini free?
Google offers a free tier for the Gemini API with free input and output tokens. For a portfolio project like this, you will stay well within the free limits.
- In VS Code, create a new file in the root of your project called .env.local. Right-click in the Explorer sidebar (not inside the app folder) and select New File.
- Name the file .env.local and add the following content, replacing your-api-key-here with the key you just copied:
GOOGLE_GENERATIVE_AI_API_KEY=your-api-key-here
What is .env.local?
This file stores environment variables that Next.js loads automatically. The GOOGLE_GENERATIVE_AI_API_KEY variable is the name the AI SDK's Google provider expects.
The .env.local file is already listed in .gitignore by default, so your secret key will never be pushed to GitHub.
- Save .env.local.
Initialize Git and push to GitHub
Version control lets you track changes and deploy automatically later. The create-next-app command already initialized a Git repository for you, so you just need to connect it to GitHub.
- Open GitHub in your browser and create a new repository.
- Click the + icon in the top-right corner of GitHub, then select New repository.
- Name it ai-summarizer.
- Leave all other settings at their defaults (public, no README, no .gitignore).
- Click Create repository.
GitHub will show you a page with setup commands. Use the following in your VS Code terminal:
- Stage and commit your project files by running:
git add .
git commit -m "Initial commit: Next.js project with AI SDK"
- Connect your local repo to GitHub and push by running these commands, replacing the URL with your own repository URL:
git remote add origin [[YOUR_REPO_URL="https://github.com/YOUR_USERNAME/ai-summarizer.git"]]
git branch -M main
git push -u origin main
- Refresh your GitHub repository page in the browser. You should see all your project files listed.
Push rejected or authentication failed?
- If you see an authentication error, make sure you are signed in to GitHub in your terminal. Run gh auth login if you have the GitHub CLI, or set up an SSH key.
- If the push is rejected because the remote already has a README, delete the GitHub repo and recreate it without initializing any files.
Why can't I push to my GitHub repository?
✔️ Awesome, I've got everything!
Great. Double check you have saved all files before moving on.
ⓧ I'd like to double check the full code
Here is what .env.local should look like (with your own key):
GOOGLE_GENERATIVE_AI_API_KEY=your-api-key-here
Here is what app/layout.tsx should look like:
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "AI Content Summarizer",
description: "Summarize any text using AI-powered streaming responses",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Your development environment is ready. You have a running Next.js app, the AI SDK installed, and your code safely stored on GitHub. Next up, you will build the streaming API route that talks to Gemini.
Build the Streaming AI API Route
Your app needs a backend endpoint that receives text from the user, sends it to Google Gemini, and returns the AI's response. Instead of waiting for the entire summary to generate before showing anything, you'll stream the response back word by word.
In this step, you'll create a Next.js API route that connects to the Gemini AI model and streams its response back to the client in real time.
In this step, get ready to:
- Create a streaming API endpoint using the Vercel AI SDK.
- Configure a system prompt that produces quality summaries.
- Test the endpoint locally to confirm streaming works.
Create the API route file
Next.js App Router uses the file system to define routes. A file at app/api/summarize/route.ts automatically becomes an endpoint at /api/summarize.
- In the VS Code Explorer sidebar, right-click the app folder and select New Folder.
- Name the folder api.
- Right-click the new api folder and create another folder called summarize.
- Right-click the summarize folder and select New File.
- Name the file route.ts.
- Add the following code to route.ts:
import { streamText } from "ai";
import { google } from "@ai-sdk/google";
export async function POST(req: Request) {
// Extract the text field from the request body
const { text } = await req.json();
// Call Gemini with streaming enabled
const result = streamText({
model: google("gemini-2.5-flash"),
system:
"You are a helpful content summarizer. Provide clear, concise summaries that capture the key points of the given text. Use well-structured paragraphs.",
prompt: `Please summarize the following text:\n\n${text}`,
});
// Return the response as a streaming HTTP response
return result.toTextStreamResponse();
}
What does this code do?
- streamText from the ai package is the Vercel AI SDK's function for generating streaming text from any supported model.
- google("gemini-2.5-flash") selects the Gemini 2.5 Flash model, which is fast and available on the free tier.
- The system property tells the AI how to behave for every request. It acts as persistent instructions that shape every response.
- The prompt property passes the user's text to the AI, asking it to summarize.
- toTextStreamResponse() converts the AI's output into a streaming HTTP response that sends text chunks as they're generated.
- Save route.ts.
- You won't see a change in the browser yet. You'll test this endpoint in the next substep.
Seeing a red squiggly line in VS Code?
- Make sure the folder structure is exactly app/api/summarize/route.ts. A misnamed folder breaks the route.
- Check that the ai and @ai-sdk/google packages are installed. If VS Code can't find the imports, re-run npm install in your terminal.
Help me fix import errors in my Next.js API route
Understand the system prompt and streaming response
Why this system prompt?
The system property is like giving the AI a job description before it starts working. Without it, the model might respond conversationally or add unnecessary preamble.
Your system prompt asks for "clear, concise summaries" and "well-structured paragraphs." These constraints help the AI produce focused output instead of rambling responses. You can tweak this prompt later to change the AI's behavior without touching any other code.
What is streaming?
Without streaming, the user waits in silence until the entire summary is generated. With streaming, each word appears as soon as the AI produces it. This makes the app feel fast and responsive, even for long summaries.
toTextStreamResponse() handles all the complexity of converting the AI's token-by-token output into a standard HTTP streaming response. The frontend can then read this stream and display text progressively.
Test the API route locally
Your dev server from Step 1 should still be running. You can test the API route using a terminal command to send a POST request directly to your endpoint.
- Open a new terminal window in VS Code by pressing Cmd+Shift+` (macOS) or Ctrl+Shift+` (Windows).
- Test the API by running this command:
curl -N -X POST http://localhost:3000/api/summarize \
-H "Content-Type: application/json" \
-d '{"text": "Artificial intelligence is transforming industries worldwide. Machine learning algorithms can now process vast amounts of data to identify patterns and make predictions. This technology is being applied in healthcare, finance, transportation, and many other sectors to improve efficiency and outcomes."}'
What should I see?
You should see summary text appearing in your terminal, streaming in progressively rather than all at once. The response is plain text, not JSON. It might take a second for the first words to appear as Gemini processes your request.
- Confirm that you see AI-generated summary text streaming into your terminal.
Not seeing any response?
- Make sure your dev server is still running in the other terminal. If it stopped, run npm run dev again.
- Check your .env.local file. The key must be named exactly GOOGLE_GENERATIVE_AI_API_KEY and contain a valid API key from Google AI Studio.
- If you see a 500 error, check the terminal running your dev server for a more detailed error message. A common cause is an invalid or expired API key.
- If you hit a rate limit (429 error), wait one minute and try again. The Gemini free tier has per-minute request limits.
Help me debug my streaming API route
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before moving on.
ⓧ I'd like to double check the full code
Here's the complete app/api/summarize/route.ts file:
import { streamText } from "ai";
import { google } from "@ai-sdk/google";
export async function POST(req: Request) {
const { text } = await req.json();
const result = streamText({
model: google("gemini-2.5-flash"),
system:
"You are a helpful content summarizer. Provide clear, concise summaries that capture the key points of the given text. Use well-structured paragraphs.",
prompt: `Please summarize the following text:\n\n${text}`,
});
return result.toTextStreamResponse();
}
Your backend is live and streaming. Next up, you'll build the frontend UI that lets users paste text and watch the summary appear in real time.
Build the Frontend UI
Your API route is ready to stream AI summaries. Now you need a way for users to actually interact with it.
In this step, you'll build the frontend page that sends text to your API and displays the AI-generated summary as it streams in, word by word.
In this step, get ready to:
- Create the main page component with a text input area, submit button, and output display.
- Implement streaming logic to display the AI response progressively as it arrives.
- Add loading states, error handling, and polished Tailwind CSS styling.
Create the page component
In Next.js, the app/page.tsx file defines what users see when they visit the root URL. The scaffolded project already has a default page with placeholder content. You'll replace it entirely with your summarizer UI.
- In VS Code, open app/page.tsx from the file explorer sidebar.
- Select all the existing content (Cmd+A on macOS or Ctrl+A on Windows) and delete it.
- Replace it with the following component code:
"use client";
import { useState } from "react";
export default function Home() {
const [inputText, setInputText] = useState("");
const [summary, setSummary] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState("");
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
if (!inputText.trim()) return;
setIsLoading(true);
setSummary("");
setError("");
try {
const response = await fetch("/api/summarize", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: inputText }),
});
if (!response.ok) {
throw new Error("Failed to generate summary");
}
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
throw new Error("No reader available");
}
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
setSummary((prev) => prev + chunk);
}
} catch (err) {
setError(err instanceof Error ? err.message : "Something went wrong");
} finally {
setIsLoading(false);
}
}
return (
<main className="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 p-8">
<div className="max-w-3xl mx-auto">
<header className="text-center mb-10">
<h1 className="text-4xl font-bold text-white mb-2">
AI Content Summarizer
</h1>
<p className="text-slate-400">
Paste any text and get an AI-powered summary in seconds
</p>
</header>
<form onSubmit={handleSubmit} className="space-y-4">
<textarea
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="Paste your text here..."
className="w-full h-48 p-4 rounded-lg bg-slate-700 text-white placeholder-slate-400 border border-slate-600 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none resize-none"
/>
<button
type="submit"
disabled={isLoading || !inputText.trim()}
className="w-full py-3 px-6 rounded-lg bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-semibold transition-colors"
>
{isLoading ? "Summarizing..." : "Summarize"}
</button>
</form>
{error && (
<div className="mt-6 p-4 rounded-lg bg-red-900/50 border border-red-700 text-red-200">
{error}
</div>
)}
{summary && (
<div className="mt-6 p-6 rounded-lg bg-slate-700/50 border border-slate-600">
<h2 className="text-lg font-semibold text-white mb-3">Summary</h2>
<p className="text-slate-300 leading-relaxed whitespace-pre-wrap">
{summary}
</p>
</div>
)}
</div>
</main>
);
}
What does this code do?
This is a React Client Component (marked with "use client" at the top). It uses four state variables to manage the UI:
- inputText stores what the user types into the textarea.
- summary accumulates the AI's streamed response chunk by chunk.
- isLoading tracks whether a request is in progress (disables the button and changes its text).
- error holds any error message to display if the request fails.
The JSX renders a form with a textarea, a submit button, a conditional error banner, and a conditional summary display area.
- Save app/page.tsx.
- Switch back to your browser at http://localhost:3000. You should see a dark gradient background with a centered heading that says "AI Content Summarizer", a large textarea, and a blue "Summarize" button.
Don't see the new page?
- Make sure your dev server is still running in the terminal. If it stopped, run npm run dev again.
- Check for red error text in the terminal. A missing quote or bracket in the JSX will prevent the page from compiling.
- Confirm you saved the file. Unsaved changes won't trigger a refresh.
Why isn't my page showing the new UI?
Understand the streaming logic
The most interesting part of this component is how it reads a streaming response from the server. Instead of waiting for the entire summary to arrive at once, it displays each word as the AI generates it.
Here's the key section inside handleSubmit that makes streaming work:
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
throw new Error("No reader available");
}
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
setSummary((prev) => prev + chunk);
}
How does streaming work here?
When your API route returns a streaming response, the browser receives it as a ReadableStream. The code reads this stream piece by piece:
- response.body?.getReader() creates a reader that can pull chunks from the stream one at a time.
- TextDecoder converts raw binary data (bytes) into readable text strings.
- The while (true) loop keeps reading chunks until done is true, meaning the server has finished sending data.
- setSummary((prev) => prev + chunk) appends each new piece of text to what's already displayed, creating the real-time typing effect.
This pattern is the standard way to consume streaming responses in modern browsers. It gives users immediate feedback instead of making them wait for the full response.
Test the full app end-to-end
Your frontend and API route are now connected. Time to test the complete flow with real text to confirm everything works together.
- Switch back to your browser at http://localhost:3000.
- Paste a few paragraphs of text into the textarea. Any article excerpt or Wikipedia paragraph works well.
- Click the Summarize button.
You should see the button text change to "Summarizing..." while the request is in progress. After a moment, text should start appearing in the Summary section below the form, streaming in progressively.
What should I see?
- The button disables and shows "Summarizing..." during the request.
- The summary appears word by word (or in small chunks) below the form in a bordered card.
- Once the stream finishes, the button re-enables and returns to "Summarize".
- If you try submitting with an empty textarea, nothing happens (the form validates that input exists).
Seeing an error message instead of a summary?
- A red error banner means the API route returned a non-200 response. Check your terminal for error details from the server.
- If you see a rate-limit error, wait about a minute and try again. The Gemini free tier has tight rate limits for rapid requests.
- Confirm your .env.local file has a valid GOOGLE_GENERATIVE_AI_API_KEY value. If you changed it, restart the dev server with npm run dev.
Help me debug why my summarizer returns an error instead of a streaming response.
Why streaming instead of waiting?
A traditional API call would make the user stare at a loading spinner for several seconds until the entire summary is ready. Streaming shows results immediately as the AI generates them. This makes the app feel much faster and more responsive, even though the total time is the same.
Most modern AI applications (ChatGPT, Gemini, Claude) use this exact pattern to provide a better user experience.
✔️ Awesome, I've got everything!
Great. Double check you've saved app/page.tsx and confirmed the streaming summary works in your browser.
ⓧ I'd like to double check the full code
Here's the complete app/page.tsx file. Make sure yours matches exactly:
"use client";
import { useState } from "react";
export default function Home() {
const [inputText, setInputText] = useState("");
const [summary, setSummary] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState("");
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
if (!inputText.trim()) return;
setIsLoading(true);
setSummary("");
setError("");
try {
const response = await fetch("/api/summarize", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: inputText }),
});
if (!response.ok) {
throw new Error("Failed to generate summary");
}
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
throw new Error("No reader available");
}
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
setSummary((prev) => prev + chunk);
}
} catch (err) {
setError(err instanceof Error ? err.message : "Something went wrong");
} finally {
setIsLoading(false);
}
}
return (
<main className="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 p-8">
<div className="max-w-3xl mx-auto">
<header className="text-center mb-10">
<h1 className="text-4xl font-bold text-white mb-2">
AI Content Summarizer
</h1>
<p className="text-slate-400">
Paste any text and get an AI-powered summary in seconds
</p>
</header>
<form onSubmit={handleSubmit} className="space-y-4">
<textarea
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="Paste your text here..."
className="w-full h-48 p-4 rounded-lg bg-slate-700 text-white placeholder-slate-400 border border-slate-600 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none resize-none"
/>
<button
type="submit"
disabled={isLoading || !inputText.trim()}
className="w-full py-3 px-6 rounded-lg bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-semibold transition-colors"
>
{isLoading ? "Summarizing..." : "Summarize"}
</button>
</form>
{error && (
<div className="mt-6 p-4 rounded-lg bg-red-900/50 border border-red-700 text-red-200">
{error}
</div>
)}
{summary && (
<div className="mt-6 p-6 rounded-lg bg-slate-700/50 border border-slate-600">
<h2 className="text-lg font-semibold text-white mb-3">Summary</h2>
<p className="text-slate-300 leading-relaxed whitespace-pre-wrap">
{summary}
</p>
</div>
)}
</div>
</main>
);
}
Your AI Content Summarizer is fully functional locally. Next up, you'll deploy it live to the internet so anyone can use it.
Deploy to Vercel and Create Your Portfolio README
Your AI Content Summarizer works locally. Now it is time to put it on the internet where anyone can use it.
In this step, you will deploy your app to Vercel, a hosting platform built by the Next.js team. Vercel auto-detects Next.js projects and gives you a live URL in minutes. You will also write a professional README to make your GitHub repository portfolio-ready.
In this step, get ready to:
- Deploy your app to Vercel with a live, shareable URL.
- Verify automatic deployments work when you push to GitHub.
- Write a professional README.md for your portfolio.
Sign up for Vercel and deploy your app
Vercel is free for personal projects on its Hobby plan. You will sign up with your GitHub account, import your repository, and add the environment variable your API route needs.
- Open your browser and go to vercel.com/new.
- Click Continue with GitHub to sign up or sign in with your GitHub account.
- Authorize Vercel to access your GitHub repositories when prompted.
What is the Vercel Hobby plan?
The Hobby plan is free forever and designed for non-commercial, personal projects. It includes up to 100 GB of bandwidth, 1,000,000 serverless function invocations per month, and up to 100 deployments per day. Perfect for portfolio apps.
- Find your AI summarizer repository in the list and click Import next to it.
- Vercel auto-detects Next.js as the framework preset. Leave the default settings as they are.
- Expand the Environment Variables section.
- In the Key field, enter GOOGLE_GENERATIVE_AI_API_KEY.
- In the Value field, paste your Google Gemini API key (the same one from your .env.local file).
- Click Deploy.
Why add the environment variable here?
Your .env.local file is excluded from Git (it is in .gitignore), so Vercel cannot read it. You must add GOOGLE_GENERATIVE_AI_API_KEY directly in Vercel's dashboard so the deployed app can access it at runtime.
Vercel will now build your project and deploy it. This usually takes 30 to 60 seconds.
Once complete, you will see a confirmation page with your live production URL.
Build failing?
Make sure all your changes are committed and pushed to GitHub. Vercel builds from the latest code on your main branch. If you see a TypeScript error, check the error log in the Vercel build output for the exact file and line number.
Help me debug my Vercel build failure
Verify the live deployment and automatic redeploys
Your app is live. Now you will confirm it works end-to-end on the public URL, and that Vercel automatically redeploys when you push new code.
- Click Visit (or copy your production URL) to open your live app in a new tab.
- Paste a paragraph of text into the textarea and click Summarize.
- Confirm that the summary streams in word by word, just like it did locally.
Test with real text
Copy a paragraph from a news article or Wikipedia page. Real text gives you a better sense of how the summarizer performs compared to short test phrases.
Now verify automatic deployments. Every time you push to your main branch, Vercel detects the push and deploys a new version automatically.
- Switch back to VS Code.
- Open app/layout.tsx and find the description line in the metadata object.
- Make a small edit, such as adding the word "instantly" to the description, then save the file.
- Commit and push the change by running these commands in your terminal:
git add .
git commit -m "Update metadata description"
git push
- Return to your Vercel dashboard. You should see a new deployment appear within seconds.
- Wait for it to finish building (look for a green Ready status), then refresh your live URL to confirm the update is live.
What is automatic deployment?
Vercel monitors your connected GitHub repository. When you push a commit to the production branch (main), it triggers a new build and deploys it automatically. This is the same CI/CD workflow used in professional teams.
Write a professional README.md
A strong README is the first thing employers and collaborators see when they visit your GitHub repository. It tells them what the project does, how to run it, and what technologies you used.
- In VS Code, create a new file called README.md in the root of your project folder (the same level as package.json).
- Copy the following README template into the file:
# AI Content Summarizer
A full-stack AI web application that summarizes text using streaming responses powered by Google Gemini.
## Live Demo
[View the live app](https://[[VERCEL_URL="your-project-name.vercel.app"]])
## Features
- Real-time streaming AI responses (word by word)
- Clean, responsive UI built with Tailwind CSS
- Server-side AI integration via Next.js API routes
- Automatic deployments from GitHub via Vercel
## Tech Stack
- **Framework:** Next.js 16 (App Router)
- **Language:** TypeScript
- **Styling:** Tailwind CSS
- **AI:** Google Gemini (gemini-2.5-flash) via Vercel AI SDK
- **Deployment:** Vercel
## Getting Started
### Prerequisites
- Node.js 18+
- A Google AI Studio API key
### Local Setup
1. Clone the repository:
```bash
git clone https://github.com/[[GITHUB_PATH="YOUR_USERNAME/YOUR_REPO"]].git
cd [[REPO_NAME="YOUR_REPO"]]
```
2. Install dependencies:
```bash
npm install
```
3. Create a `.env.local` file in the root directory:
```
GOOGLE_GENERATIVE_AI_API_KEY=your-api-key-here
```
4. Start the development server:
```bash
npm run dev
```
5. Open [http://localhost:3000](http://localhost:3000) in your browser.
## License
MIT
What does this README include?
- A project description that explains what the app does.
- A live demo link so people can try it immediately.
- A features list highlighting your technical capabilities.
- A tech stack section that maps to skills employers look for.
- Local setup instructions so anyone can clone and run it.
- Replace the Live Demo URL with your actual Vercel deployment URL.
- Replace the GitHub clone path with your actual GitHub username and repository name.
- Save README.md.
- Push the README to GitHub by running these commands:
git add README.md
git commit -m "Add professional README"
git push
- Return to your GitHub repository page and refresh it. You should see the README rendered below your file list.
- Check your Vercel dashboard. A new deployment should already be building from this push.
README not showing on GitHub?
Make sure the file is named exactly README.md (uppercase) and is in the root of your repository, not inside a subfolder. GitHub only auto-renders the README if it is at the top level.
Help me figure out why my README is not showing
Your app is live, auto-deploying, and your repo looks professional. Next up, you will tackle the Secret Mission and add multiple summarization modes to make your app even more impressive.
Secret mission
Add Multiple Summarization Modes
Your summarizer currently produces one type of output. What if the user wants a quick two-sentence overview for a Slack message, a detailed breakdown for a report, or a bullet-point list for meeting notes? In this secret mission, you'll add a mode selector that lets users choose between Brief, Detailed, and Bullet Points summaries, powered by dynamic prompt engineering on the backend.
Clean Up Your Resources
Clean Up Your Resources
This project runs on entirely free services. Your Vercel deployment uses the free Hobby plan, and the Gemini API key operates within the free tier. There are no ongoing costs to worry about.
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- Next.js project folder on your Desktop (local files).
- GitHub repository.
- Vercel deployment (free Hobby plan).
- Google AI Studio API key (free tier).
Keep everything running
No action needed. Choose this if you want your live app to stay accessible and you plan to keep building on it.
- Your Vercel deployment stays live indefinitely on the free Hobby plan.
- Your Gemini API key remains active within free tier rate limits at no cost.
- Your local project folder stays on your Desktop for future editing.
- Your GitHub repository remains public (or private) and accessible.
Pause - I'll come back to this later
Since both Vercel and the Gemini API are free, there is nothing to pause for cost reasons. If you want to free up local resources, you can stop the dev server.
- If your local dev server is still running, press Ctrl+C in the terminal to stop it.
- Your Vercel deployment and GitHub repo will remain available whenever you return.
Delete - I don't want to use this again
Remove all project resources and start fresh. Follow each item below to fully clean up.
- Delete your local project folder. In your terminal, run:
cd ~/Desktop
rm -rf ai-content-summarizer
Replace ai-content-summarizer with whatever you named your project folder during create-next-app.
- On Windows, use this command instead:
cd ~\Desktop
Remove-Item -Recurse -Force ai-content-summarizer
- Delete your Vercel project. Open your Vercel dashboard, select the project, go to Settings, scroll to the bottom of the page, and click Delete Project. Confirm the deletion when prompted.
- Revoke your Google AI Studio API key. Open Google AI Studio, navigate to your API keys list, find the key you created for this project, and delete it.
- Delete your GitHub repository. Open your repository on GitHub, go to Settings, scroll to the bottom under Danger Zone, and click Delete this repository. Type the repository name to confirm.
Nice Work!
Nice Work!
Nice work! You just built and deployed a full-stack AI web application that streams real-time summaries powered by Google Gemini.
You've learned how to:
- Build a full-stack AI web application with Next.js 16, TypeScript, and Tailwind CSS.
- Integrate Google Gemini AI with real-time streaming responses using the Vercel AI SDK.
- Deploy a live application to Vercel with automatic CI/CD from GitHub, complete with a professional README for your portfolio.
- Secret Mission: Added multiple summarization modes with dynamic prompt engineering and a mode selector UI.
Ready to quiz yourself?