Skip to content

notbd/tianwei.io

Repository files navigation

tianwei.io

The frontend layer of my personal website tianwei.io.

Stack

Site Architecture

  • Frontend: a Next.js application rendering content from the API dynamically using SSR with optimized caching strategies.
  • API Layer: a Hono service (Node.js) that serves content data from the content engine via REST endpoints.
  • Content Engine: a dedicated repo that stores, parses and syncs MDX to a remote PostgreSQL database.

Note: previously this site incorporated Contentlayer to manage frontend and content data in a single repo. I have since moved to a decoupled architecture that separates the frontend and backend which allows for better flexibility and scalability.

Local Run

git clone [email protected]:notbd/tianwei.io.git
cd tianwei.io
pnpm install

# Set up the `.env.local` according to the instructions in `.env.example`
# start local dev server
pnpm run dev

# lint
pnpm run lint

# build
pnpm run build

Notes:

  1. Cloudinary env variables need to be configured following the instructions for images to show properly.
  2. Typography and code highlighting are handled by custom React components within src/components/mdx and via the rehype-pretty-code package respectively.

Cache Revalidation & Warming

The application exposes a revalidation API endpoint at /api/revalidate that invalidates Next.js cache tags and optionally warms the cache by pre-fetching fresh data.

Authentication

Requests must include a Bearer token matching REVALIDATION_SECRET in the Authorization header.

Usage

  • Revalidate a specific post:

    POST /api/revalidate
    {
      "slug": "post-slug"
    }

    Invalidates both the post cache tag (post-{slug}) and the posts list tag, then warms both.

  • Revalidate by tag(s):

    POST /api/revalidate

    Single tag:

    {
      "tag": "tag-name"
    }

    Multiple tags:

    {
      "tags": ["tag1", "tag2"]
    }

    Invalidates the specified cache tags and warms matching routes.

Warming Behavior

After revalidation, the system automatically warms the cache by pre-fetching data for matching routes. This ensures fresh content is available immediately after invalidation:

  • posts tag: Fetches the posts list and all individual post pages
  • post-{slug} tags: Fetches the specific post page
  • Parallel execution: Warming executes in parallel for multiple tags to minimize latency

Warming failures are logged but don't prevent revalidation from succeeding, allowing the cache to be invalidated even if pre-fetching encounters errors.

License

Source code is licensed under AGPLv3,
The content is licensed under CC BY-NC-SA 4.0.

About

My personal site

Resources

License

Stars

Watchers

Forks