Upstash Integration with Next.js

Upstash Redis + Next.js = scalable web features without backend complexity.
This project showcases how I integrated Upstash into my personal website, sandimaulanajuhana.com, to create a fast, lightweight, and serverless page view counter — optimized for edge runtime and minimal cost.
⚙️ Use Case: Realtime Page View Counter
When a page is visited:
- A
POST
request to/api/views/[slug]
increments the view counter in Redis. - A
GET
request fetches the current number of views. - The number is shown live using a React component.
API Route Example
// /api/views/[slug]/route.ts
import { redis } from '@/lib/redis'
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const { pathname } = new URL(request.url)
const slug = pathname.split('/').pop()
await redis.incr(`views:${slug}`)
return NextResponse.json({ success: true })
}
export async function GET(request: NextRequest) {
const { pathname } = new URL(request.url)
const slug = pathname.split('/').pop()
const views = await redis.get<number>(`views:${slug}`)
return NextResponse.json({ views: views ?? 0 })
}
React Component
components/ViewCounter
'use client'
import { useEffect, useState, useRef } from 'react'
type ViewCounterProps = {
slug: string
increment?: boolean
silent?: boolean
}
export default function ViewCounter({
slug,
increment = true,
silent = false,
}: ViewCounterProps) {
const [views, setViews] = useState<number | null>(null)
const hasPosted = useRef(false)
useEffect(() => {
if (increment && !hasPosted.current) {
hasPosted.current = true
fetch(`/api/views/${slug}`, { method: 'POST' }).catch(console.error)
}
fetch(`/api/views/${slug}`)
.then((res) => res.json())
.then((data) => setViews(data.views))
.catch(console.error)
}, [slug, increment])
if (views === null || silent) return null
return (
<span className="ml-3 text-emerald-500 dark:text-emerald-500">
📖 {views.toLocaleString()} Reads
</span>
)
}
🚀 Why Upstash? ⚡ Ultra fast — Redis in-memory speed
🌍 Edge-ready for global low-latency
💸 Serverless pricing — great for solo developers
🧘 Stateless integration — works cleanly with App Router routes
🧪 Experimental Add-on: Telegram Bot Notifications I extended the counter with a Telegram bot that sends:
Article slug
Device type
IP & location (via Vercel Analytics)
Timestamp
Rate-limited by IP & time window to prevent spam.
📘 Related Article
👉 Counting Page Views with Upstash Redis in a Next.js App Router Project
This project is part of a larger effort to explore practical, scalable solutions using serverless tech — and Redis is one of my favorite tools to build lightweight features without backend overhead.