A full-stack blog platform built with React.js and Appwrite, featuring user authentication, rich text editing, and image uploads. Users can create, edit, and delete their own posts with a clean, responsive UI.
π Live Demo: blog-app-two-livid.vercel.app
- π User Authentication (Sign Up / Login / Logout) via Appwrite
- π Create, Edit & Delete blog posts
- πΌοΈ Image upload and preview for post thumbnails
- π Rich Text Editor (TinyMCE)
- π Protected routes β only post authors can edit/delete their posts
- β‘ Fast and responsive UI built with Tailwind CSS
- βοΈ Deployed on Vercel
| Technology | Usage |
|---|---|
| React.js | Frontend framework |
| Redux Toolkit | Global state management |
| React Router DOM | Client-side routing |
| Appwrite | Backend as a Service (Auth, DB, Storage) |
| TinyMCE | Rich text editor |
| Tailwind CSS | Styling |
| Vite | Build tool |
| Vercel | Deployment |
- Node.js v18+
- An Appwrite account and project
# Clone the repository
git clone https://github.com/Sarthak050205/Blog-App.git
cd Blog-App
# Install dependencies
npm installCreate a .env file in the root directory:
VITE_APPWRITE_URL=https://cloud.appwrite.io/v1
VITE_APPWRITE_PROJECT_ID=your_project_id
VITE_APPWRITE_DATABASE_ID=your_database_id
VITE_APPWRITE_COLLECTION_ID=your_collection_id
VITE_APPWRITE_BUCKET_ID=your_bucket_id
VITE_TINYMCE_API_KEY=your_tinymce_keynpm run devsrc/
βββ appwrite/ # Appwrite service config (auth, database, storage)
βββ components/ # Reusable UI components
β βββ Header/
β βββ Footer/
β βββ post-form/
β βββ ...
βββ pages/ # Route-level page components
βββ store/ # Redux slices
βββ conf/ # Environment variable config
βββ main.jsx
A full log of bugs caught and fixed β great learning experience overall.
| # | File | Bug | Fix |
|---|---|---|---|
| 1 | App.jsx |
<Outlet /> was commented out β child routes never rendered |
Uncommented <Outlet /> |
| 2 | Appwrite auth service | Wrong method name createEmailSession instead of createEmailPasswordSession |
Updated to correct Appwrite SDK v13+ method |
| 3 | AllPost.jsx |
Typo in import path, wrong fetch method, wrong property name, API call outside useEffect |
Fixed import, method, property, wrapped call in useEffect |
| 4 | LogoutBtn.jsx |
Importing from wrong file | Fixed import path to correct store/slice |
| 5 | SignUp.jsx |
lable typo on form field |
Renamed to label |
| 6 | Button.jsx |
px-4, had a comma, py2 missing dash |
Fixed to px-4 and py-2 |
| 7 | PostForm.jsx |
status field sent as string "true"/"false" instead of boolean |
Converted to proper boolean before submitting to Appwrite |
| 8 | PostForm.jsx |
Missing comma in object β silent JS syntax error | Added missing comma |
| 9 | Redux store | Appwrite response object contained functions β Redux serializable check error | Extracted only plain data before dispatching to store |
| 10 | authSlice.js |
userData was undefined β wrong payload structure assumed |
Fixed payload destructuring to match actual dispatched shape |
| 11 | Post detail page | parse(post.content) crashing when post.content was null |
Added null check before calling parse() |
| 12 | Appwrite storage service | getFilePreview doesn't exist on free plan β also this.bucket vs this.storage naming mismatch |
Renamed to getFileView and fixed constructor naming |
Sarthak Kumar Lohani
- LinkedIn: linkedin.com/in/sarthak-kumar-lohani
- GitHub: github.com/Sarthak050205
This project is open source and available under the MIT License.