In diesem Beitrag zeige ich Ihnen, wie schnell Sie eine Klatschfunktion zu Ihren Blogbeiträgen hinzufügen können. Wir verwenden Upstash Redis als unsere serverlose DB, Next.js 14 für die App und Azure AD B2C mit Next-Auth, damit nur eingeloggte Benutzer klatschen können.
Hier ist das GitHub repo mit dem vollständigen Code.
Redis von Upstash kurz erklärt
Redis von Upstash ist ein serverloser Datenbankdienst, der für Redis optimiert ist und skalierbare und latenzarme Datenspeicherung bietet. Er verwendet ein Pay-per-Request-Preismodell, was ihn für Anwendungen mit variablen Arbeitslasten kosteneffektiv macht.
Upstash übernimmt das Infrastrukturmanagement, sodass Entwickler sich auf den Aufbau ihrer Anwendungen konzentrieren können, ohne sich um die Serverwartung kümmern zu müssen. Die Plattform sorgt für hohe Verfügbarkeit und Haltbarkeit, indem sie Replikation und Failover automatisch verwaltet.
Zudem integriert sich Upstash nahtlos in serverlose Umgebungen und unterstützt verschiedene Programmiersprachen und Frameworks. Seine Benutzerfreundlichkeit und effiziente Leistung machen es zu einer geeigneten Wahl für Echtzeitanwendungen wie Caching, Sitzungsverwaltung und Analytik.
Wir werden den "Free plan" für unser Projekt benutzen.

Neue NPM Pakete
Wir benötigen ein neues NPM Paket für Redis.
npm i @upstash/redisRegistrieren eines Upstash Kontos
Öffnen Sie https://console.upstash.com/login, melden Sie sich mit Ihrem GitHub-, Google- oder Amazon-Konto an und erstellen Sie eine neue Redis-Datenbank.

Wählen Sie dann die zuvor erstellte Redis-Datenbank aus und klicken Sie auf den ersten Tab „Details“, damit Sie den Endpunkt und das Passwort (Token) kopieren können.

Wir fügen die kopierten Infos in unserer .env.local Datei ein.
# Redis Upstash
UPSTASH_REDIS_REST_URL="https://xxxx.upstash.io"
UPSTASH_REDIS_REST_TOKEN="xxxxxxxx"Neue Api Route für den Zugriff auf Redis
Wir erstellen eine neue Api Route für den Datenaustausch mit Redis (Upstash)
// app/api/claps/route.ts
import { NextRequest, NextResponse } from "next/server";
import redis from "../../../lib/redis";
export async function POST(request: NextRequest) {
const { slug } = await request.json();
if (!slug) {
return NextResponse.json({ error: "Slug is required" }, { status: 400 });
}
const claps = await redis.incr(`claps:${slug}`);
return NextResponse.json({ claps });
}
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const slug = searchParams.get("slug");
if (!slug) {
return NextResponse.json({ error: "Slug is required" }, { status: 400 });
}
const claps = await redis.get<number>(`claps:${slug}`);
return NextResponse.json({ claps: claps || 0 });
}Neue Redis Lib Datei
Wir erstellen eine neue Datei (src/lib/redis.ts) für die Redisintegration
// lib/redis.ts
import { Redis } from "@upstash/redis";
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
export default redis;Neue Komponente für Applausfunktion
Es ist Zeit für die Erstellung unserer neuen Clap-Komponente. Da wir das Klatschen auf eingeloggte Benutzer beschränken, müssen wir den useSession-Hook aus dem next-auth/react-Paket importieren.
"use client";
import { useState, useEffect } from "react";
import type { LocaleTypes } from "@/app/i18n/settings";
import { useTranslation } from "@/app/i18n/client";
import { useParams } from "next/navigation";
import { useSession } from "next-auth/react";
interface ClapButtonProps {
slug: string | undefined;
}
export default function ClapButton({ slug }: ClapButtonProps) {
const [claps, setClaps] = useState<number>(0);
const locale = useParams()?.locale as LocaleTypes;
const { t } = useTranslation(locale, "common");
const { data: session } = useSession();
const disabled = !session;
useEffect(() => {
const fetchClaps = async () => {
const res = await fetch(`/api/claps?slug=${slug}`);
const data = await res.json();
setClaps(data.claps);
};
fetchClaps();
}, [slug]);
const handleClap = async () => {
const res = await fetch("/api/claps", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ slug }),
});
const data = await res.json();
setClaps(data.claps);
};
return (
<div>
{(session && (
<div className="pb-4 text-base">{t("claps.clapText")}</div>
)) || <div className="pb-4 text-base">{t("claps.clapLogin")}</div>}
{/* <div className="pb-4 text-base">{t("clapButton")}</div> */}
<button
disabled={disabled}
className="text-2xl p-2 dark:bg-gray-500 rounded-lg dark:text-white bg-gray-200 text-gray-600 w-20"
onClick={handleClap}
>
👏 {claps}
</button>
</div>
);
}Als letzten Schritt werden wir die neue Komponente in unsere page.tsx importieren und den „Slug“ an die Komponente übergeben, da dies der Schlüssel ist, den wir für die Datenspeicherung benötigen.
// Claps
import ClapButton from "@/components/contentful/ClapButton.component";
<Container className="max-w-5xl mt-8">
<ClapButton slug={blogPost.slug || ""} />
</Container>Seitenvorschau mit integrierter Applausfunktion
Hier ist ein Screenshot des Endergebnisses.

Cloudapp-dev und bevor Sie uns verlassen
Danke, dass Sie bis zum Ende gelesen haben. Noch eine Bitte bevor Sie gehen:




