← back to works

MERN Stack Blog Platform

Jan 2022fullstack
Next.jsMongoDBExpress.jsMongooseNode.jsTypeScriptMarkdown

overview

A full stack blog platform using the MERN stack with Next.js replacing Create React App for server-side rendering and improved SEO. Authors can write in Markdown with a live split-pane preview the left pane shows raw Markdown, the right renders the output in real time via a debounced event listener.

The backend is an Express.js REST API with Mongoose ODM providing schema validation and typed document models. Posts, authors, tags, and comments are modelled as separate collections with references rather than embedded documents this keeps individual documents small and makes tag/author queries efficient. JWT authentication is issued on login and validated as Bearer tokens on protected endpoints.

Next.js provides server-side rendering for published posts, which means post content is in the HTML at request time for search engine indexing. The editor interface is a pure client-side SPA for fast interactive feedback. Static generation is used for the homepage and tag listing pages.

architecture

// MERN stack architecture
Next.js Frontend
  ├── SSR: /posts/[slug]     (published post pages)
  ├── SSG: /                 (homepage, tag pages)
  └── SPA: /editor           (Markdown editor, real-time preview)
     │
     ▼
Express.js REST API
  ├── POST /auth/login        (JWT issue)
  ├── GET  /posts             (list, filter by tag)
  ├── GET  /posts/:slug       (single post)
  ├── POST /posts             (create auth required)
  └── PUT  /posts/:slug       (update auth required)
     │
     ▼
Mongoose ODM
     │
     ▼
MongoDB
  ├── posts      { title, slug, content, tags[], authorId }
  ├── authors    { name, bio, avatarUrl }
  └── tags       { name, slug, count }

technical.decisions

Next.js over CRA for SSR

Blog post content needs to be in the HTML at request time for search engine indexing. Create React App renders on the client, meaning crawlers see an empty shell. Next.js getServerSideProps fetches the post and embeds it in the HTML published posts are fully indexable without a separate SSR server.

Reference-based schema over embedding

Embedding all post data in a single MongoDB document (including comments, tags, author) would grow documents unboundedly and make cross-collection queries expensive. Separate collections with ObjectId references keeps document sizes predictable and allows efficient tag and author queries with populate().

Debounced Markdown preview

Parsing Markdown on every keypress is CPU-intensive for long documents. A 150ms debounce on the input event balances responsiveness with performance the preview updates fast enough to feel real-time while avoiding parser invocations on every keystroke.

outcomes

  • Published posts fully server-side rendered for SEO
  • Real-time Markdown preview with 150ms debounce
  • Reference-based schema keeps document sizes predictable
  • JWT auth with Bearer token pattern for protected endpoints

tech.stack

Next.jsMongoDBExpress.jsMongooseNode.jsTypeScriptMarkdown