DEV Community

Cover image for I Built a YouTube Dislike Viewer with Next.js 16 — Here's How
GuideBook
GuideBook

Posted on

I Built a YouTube Dislike Viewer with Next.js 16 — Here's How

I Built a YouTube Dislike Viewer with Next.js 16

Ever since YouTube removed the public dislike count, it's been harder to judge video quality at a glance. So I built a
simple tool to bring it back.

Live site: https://www.youtubedislikeviewer.shop

What It Does

Paste any YouTube URL or video ID, and instantly see:

  • 👍 Likes & 👎 Dislikes
  • 📊 Like/Dislike ratio bar
  • 👁 View count & rating
  • 🕐 Search history (stored locally)

Tech Stack

  • Next.js 16 (App Router + Turbopack)
  • React 19 + TypeScript 5.9
  • Tailwind CSS 4
  • Return YouTube Dislike API (community-driven dislike data)

Key Design Decisions

API Proxy with Caching

Instead of calling the dislike API directly from the client, I set up a server-side proxy route at /api/dislike. This
lets me add cache headers (s-maxage=300, stale-while-revalidate=600) so repeated lookups for the same video are fast
and cheap.

// app/api/dislike/route.ts (simplified)
export async function GET(request: Request) {
const videoId = new URL(request.url).searchParams.get('videoId');
const res = await fetch(
https://returnyoutubedislikeapi.com/votes?videoId=${videoId}
);
const data = await res.json();
return Response.json(data, {
headers: {
'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=600',
},
});
}

Robust URL Parsing

YouTube URLs come in many flavors — youtube.com/watch?v=, youtu.be/, /embed/, or just a raw 11-character ID. A single
extraction function handles all of them with regex.

Thumbnail Fallback

Not every video has a maxresdefault thumbnail. The component tries the highest quality first and falls back to
hqdefault on error — no broken images.

What I Learned

  1. Next.js 16 App Router is mature and pleasant to work with. The server/client component split feels natural once you get used to it.
  2. Caching at the edge with simple Cache-Control headers goes a long way — no Redis needed for a project this size.
  3. localStorage is still a perfectly fine solution for lightweight client-side persistence like search history.

Try It Out

Check it out at https://www.youtubedislikeviewer.shop and let me know what you think!

Top comments (0)