এই টিউটোরিয়ালে আমরা আপনার ব্লগের জন্য একটি কমেন্ট সেকশন তৈরি করব। আমাদের ব্যবহার할 টেক স্ট্যাক:
- NextJS 13 (App ডিরেক্টরিতে)
- NextAuth (অথেন্টিকেশনের জন্য)
- Upstash Redis (কমেন্ট সংরক্ষণের জন্য)
- SWR (কমেন্ট ক্যাশিং এবং রিভ্যালিডেশনের জন্য)
চলুন শুরু করি।
NextAuth দিয়ে অথেন্টিকেশন হ্যান্ডল করা
প্রথমে, আমরা যেকোনো কাকে কমেন্ট পোস্ট করার অনুমতি দিতে পারি না, ঠিক কি? কেউ আপনার ব্লগে কমেন্ট স্প্যাম করার জন্য একটি স্ক্রিপ্ট চালাতে পারে। আসুন প্রথমে একটি অথেন্টিকেশন সিস্টেম তৈরি করি মানুষকে কমেন্ট পোস্ট করার অনুমতি দেওয়ার আগে। আমরা NextAuth ব্যবহার করব।
আপনার প্রজেক্টে next-auth ইনস্টল করুন।
pnpm install next-auth
App Directory-এর ভিতর ডিরেক্টরি স্ট্রাকচার:
. ├── app │ ├── api │ │ └── auth │ │ └── [...nextauth] │ │ └── route.ts │ ├── blog │ │ ├── page.tsx │ │ └── [...slug] │ │ └── page.tsx │ ├── components │ │ └── LoginButton.tsx │ ├── favicon.ico │ ├── globals.css │ ├── layout.tsx
আমাদের Auth API রুট সেট আপ করি:
// app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";
const handler = NextAuth({ providers: [ GithubProvider({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, }), ], callbacks: { async session({ session, token }) { if (session && session.user && token.sub) { session.user.sub = token.sub; } return session; }, }, });
export { handler as GET, handler as POST };
এখান থেকে একটি নতুন Github OAuth অ্যাপ্লিকেশন তৈরি করে GITHUB_CLIENT_ID এবং GITHUB_CLIENT_SECRET পান।
এখন, NextAuth আপনাকে যেকোনো ক্লায়েন্ট কম্পোনেন্ট থেকে next-auth-র signIn এবং signOut ফাংশন ব্যবহার করে সাইন ইন এবং সাইন আউট করতে দেয়। কিন্তু এর আগে, আপনাকে একটি কনটেক্সট প্রোভাইডার সেট আপ করতে হবে যা আপনার সম্পূর্ণ অ্যাপ্লিকেশনকে র্যাপ করে।
// app/layout.tsx
"use client";
import "./globals.css";
import { SessionProvider } from "next-auth/react";
export default function RootLayout({ children, }: { children: React.ReactNode; }) {
return ( <html lang="en"> <SessionProvider> <body>{children}</body> </SessionProvider> </html> ); }
SessionProvider আপনাকে অ্যাপ্লিকেশনের যেকোনো ক্লায়েন্ট কম্পোনেন্ট থেকে সেশন স্টেট অ্যাক্সেস করতে দেবে।
আপনি next-auth-র useSession হুক ব্যবহার করে সেশন স্টেট অ্যাক্সেস করতে পারেন। এখানে একটি লগইন বাটনের নমুনা:
"use Client";
import { signIn, signOut, useSession } from "next-auth/react";
export default function LoginButton() {
const { data: session } = useSession();
if (session) { return ( <div> Signed in as {session.user?.name} using {session.user?.email} <br /> <button onClick={() => signOut()}>Sign out</button> </div> ); }
return ( <div> Not signed in <br /> <button onClick={() => signIn()}> Sign in </button> </div> ); }
এইভাবে, আমাদের Auth সিস্টেম জায়গায় আছে। এখন সার্ভার সাইড রুট তৈরি করি Redis ডেটাবেসে কমেন্ট সংরক্ষণ করার জন্য।
Redis ডেটাবেস সেট আপ করা
- Upstash-এ যান এবং একটি Redis ডেটাবেস তৈরি করুন।
- আপনার ব্যবহারকারীদের কাছাকাছি একটি রিজন বেছে নিন এবং TLS এনক্রিপশন অপ্ট করুন।
@upstash/redisপ্যাকেজ ইনস্টল করুন।
pnpm install @upstash/redis
- এই টোকেনগুলো আপনার
.env.local-এ কপি করুন।
আমরা আমাদের API এন্ডপয়েন্টগুলো এখন এই ডিরেক্টরি স্ট্রাকচারে লিখব:
. ├── app │ ├── api │ │ ├── auth │ │ │ └── [...nextauth] │ │ │ └── route.ts │ │ ├── comment │ │ │ ├── delete │ │ │ │ └── route.ts │ │ │ ├── get │ │ │ │ └── route.ts │ │ │ └── post │ │ │ └── route.ts │ │ └── lib │ │ ├── getUser.ts │ │ └── redis.ts
- একটি Redis ক্লায়েন্ট ইনস্ট্যান্স তৈরি করুন
// app/api/lib/redis.ts
import { Redis } from "@upstash/redis";
/* এটি process.env ব্যবহার করে আপনার এনভায়রনমেন্ট থেকে UPSTASH_REDIS_REST_URL এবং UPSTASH_REDIS_REST_TOKEN লোড করার চেষ্টা করে */
const redis = Redis.fromEnv();
export default redis;
ততটুকুই। আমাদের Redis ক্লায়েন্ট এখন সেট আপ হয়েছে এবং যা বাকি আছে তা হলো আমাদের অ্যাপ্লিকেশনে এর জন্য API রুট সেট আপ করা।
আমরা কমেন্ট সংরক্ষণের জন্য Redis Lists ব্যবহার করব। তারা একটি স্ট্যাক হিসেবে কাজ করতে পারে যাতে সবচেয়ে সাম্প্রতিক কমেন্টটি টপে প্রদর্শিত হয়। অবশ্যই, আমরা সর্টিং লজিক ক্লায়েন্ট সাইডেও ইমপ্লিমেন্ট করতে পারতাম কিন্তু যখন Redis ইতিমধ্যে এই ডেটা স্ট্রাকচার দিচ্ছে, তাহলে আসুন এটি ব্যবহার করি।
আপনি পুরো কোড এখানে দেখতে পারেন। এখানে সারসংক্ষেপ:
একটি কমেন্ট তৈরি করুন:
redis.lpush(referer, comment)। এটিrefererকি دار লিস্টে কমেন্টটি পুশ করবে।সব কমেন্ট পান
redis.lrange(referer, 0, -1)একটি কমেন্ট ডিলিট করুন
redis.lrem(referer, 0, comment)। এটিrefererকি دار লিস্টেcomment-এর সব অকারেন্স ডিলিট করবে।
আমাদের API এখন জায়গায় আছে। আসুন ফ্রন্টএন্ডকে ব্যাকএন্ডের সাথে ইন্টিগ্রেট করি।
ক্লায়েন্ট সাইড সেট আপ করা
এটা så কঠিন নয়। আমাদের শুধু আপনার তৈরি করা এন্ডপয়েন্টগুলো fetch ব্যবহার করে হিট করতে হবে। আমরা swr লাইব্রেরি ব্যবহার করব কমেন্টের ক্যাশিং এবং রিভ্যালিডেশনের জন্য। কিন্তু ব-olেই React Query-এর মত অন্যান্য লাইব্রেরি ব্যবহার করতে পারেন।
আমরা একটি useComment() হুক তৈরি করব যেটিতে onSubmit() এবং onDelete() হ্যান্ডলার থাকবে রিকোয়েস্ট করার জন্য।
"use client";
import { useState } from "react";
import type { Comment } from "@/app/interfaces/interfaces";
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
const useComment = () => {
const [text, setText] = useState("");
const { data: comments, mutate } = useSWR<Comment[]>( "/api/comment/get", fetcher, { fallbackData: [], }, );
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
await fetch("/api/comment/post", { method: "POST", body: JSON.stringify({ text }), headers: { "Content-Type": "application/json", }, });
setText("");
await mutate();
} catch (error) { console.log(error); }
};
const onDelete = async (comment: Comment) => {
try {
await fetch("/api/comment/delete", { method: "POST", body: JSON.stringify({ comment }), headers: { "Content-Type": "application/json", }, });
await mutate();
} catch (error) { console.log(error); }
};
return { text, setText, comments, onSubmit, onDelete };
};
export default useComment;
এখন আমাদের কমেন্ট সেকশনটি হয়ে গেল। আমরা কমেন্ট ফেচ, পোস্ট এবং ডিলিট করতে পারছি। পরবর্তী ধাপগুলো হবে কমেন্ট বক্স এবং কমেন্ট লিস্টের জন্য কম্পোনেন্ট তৈরি করা। এখানে একটি সম্পূর্ণ নমুনা আছে।