Hritik.blogs is a full-stack content platform built with Next.js App Router, MongoDB, and Mongoose. It includes a public blog experience, a lightweight admin dashboard, newsletter subscriptions, and server-side rendering for the main feed.
The public site focuses on fast reading and simple discovery. The home page loads blog data on the server with ISR, the category filter is keyboard-friendly, and blog cards are optimized for responsive images and concise previews. The blog detail page renders full HTML content with a small sanitization layer to strip unsafe or noisy markup before display.
The admin side provides a focused workflow for creating posts, browsing all posts, and managing newsletter signups. The API routes are designed to connect to MongoDB on demand and clean up uploaded images when posts are deleted.
- Server-rendered home feed with
revalidate = 60for fresher content and better first paint. - Responsive blog cards with tuned
next/imagebreakpoints. - Category filtering on the homepage.
- Blog detail pages with HTML rendering and sanitization.
- Admin tools for adding posts, listing posts, and reviewing subscriptions.
- Dynamic
robots.txtand web manifest support. - PWA and favicon metadata configured in the app layout.
- Next.js 16
- React 19
- Tailwind CSS 4
- MongoDB
- Mongoose
- Axios
- React Toastify
- React Icons
/- blog homepage/blogs/[id]- blog detail page
/admin- admin landing page/admin/addProduct- create a new blog post/admin/blogList- manage existing posts/admin/subscriptions- view and delete newsletter subscribers
/api/blogGET- fetch all blogsGET?id=<blogId>- fetch a single blogPOST- create a blog and upload its imageDELETE?id=<blogId>- delete a blog and its image
/api/emailGET- fetch all subscriber emailsPOST- save a subscriber emailDELETE?id=<emailId>- delete a subscriber email
- Home feed blogs are loaded on the server and sorted by newest first.
- Blog cards convert stored HTML into a plain-text preview.
- Blog detail pages sanitize stored HTML before rendering.
- The add-post form also sanitizes HTML before it reaches the database.
- Image uploads are written into
public/so the stored paths can be served directly. - MongoDB connections are cached in
lib/config/db.jsto avoid reconnecting on hot reload.
npm installCreate a .env file in the project root:
MONGODB_URI=your_mongodb_connection_stringnpm run devOpen http://localhost:3000.
npm run dev- start the development servernpm run build- create a production buildnpm run start- run the production servernpm run lint- run ESLint
app/page.jsx- homepage data loading and layoutapp/blogs/[id]/page.jsx- blog reader pageapp/admin/page.jsx- admin landing pageapp/admin/addProduct/page.jsx- blog creation formapp/admin/blogList/page.jsx- blog management tableapp/admin/subscriptions/page.jsx- subscription managementapp/api/blog/route.js- blog CRUD APIapp/api/email/route.js- subscription APIapp/robots.js- robots.txt generatorapp/manifest.webmanifest- web app manifestapp/layout.jsx- app metadata and shared layoutlib/config/db.js- MongoDB connection helperlib/models/blog.model.js- blog schemalib/models/email.model.js- subscriber schemacomponents/Bloglist.jsx- homepage filtering and gridcomponents/Blogitem.jsx- blog card UIcomponents/Header.jsx- homepage hero headercomponents/Nav.jsx- top navigationcomponents/Newsletter.jsx- newsletter signup UIcomponents/AdminComponents/Sidebar.jsx- admin navigationcomponents/AdminComponents/BlogTable.jsx- admin blog list rowscomponents/AdminComponents/SubscriptionTable.jsx- subscription rows
- Content sanitization is intentionally lightweight and regex-based for controlled admin input.
- The current ESLint setup may require
typescriptto be installed locally beforenpm run lintsucceeds. - Public and admin UI share the same visual language, so layout and metadata changes in
app/layout.jsxaffect both.