built this project to handle proper document pagination on the web - basically trying to recreate that Google Docs/Word feel where you can actually see where the page ends. It's not just a bottomless text area.
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- Editor Engine: Tiptap (Headless wrapper for ProseMirror)
- Database: MongoDB (via Mongoose)
- AI: Google Gemini (1.5 Flash/Pro)
- Visual Pagination: Content automatically splits into pages (US Letter size). You can see the breaks while you type.
- Document Management: Simple dashboard to create, save, delete, and switch between docs.
- AI Writer: Integrated a "Generate with AI" button. Just give it a prompt and it writes the section for you using Gemini.
- Print Friendly: Custom CSS to make sure what you see on screen is exactly what gets printed. No weird sidebar artifacts.
You'll need a .env.local file in the root with these two keys:
MONGODB_URI=mongodb+srv://...
GEMINI_API_KEY=...Run npm install and then npm run dev to start it up.
I didn't want to overcomplicate things by splitting the actual document model up front, so I went with a visual approach. The editor behaves as one continuous block, but I run a ResizeObserver that constantly watches the content height. Based on US Letter dimensions (approx 1056px), I mathematically calculate where the breaks should occur and render a visual "cut" there. It gives the user immediate feedback of pagination without the complexity of managing split ProseMirror states.
- Visual vs Physical: Since it's technically one long text block, a line of text can occasionally sit right on the break line if the font sizes are weird. It's not "physically" moving nodes to a new container like MS Word does.
- Performance: For massive documents (100+ pages), having the entire document in one DOM tree might get heavy. Virtualization would be needed for production scale.
With more time, I would focus on:
- Accurate Page Identification: Refining the math to handle large elements (like tables/images) pushing to the next page more largely.
- Typing Space: Polishing the margins and padding so the "space to type" feels more distinct per page, avoiding any text bleed near the edges.