Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
829287a
readme
sinanrahman Feb 9, 2026
f73ce73
model changed slightly
sinanrahman Feb 9, 2026
0c93d1d
titleChange
Hana-Haris3 Feb 9, 2026
a05f37d
Merge branch 'main' into hana
Hana-Haris3 Feb 9, 2026
02145e0
Merge pull request #1 from sinanrahman/hana
sinanrahman Feb 9, 2026
4f2976e
color theme change
salih85 Feb 9, 2026
cc8a6bd
Merge branch 'main' into salih
sinanrahman Feb 9, 2026
747fb20
Merge pull request #2 from sinanrahman/salih
sinanrahman Feb 9, 2026
dcb085e
update color theme
salih85 Feb 9, 2026
5f2e459
Merge pull request #3 from sinanrahman/salih
sinanrahman Feb 9, 2026
dcdeee8
add collaboration setup
salih85 Feb 9, 2026
ab46688
Merge pull request #4 from sinanrahman/salih
sinanrahman Feb 9, 2026
2625523
collab
Hana-Haris3 Feb 10, 2026
9ba6bc2
Merge pull request #5 from sinanrahman/hana
sinanrahman Feb 10, 2026
7e7c89b
almost
sinanrahman Feb 10, 2026
3940b8e
Merge pull request #6 from sinanrahman/sinan
sinanrahman Feb 10, 2026
68948d4
add share button
salih85 Feb 11, 2026
f7fcb32
Merge pull request #7 from sinanrahman/salih
sinanrahman Feb 11, 2026
f6ed5eb
createId
Hana-Haris3 Feb 11, 2026
9231434
Merge pull request #8 from sinanrahman/hana
sinanrahman Feb 11, 2026
ae6b436
antigravity
sinanrahman Feb 11, 2026
d9f25b4
Merge pull request #9 from sinanrahman/sinan
sinanrahman Feb 11, 2026
f96b23c
remove email invite from share modal
salih85 Feb 12, 2026
70d68f7
Merge pull request #10 from sinanrahman/salih
sinanrahman Feb 12, 2026
ace5559
add video call
salih85 Feb 13, 2026
77e506c
Merge pull request #11 from sinanrahman/salih
sinanrahman Feb 13, 2026
6ea9947
solved
sinanrahman Feb 13, 2026
9bc7495
solved
sinanrahman Feb 13, 2026
29fb501
solved
sinanrahman Feb 13, 2026
ea5f5d2
solved
sinanrahman Feb 13, 2026
69735da
solved
sinanrahman Feb 13, 2026
c9e1313
solved
sinanrahman Feb 13, 2026
0f0d4aa
solved
sinanrahman Feb 13, 2026
781f5f6
solved
sinanrahman Feb 13, 2026
9a2c7bc
solved
sinanrahman Feb 13, 2026
81c1b85
ip host
sinanrahman Feb 13, 2026
774e0de
all done
sinanrahman Feb 13, 2026
6564f2e
fix: robust CORS and logging
sinanrahman Feb 13, 2026
84e3203
fix: core CORS and auth stability
sinanrahman Feb 13, 2026
bc92907
fix: core CORS and auth stability
sinanrahman Feb 13, 2026
49eda67
fix: core CORS and auth stability
sinanrahman Feb 13, 2026
5503d15
Fix UI styling
salih85 Feb 14, 2026
58c2547
done
sinanrahman Feb 14, 2026
fbbcf0e
remove logo
salih85 Feb 15, 2026
93d1cf0
Merge branch 'salih' of https://github.com/sinanrahman/ogDoc into salih
salih85 Feb 15, 2026
096b417
Merge pull request #14 from sinanrahman/salih
sinanrahman Feb 15, 2026
1075f0b
logo
sinanrahman Feb 15, 2026
81dbce0
email
sinanrahman Feb 15, 2026
e309e76
email
sinanrahman Feb 15, 2026
cad9027
email
sinanrahman Feb 15, 2026
b688e86
email
sinanrahman Feb 15, 2026
2a9a914
email
sinanrahman Feb 15, 2026
c6160e9
email
sinanrahman Feb 15, 2026
3cd7281
Merge pull request #15 from sinanrahman/mail
sinanrahman Feb 15, 2026
b617dc1
email
sinanrahman Feb 15, 2026
b4eed26
Merge pull request #16 from sinanrahman/mail
sinanrahman Feb 15, 2026
742c2ae
email
sinanrahman Feb 15, 2026
79ad8db
Merge pull request #17 from sinanrahman/mail
sinanrahman Feb 15, 2026
8568112
email
sinanrahman Feb 15, 2026
a01cc71
Merge pull request #18 from sinanrahman/mail
sinanrahman Feb 15, 2026
5b99564
email
sinanrahman Feb 15, 2026
12df87c
Merge pull request #19 from sinanrahman/mail
sinanrahman Feb 15, 2026
190b616
email
sinanrahman Feb 15, 2026
dfb91a1
Merge pull request #20 from sinanrahman/mail
sinanrahman Feb 15, 2026
ad2b0ee
email
sinanrahman Feb 15, 2026
ec77181
Merge pull request #21 from sinanrahman/mail
sinanrahman Feb 15, 2026
e5b3e15
email
sinanrahman Feb 15, 2026
07702f0
Merge pull request #22 from sinanrahman/mail
sinanrahman Feb 15, 2026
0b306cf
email
sinanrahman Feb 15, 2026
e6af9bf
Merge pull request #23 from sinanrahman/mail
sinanrahman Feb 15, 2026
1ea7994
email
sinanrahman Feb 15, 2026
639ddd2
Merge pull request #24 from sinanrahman/mail
sinanrahman Feb 15, 2026
9198344
email verification
sinanrahman Feb 15, 2026
338c8b8
Merge pull request #25 from sinanrahman/mail
sinanrahman Feb 15, 2026
17c889d
email verification
sinanrahman Feb 15, 2026
74f10fe
email verification
sinanrahman Feb 15, 2026
65882cb
Merge pull request #26 from sinanrahman/mail
sinanrahman Feb 15, 2026
0e9031e
video call fix
sinanrahman Feb 15, 2026
b8754f8
Merge pull request #27 from sinanrahman/mail
sinanrahman Feb 15, 2026
7a0a67e
video call fix
sinanrahman Feb 15, 2026
a94ccc4
Merge pull request #28 from sinanrahman/mail
sinanrahman Feb 15, 2026
1cdfbf3
video call fix
sinanrahman Feb 15, 2026
d5dc4cf
Merge pull request #29 from sinanrahman/mail
sinanrahman Feb 15, 2026
267f2e3
remove user
salih85 Feb 16, 2026
b56b1ac
Merge pull request #30 from sinanrahman/salih
sinanrahman Feb 16, 2026
e7e0e59
remove user
salih85 Feb 16, 2026
24e460b
remove user
salih85 Feb 16, 2026
4a50948
Merge pull request #31 from sinanrahman/salih
sinanrahman Feb 16, 2026
9c9c8c8
responsive
Hana-Haris3 Feb 16, 2026
bfe8a91
Merge pull request #32 from sinanrahman/hana
sinanrahman Feb 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 218 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,279 @@
# Blogify 📝
# OG Docs 📝

**A modern, collaborative blogging platform built for speed, security, and developer-centric content control.**
**A modern, real-time collaborative documentation platform built for speed, security, and developer-centric content control.**

## About The Project

**Blogify** is a full-stack web application designed to streamline the way developers write and share articles. The project focuses on structured content delivery, moving away from standard plain-text storage to a robust, custom-tailored data architecture.
**OG Docs** is a full-stack web application designed to streamline the way teams and developers write, edit, and share documentation together. The platform emphasizes structured content delivery and real-time collaboration, moving beyond traditional plain-text storage toward a robust, custom-tailored data architecture.

Built as a high-performance **MERN** application, Blogify provides a seamless writing experience while giving authors granular control over their content's metadata and presentation.
Built as a high-performance **MERN** application, OG Docs enables multiple collaborators to work simultaneously in a shared workspace, with changes reflected instantly for everyone—ensuring smooth, efficient, and transparent collaboration.

---

## 🚀 Key Features

* **Custom Slate.js Engine:** Uses a custom-built implementation to structure content into JSON format, ensuring consistent styling and portability.
* **Real-Time Collaborative Workspace:** A dedicated editing area where multiple collaborators can make changes simultaneously, with updates reflected in real time.
* **Custom Slate.js Engine:** A custom-built implementation that structures content into JSON format for consistent styling and long-term portability.
* **Modern UI/UX:** A clean, responsive interface built with **React 19**, **Tailwind CSS 4.0**, and **CoreUI** components.
* **Secure Authentication:** Integrated **Google OAuth** for quick and secure user access.
* **Secure Authentication:** Integrated **Google OAuth** for fast and secure user access.
* **Developer-Friendly Build:** Optimized with **Vite** for near-instant hot module replacement (HMR).
* **Robust Security:** Hardened backend using **Helmet**, **HPP**, **Rate Limiting**, and **Zod** for schema validation.
* **Robust Security:** Hardened backend using **Helmet**, **HPP**, **Rate Limiting**, and **Zod** for strict schema validation.

---

## 🛠 The Tech Stack

### Frontend

* **Library:** React 19
* **Styling:** Tailwind CSS 4.0 & CoreUI
* **Editor:** Slate.js (Custom JSON Content Engine)
* **State & Routing:** React Router 7
* **Build Tool:** Vite

### Backend

* **Runtime:** Node.js
* **Framework:** Express.js (v5)
* **Authentication:** JWT & Google Auth Library
* **Validation:** Zod

### Database

* **Database:** MongoDB
* **ODM:** Mongoose

---

## ⚙️ How It Works

The core logic of Blogify revolves around a structured data pipeline:

1. **The Input:** Authors use a custom editor powered by **Slate.js**. Instead of generating messy HTML, it outputs a clean **JSON tree** representing the document structure.
2. **The Storage:** This JSON object is validated via **Zod** and stored in **MongoDB** through **Mongoose** models.
3. **The Rendering:** On the frontend, our custom engine traverses the JSON tree and dynamically "paints" the content using Tailwind-styled React components.

The core logic of OG Docs revolves around a structured, collaborative data pipeline:

1. **The Input:** Contributors write using a custom editor powered by **Slate.js**. Instead of generating raw HTML, the editor produces a clean **JSON tree** representing the document structure.
2. **The Collaboration Layer:** Multiple users can edit the same document simultaneously, with real-time updates synchronized across all active sessions.
3. **The Storage:** The JSON structure is validated using **Zod** and securely stored in **MongoDB** via **Mongoose** models.
4. **The Rendering:** On the frontend, a custom rendering engine traverses the JSON tree and dynamically paints the content using Tailwind-styled React components.

---

## 📦 Installation & Setup

Follow these steps to get a copy of Blogify running locally.
Follow these steps to run OG Docs locally.

### Prerequisites

* [Node.js](https://nodejs.org/) (Latest LTS)
* [MongoDB](https://www.mongodb.com/) account or local instance.
* [MongoDB](https://www.mongodb.com/) account or local instance

### Steps

1. **Clone the Repository**
```bash
git clone [https://github.com/shamil-tp/Blogify.git](https://github.com/shamil-tp/Blogify.git)
cd blogify
```
1. **Clone the Repository**

```bash
git clone https://github.com/shamil-tp/Blogify.git
cd blogify
```

2. **Setup Backend**

```bash
cd backend
npm install
```

Create a `.env` file in the `backend` folder and add your `MONGODB_URI`, `JWT_SECRET`, and `PORT`.

3. **Setup Frontend**

2. **Setup Backend**
```bash
cd backend
npm install
```
Create a `.env` file in the `backend` folder and add your `MONGODB_URI`, `JWT_SECRET`, and `PORT`.
```bash
cd ../frontend
npm install
```

3. **Setup Frontend**
```bash
cd ../frontend
npm install
```
4. **Run Development Servers**

4. **Run Development Servers**
* **Backend:** `npm run test` (uses nodemon)
* **Frontend:** `npm run dev` (uses vite)
* **Backend:** `npm run test` (nodemon)
* **Frontend:** `npm run dev` (Vite)

5. **View the App**
Open `http://localhost:5173` for the frontend.
5. **View the App**
Open `http://localhost:5173` in your browser.

---

## 👥 The Team

This project was collaboratively designed and developed by:

* **Shamil** - [GitHub](https://github.com/shamil-tp)
* **Sinan** - [GitHub](https://github.com/sinanrahman/)
* **Ranfees** - [GitHub](https://github.com/Ranfees)
* **Sinan** – [GitHub](https://github.com/sinanrahman/)
* **Hana** – [GitHub](https://github.com/Hana-Haris3)
* **Salih** – [GitHub](https://github.com/salih85)

---

OG Docs is built with collaboration at its core—designed to help teams write, iterate, and ship documentation together, faster and cleaner.










frontend/src/
├── collaboration/
│ ├── socket.js
│ ├── ydoc.js
│ ├── awareness.js
│ └── collabTypes.js
├── hooks/
│ ├── useAuth.jsx
│ └── useCollaboration.js ← NEW
├── components/
│ └── GridEditor/
│ ├── GridEditor.jsx
│ ├── withCollaboration.js ← NEW
│ ├── TextWidget.jsx
│ ├── ImageWidget.jsx
│ └── VideoWidget.jsx








backend/
├── socket/
│ ├── index.js
│ ├── auth.js
│ ├── rooms.js
│ └── handlers/
│ ├── joinDoc.js
│ ├── syncUpdate.js
│ ├── awareness.js
│ └── disconnect.js
├── collaboration/
│ ├── yjs/
│ │ ├── createDoc.js
│ │ └── applyUpdate.js
│ └── persistence/
│ ├── loadSnapshot.js
│ └── saveSnapshot.js





👤 Teammate A — Backend (Realtime Engine)
🎯 Responsibility

Everything related to:

Socket.IO

Yjs document sync

MongoDB snapshots

📁 Files they touch
backend/
├── socket/
├── collaboration/
├── models/Blog.js


They do NOT touch frontend.

🔧 Their Tasks (Very Exact)
A1 — Socket.IO server

Attach Socket.IO to Express

JWT auth on connection

Rooms per blogId

A2 — Yjs document manager

Create Yjs doc per blog

Load collabSnapshot

Keep docs in memory

A3 — Sync protocol

Receive Yjs updates

Broadcast to room

Prevent echo loops

A4 — Persistence

Save snapshot when:

last user leaves

OR every 30s

📦 Output

socket.emit("doc:update", update)
socket.emit("doc:sync", state)





👤 Teammate B — Frontend (Quill + Yjs)
🎯 Responsibility

Bind Quill editor → Yjs → Socket.IO.

📁 Files they touch
frontend/src/
├── collaboration/
│ ├── socket.js
│ ├── ydoc.js
│ └── awareness.js
├── components/GridEditor/
│ ├── GridEditor.jsx
│ └── withCollaboration.js


They do NOT touch backend.

🔧 Their Tasks (Very Exact)
B1 — Yjs + Quill binding

Create Y.Doc

Create Y.Text

Bind using y-quill

import { QuillBinding } from 'y-quill'

B2 — Socket sync

Send Yjs updates to backend

Apply remote updates

B3 — Presence & cursors

Use quill-cursors

Show colored cursors per user

📦 Output

<QuillEditor docId="..." />
20 changes: 20 additions & 0 deletions backend/collaboration/persistence/loadSnapshot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// const Blog = require("../../models/Blog");

// const loadSnapshot = async (blogId) => {
// const blog = await Blog.findById(blogId);
// if (blog && blog.collabSnapshot) {
// return blog.collabSnapshot;
// }
// return null;
// };

// module.exports = { loadSnapshot };
// collaboration/persistence/loadSnapshot.js
const Blog = require("../../models/Blog");

const loadSnapshot = async (blogId) => {
const blog = await Blog.findById(blogId);
return blog?.collabSnapshot || null;
};

module.exports = { loadSnapshot };
29 changes: 29 additions & 0 deletions backend/collaboration/persistence/saveSnapshot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// const Blog = require("../../models/Blog");
// const Y = require("yjs");

// const saveSnapshot = async (blogId, ydoc) => {
// try {
// const update = Y.encodeStateAsUpdate(ydoc);
// await Blog.findByIdAndUpdate(blogId, { collabSnapshot: update });
// setInterval(async () => {
// for (const [blogId, ydoc] of docs) {
// await saveSnapshot(blogId, ydoc);
// }
// }, 30_000);
// } catch (e) {
// console.error("Failed to save snapshot", e);
// }
// };

// module.exports = { saveSnapshot };
// collaboration/persistence/saveSnapshot.js
const Blog = require("../../models/Blog");
const Y = require("yjs");

const saveSnapshot = async (blogId, ydoc) => {
const snapshot = Y.encodeStateAsUpdate(ydoc);
await Blog.findByIdAndUpdate(blogId, { collabSnapshot: Buffer.from(snapshot) });
};

module.exports = { saveSnapshot };

23 changes: 23 additions & 0 deletions backend/collaboration/socket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import io from 'socket.io-client';

let socket = null;

export const initSocket = (url, docId) => {
if (socket) return socket;

socket = io(url, { query: { docId } });

socket.on('connect', () => {
console.log('🔗 Socket connected!', socket.id);
});

socket.on('connect_error', (err) => {
console.error('❌ Socket connection error:', err);
});

socket.on('disconnect', (reason) => {
console.log('⚠️ Socket disconnected:', reason);
});

return socket;
};
Loading