Back to all articles

How I Built the Blog on My Site

A technical look at how I built my blog with a frontend first reading experience, a PHP/MySQL API backend, Markdown publishing, and static generation that still picks up new posts before the next build.

4 April 20263 min readBy Serem Titus
Cover image for How I Built the Blog on My Site

When I added a blog to my site, I didn't want it to feel like a separate product. I wanted it to look, feel, and behave like the rest of the site while still keeping a simple writing workflow behind the scenes.

That idea shaped everything.

Instead of building a separate backend rendered blog, I split responsibilities:

  • Frontend - handles UI, routing, search, and reading
  • Backend - handles API, storage, auth, and publishing

This keeps things clean and maintainable.


Frontend: Owns the Blog Experience

The blog lives inside the main frontend app:

  • /blog - list of posts
  • /blog/:slug - individual post

This means:

  • Same design system
  • Same navigation and layout
  • No "separate CMS feel"

The blog pages are simple:

  • Fetch posts from the API
  • Support search
  • Render content consistently

Writer/admin features are not exposed here; this side is strictly for readers.


Backend: API Only

The backend does one job: serve data and handle writer actions.

It provides endpoints for:

  • Posts (list + detail)
  • Auth (login, logout, password)
  • Post management (create, edit)
  • Uploads (images)
  • Markdown preview

No HTML rendering. Just JSON.

This avoids mixing UI with business logic.


Database: Simple by Design

I use MySQL with minimal structure.

blog_posts

  • slug, title, summary
  • markdown + HTML content
  • cover image
  • timestamps

blog_settings

  • stores things like password hash

Since I'm the only writer, I skipped:

  • roles
  • drafts
  • approvals

Less complexity, faster workflow.


Markdown as the Source

I write in Markdown, not HTML.

  • Markdown = source of truth
  • Backend converts to sanitized HTML
  • Both versions are stored

There's also a preview endpoint, so what I see before publishing is exactly what gets published.


Writer Workflow: Fast and Private

The admin system is built for speed:

  • Simple password login (session based)
  • Create/edit posts
  • Upload images
  • Preview Markdown

Key choices:

  • No public admin access
  • CSRF protection included
  • No drafts - publishing is immediate

This matches how I actually write.


Image Uploads

Images go through the backend:

  • Validates type and size
  • Stores in uploads directory
  • Returns a public URL

Simple and controlled, no external asset juggling.


Static + Live Data

I combine static generation with live API updates:

At build time:

  • Prerender /blog and posts - fast and SEO friendly

At runtime:

  • Fetch latest data from API - stays fresh

Result:

  • Fast pages
  • Up to date content
  • No need to rebuild after every post

Why This Architecture Works

Each layer does what it's best at:

  • Frontend - UI & experience
  • Backend - data & auth
  • Build step - static output
  • API - freshness

This avoids:

  • heavy CMS complexity
  • disconnected blog systems
  • messy backend rendering

Final Thought

The tools (React, PHP, MySQL, Markdown) aren't the important part.

The key decision was architectural:

Keep the frontend for reading, the backend API only, and the workflow simple.

For a one writer blog, this setup is clean, fast, and easy to maintain.