Video summary
How to Build a Full Stack AI Powered Blog App using MERN Stack, Google Gemini and ImageKit API
Main summary
Key takeaways
Main ideas & concepts conveyed
Build a full-stack AI-powered blog application using the MERN stack (React + Node/Express + MongoDB), enhanced with:
- ImageKit API for uploading and optimizing blog images (compression/transforms, modern formats)
- Google Gemini for generating blog descriptions/content automatically
Core user flows
Visitors can:
- Browse blogs
- Search by title/category
- Filter by category
- Read blog details
- Submit comments
An admin dashboard lets an admin:
- Publish/unpublish blogs
- Delete blogs
- View the blogs list
- Moderate comments (approved vs not approved)
- Approve/delete comments
- Add new blogs using an AI-generated description
Deployment
- Deploy backend and frontend to Vercel using:
- Environment variables
- Extended function timeout for AI generation (up to 60 seconds)
UI / feature breakdown (what the app does)
Public (visitor) side
Homepage
- Top navigation bar with logo and a login button
- Search input (search by blog title/category)
- Category filter menu (All, Technology, Startup, Lifestyle, Finance)
- Blog list cards
- Newsletter subscription form
- Footer
Blog details page
Displays:
- Publish date (formatted)
- Title, subtitle
- Author (hardcoded in the tutorial)
- Featured image
- Blog content (rendered as rich HTML)
- Comments section
- Shows only approved comments
- Includes a comment submission form
- Social share icons
- Footer
Admin side
Admin login page
- Email + password fields
- Uses backend login API to obtain a JWT token
Admin dashboard layout
- Shared navigation + sidebar for admin routes
- Dashboard shows:
- Total blogs
- Total comments
- Draft (unpublished) count
- Recent blog preview
Admin pages
- Add Blog
- Upload thumbnail
- Enter title/subtitle
- Generate description with AI
- Select category
- Publish toggle
- Blog List
- Table with publish/unpublish and delete actions
- Comments
- Table with toggle between approved / not approved
- Approve/delete actions
Methodology / implementation steps (detailed)
1) Frontend setup (React + routing + styling)
-
Create a React project using Vite/Wheat tooling:
bash npm create ... @latest- Create a client folder
- Choose React + JavaScript variant
- Install/configure dependencies:
npm install(client dependencies)npm run dev- Remove default template code and update:
- App structure using
rafce - Clear CSS files
- Update
index.htmltitle/favicon - Add assets:
- Copy provided
assetsintoclient/src/assets - Add favicon SVG into
public/ - Styling:
- Import Outfit font via
index.css - Hide scrollbars
- Add Tailwind CSS
- Install and configure
tailwind.config.jsplugins - Import Tailwind into
index.css
- Install and configure
- Define primary theme color
- Add routing:
- Install
react-router-dom - Use
BrowserRouter - Define routes:
/(home)/blog/:id(blog detail)
2) Frontend components & page structure
Create folders:
src/componentssrc/pages
Public pages:
Home.jsxBlog.jsx
Public components:
Navbar.jsx(logo + login/admin routing)Header.jsx(gradient background + AI feature banner + title + search UI)BlogList.jsx(category menu + Framer Motion animated selection)BlogCard.jsx(thumbnail + category tag + title + truncated description + navigation)Newsletter.jsxFooter.jsxLoader.jsx(loading spinner for blog detail)
Blog detail rich content
- Render rich HTML using
dangerouslySetInnerHTML - Import provided rich-text CSS stylesheet
- Convert timestamps using moment
3) Public-side data handling and API integration
- Add Axios
- Use Context for global state via
AppContext.jsx - Configure:
axios.defaults.baseURLfromclient/.env
- Store:
token(JWT)blocks(blog list)input(search keyword)
Search behavior
Filter blogs by:
blog.titleincludes input ORblog.categoryincludes input
Include a clear search button to reset the input.
4) Blog detail backend interactions (comments + fetching)
- Blog detail fetch:
- Get blog by
:id(impliedGET /api/blog/:id)
- Get blog by
- Comments for that blog:
- Submit comments using:
POST /api/blog/add comment(implied)
- Fetch approved comments (only approved are rendered)
- Submit comments using:
Comment submission
- Controlled fields:
name,content - New comments default to unapproved
- Blog page displays only comments with
isApproved: true
5) Admin frontend setup (dashboard routing + layout)
Create admin folder:
src/pages/admin/layout.jsx(admin navigation + outlet)dashboard.jsxaddBlog.jsxlistBlog.jsxcomments.jsx
Create admin components:
src/components/admin/login.jsxsrc/components/admin/sidebar.jsx- Table row components:
BlogTableItem.jsxCommentTableItem.jsx
Admin routing (child routes)
/admin→ layout- index → dashboard
/admin/addblog→ add blog form/admin/listblog→ blog list/admin/comments→ comment moderation
6) Admin auth (JWT)
Backend endpoints:
POST /api/admin/login- Validates
ADMIN_EMAIL+ADMIN_PASSWORDfrom env vars - Returns JWT
- Validates
Frontend:
- Store token in
localStorage:localStorage.setItem("token", token)
- Attach token to Axios headers:
axios.defaults.headers.common["authorization"] = token
Navbar:
- Show “Dashboard” if token exists
- Show “Login” if absent
7) Backend setup (Express + MongoDB + routes)
- Backend structure:
server/withserver.js
- ESM setup in
package.json:"type": "module"
- Install dependencies:
express,mongoose,cors,dotenv,jsonwebtoken,multer,nodemon
- Express configuration:
- JSON parsing middleware
- Basic
/health endpoint - Start via nodemon script
8) MongoDB connection
- Create
configs/db.js- Connect using
mongoose.connect(process.env.MONGODB_URI) - Log when “connected”
- Connect using
- Ensure MongoDB Atlas network access includes your IP
9) Backend data models
models/blog.js
Fields:
title,subtitle,description,categoryimage(URL)isPublished(boolean)- timestamps enabled
models/comment.js
Fields:
blogreference (ObjectId→ Blog)namecontentisApproved(boolean, defaultfalse)- timestamps enabled
10) ImageKit integration (thumbnail upload + optimization)
- Create ImageKit config:
configs/imageKit.js(initialize with env keys)
When adding a blog:
- Read uploaded image into a buffer (
fs.readFileSync) - Upload to ImageKit:
imagekit.upload(...)
- Use transformations for an optimized URL:
quality: "auto"format: "webp"width: 1280
- Save the optimized URL to MongoDB (not the original file)
11) Gemini integration (AI description generation)
- Create Gemini config:
configs/gemini.js
- Use
@google/genaiwithprocess.env.GEMINI_API_KEY - Provide a function that takes a prompt and returns model output
Controller:
generateContent(req, res)- Reads
promptfrom request body - Calls Gemini (example: Gemini 2.0 Flash)
- Returns
{ success: true, content: ... }
- Reads
Admin UI:
- “Generate with AI” button calls:
POST /api/blog/generatewith{ prompt: title }
- Render returned rich HTML into the Quill editor content
12) Blog APIs (CRUD + publish toggle)
- Add blog (admin protected, uses multer + auth middleware):
POST /api/blog/add
- Get all published blogs:
GET /api/blog/all(filtersisPublished: true)
- Get blog by id:
GET /api/blog/:blogId
- Delete blog (admin protected; also deletes related comments):
POST /api/blog/delete
- Publish toggle (admin protected):
POST /api/blog/toggle publish- flips
isPublished
13) Comment APIs (add + fetch + moderation)
- Add comment:
POST /api/blog/add comment- sets
isApproved = falseby default
- Fetch comments for a blog:
POST /api/blog/commentswithblogId- returns only approved comments
- Admin moderation:
POST /api/admin/approve comment→ setsisApproved = truePOST /api/admin/delete comment→ removes comment by id
- Admin dashboard list endpoints:
GET /api/admin/blogs(all blogs)GET /api/admin/comments(all comments with approval flags)GET /api/admin/dashboard(counts + recent blogs)
14) Frontend admin data wiring
- Dashboard
- Calls
GET /api/admin/dashboard - Sets state for:
- blog count
- comment count
- draft count
- recent blogs
- Calls
- Blog list
- Calls blogs endpoint
- Table actions:
- toggle publish
- delete blog (with confirmation prompt)
- Comments page
- Calls endpoint to get all comments
- Filters view by approved/unapproved
- Actions:
- approve comment (calls admin approve endpoint)
- delete comment (calls admin delete endpoint)
15) Quill editor integration for AI-generated rich text
- Install/use:
npm i quill
- Import Quill snow CSS in React entry (
main CSS import) - Initialize Quill once using
useEffect
Usage:
- Submission HTML:
quillRef.current.root.innerHTML
- Rendering:
dangerouslySetInnerHTML
Deployment steps (Vercel)
1) Configure Vercel
- Add
vercel.json:client/vercel.json(frontend)server/vercel.json(backend)
- Add
.gitignoreto excludenode_modules
2) Deploy backend first
- Import GitHub repo into Vercel
- Set env vars (JWT secret, admin creds, MongoDB URI, ImageKit keys, Gemini API key)
- Increase function max duration for AI generation:
- 60 seconds
- Redeploy and record backend domain
3) Deploy frontend
- Import same repo
- Set root directory to
client/ - In
client/.env, set base URL to deployed backend URL - Increase frontend function timeout similarly
4) Verify
- Homepage loads blogs
- Admin login works
- Admin can add blogs and generate descriptions with AI
Speakers / sources featured (at end)
- No human speakers explicitly identified in the subtitles.
- Video host / channel identity references:
- “greatest tech” (creator/channel)
- “great stack” (title phrase)
- Tools / external systems referenced as sources:
- MERN stack: ReactJS, NodeJS, ExpressJS, MongoDB
- ImageKit API
- Google Gemini / Google AI Studio
- Vercel
- MongoDB Atlas
- Tailwind CSS
- Framer Motion (motion/react)
- Moment.js
- Quill
- Axios
- React Hot Toast
- Postman (API testing)
- Google Fonts (Outfit font)