A modern, full-stack blogging platform built with Next.js 15, tRPC, PostgreSQL, and Drizzle ORM. This application demonstrates modern web development practices with type-safe APIs, responsive design, and a clean architecture.
- β Blog post CRUD operations (create, read, update, delete)
- β Category CRUD operations
- β Assign one or more categories to posts
- β Blog listing page showing all posts
- β Individual post view page
- β Category filtering on listing page
- β Basic responsive navigation
- β Clean, professional UI
- β Landing page with Header/Hero, Features, and Footer sections
- β Dashboard page for managing posts
- β Draft vs Published post status
- β Loading and error states
- β Mobile-responsive design
- β Content editor with markdown support
- π Search functionality for posts
- π Post statistics (word count, reading time)
- π Dark mode support
- π Image upload for posts
- π Post preview functionality
- π SEO meta tags
- π Pagination
- Frontend: Next.js 15 with App Router, React 19, TypeScript
- Styling: Tailwind CSS, shadcn/ui components
- Backend: tRPC for type-safe APIs
- Database: PostgreSQL with Drizzle ORM
- State Management: Zustand (where needed)
- Data Fetching: React Query (via tRPC integration)
- Form Handling: React Hook Form with Zod validation
- Icons: Lucide React
src/
βββ app/ # Next.js App Router pages
β βββ api/trpc/ # tRPC API routes
β βββ blog/ # Blog pages
β βββ dashboard/ # Admin dashboard
β βββ globals.css # Global styles
β βββ layout.tsx # Root layout
β βββ page.tsx # Landing page
β βββ providers.tsx # tRPC and React Query providers
βββ components/ # Reusable components
β βββ ui/ # shadcn/ui components
β βββ navigation.tsx # Navigation component
βββ lib/ # Utilities and configurations
βββ db.ts # Database connection
βββ schema.ts # Database schema
βββ trpc.ts # tRPC configuration
βββ trpc-client.ts # tRPC client setup
βββ routers/ # tRPC routers
βββ index.ts # Main app router
βββ posts.ts # Posts router
βββ categories.ts # Categories router
- Node.js 18.17 or later
- PostgreSQL database (local or hosted)
-
Clone the repository
git clone <repository-url> cd blog-platform
-
Install dependencies
npm install
-
Set up environment variables
cp .env.local.example .env.local
Update
.env.localwith your database connection string:DATABASE_URL="postgresql://username:password@localhost:5432/blog_platform"
-
Set up the database
# Generate migration files npm run db:generate # Push schema to database npm run db:push
-
Start the development server
npm run dev
-
Open your browser Navigate to http://localhost:3000
The application uses three main tables:
id(UUID, Primary Key)title(VARCHAR, 200 chars)content(TEXT)slug(VARCHAR, 200 chars, Unique)published(BOOLEAN, default: false)createdAt(TIMESTAMP)updatedAt(TIMESTAMP)
id(UUID, Primary Key)name(VARCHAR, 100 chars, Unique)description(TEXT)slug(VARCHAR, 100 chars, Unique)createdAt(TIMESTAMP)updatedAt(TIMESTAMP)
id(UUID, Primary Key)postId(UUID, Foreign Key)categoryId(UUID, Foreign Key)createdAt(TIMESTAMP)
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run db:generate- Generate database migrationsnpm run db:migrate- Run database migrationsnpm run db:push- Push schema changes to databasenpm run db:studio- Open Drizzle Studio
The application uses tRPC for type-safe API endpoints:
getAll- Get all published posts with optional category filteringgetBySlug- Get a single post by slugcreate- Create a new postupdate- Update an existing postdelete- Delete a postgetAllForAdmin- Get all posts (including drafts) for admin
getAll- Get all categoriesgetBySlug- Get a single category by slugcreate- Create a new categoryupdate- Update an existing categorydelete- Delete a category
/- Landing page with hero, features, and footer/blog- Blog listing page with category filtering/blog/[slug]- Individual post view page/dashboard- Admin dashboard for managing posts and categories/dashboard/new- Create new post page/dashboard/edit/[id]- Edit existing post page
The application uses shadcn/ui components for a consistent and professional design:
- Button - Various button styles and sizes
- Card - Content containers with header and content sections
- Input - Form input fields
- Textarea - Multi-line text input
- Label - Form labels
- Select - Dropdown selection component
- Badge - Small status and category indicators
- Separator - Visual content separators
The application leverages TypeScript and tRPC for end-to-end type safety:
- Database Schema: Defined with Drizzle ORM with full TypeScript support
- API Layer: tRPC provides automatic type inference from server to client
- Frontend: All API calls are fully typed with autocomplete and error checking
- Validation: Zod schemas ensure data integrity at runtime
The application is fully responsive and works seamlessly across:
- Desktop (1024px+)
- Tablet (768px - 1023px)
- Mobile (320px - 767px)
Key responsive features:
- Mobile-first navigation with hamburger menu
- Responsive grid layouts for blog posts
- Flexible form layouts
- Touch-friendly button sizes
-
Push to GitHub
git add . git commit -m "Initial commit" git push origin main
-
Deploy to Vercel
- Connect your GitHub repository to Vercel
- Add environment variables in Vercel dashboard
- Deploy automatically on push
DATABASE_URL="your-production-database-url"- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Next.js - React framework
- tRPC - Type-safe APIs
- Drizzle ORM - TypeScript ORM
- shadcn/ui - UI components
- Tailwind CSS - CSS framework
- Lucide - Icon library
If you have any questions or need help with the project, please:
- Check the Issues page
- Create a new issue with detailed information
- Contact the maintainers
Built with β€οΈ using modern web technologies