Loading...
Azure-Ad-B2C-Claps
Author Cloudapp
E.G.

Next.js 14 / Upstash Redis - Hinzufügen einer Clap-Funktion innerhalb weniger Minuten

30. Mai 2024
Inhaltsverzeichnis

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.

Pricing Redis Upstash
Pricing Redis Upstash

Neue NPM Pakete

Wir benötigen ein neues NPM Paket für Redis.

npm i @upstash/redis

Registrieren 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.

Redis-Upstash-Redis-Create
Redis-Upstash-Redis-Create

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.

Redis-Upstash-Env
Redis-Upstash-Env

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.

SEO-Title-Blog-Post
SEO-Title-Blog-Post

Cloudapp-dev und bevor Sie uns verlassen

Danke, dass Sie bis zum Ende gelesen haben. Noch eine Bitte bevor Sie gehen:

Wenn Ihnen gefallen hat was Sie gelesen haben oder wenn es Ihnen sogar geholfen hat, dann würden wir uns über einen "Clap" 👏 oder einen neuen Follower auf unseren Medium Account sehr freuen.

Verwandte Artikel