Install nextjs npx create-next-app@latest https://nextjs.org/docs/getting-started/installation
Install the following
npm install react-daisyui
https://www.npmjs.com/package/react-daisyui
daisyUI components built with React, Typescript and TailwindCSS
Mongoose
npm install mongoose
https://www.npmjs.com/package/mongoose
edit tailwind.config.ts Add daisyui to plugins
edit tailwind.config.ts
//edit tailwind.config.ts import type { Config } from 'tailwindcss' const config: Config = { content: [ './pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { backgroundImage: { 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, }, }, plugins: [require('daisyui')], //https://www.npmjs.com/package/react-daisyui } export default config.env
MONGODB_URI=mongodb://127.0.0.1/app\page.tsx
// import { dbConnect } from "@/lib/connectMongo"; import Link from "next/link"; import Image from 'next/image' async function getData(perPage, page) { try { // DB Connect const client = await dbConnect(); const db = client.db("nextjs14"); // DB Query const items = await db .collection("products") .find({}) .skip(perPage * (page - 1)) .limit(perPage) .toArray(); const itemCount = await db.collection("products").countDocuments({}); const respnse = { items, itemCount }; //console.log(items); console.log(itemCount); return respnse; } catch (error) { throw new Error("Failed to fetch data. Please try again later."); } } export default async function Page({ searchParams }) { let page = parseInt(searchParams.page, 10); page = !page || page < 1 ? 1 : page; const perPage = 4; const data = await getData(perPage, page); const totalPages = Math.ceil(data.itemCount / perPage); const prevPage = page - 1 > 0 ? page - 1 : 1; const nextPage = page + 1; const isPageOutOfRange = page > totalPages; const pageNumbers = []; const offsetNumber = 3; for (let i = page - offsetNumber; i <= page + offsetNumber; i++) { if (i >= 1 && i <= totalPages) { pageNumbers.push(i); } } return ( <> <div className="container mx-auto"> <div className="flex justify-between items-center"> <h1 className="font-bold py-10 text-2xl">Next.js 14 Pagination MongoDB</h1> </div> <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> <thead className="bg-gray-100 dark:bg-gray-700"> <tr> <th scope="col" className="p-4"> <div className="flex items-center"> <input id="checkbox-all" type="checkbox" className="w-4 h-4 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" /> <label htmlFor="checkbox-all" className="sr-only">checkbox</label> </div> </th> <th className="py-3 text-left">Image</th> <th className="py-3 text-left">Product Name</th> <th className="py-3 text-left">Price</th> <th className="py-3 text-left">Category</th> <th className="py-3 text-left">Actions</th> </tr> </thead> <tbody className="bg-white divide-y divide-gray-200 dark:bg-gray-800 dark:divide-gray-700"> {data.items.map((item) => ( <tr key={item._id} className="hover:bg-gray-100 dark:hover:bg-gray-700"> <td className="p-4 w-4"> <div className="flex items-center"> <input id="checkbox-table-1" type="checkbox" className="w-4 h-4 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" /> <label htmlFor="checkbox-table-1" className="sr-only">checkbox</label> </div> </td> <td> <Image src={item.image} alt={item.name} width={80} height={80} className="rounded-lg" /> </td> <td>{item.name}</td> <td>${item.price}</td> <td>{item.category}</td> <td> Delete </td> </tr> ))} </tbody> </table> {isPageOutOfRange ? ( <div>No more pages...</div> ) : ( <div className="flex justify-center items-center mt-16"> <div className="flex border-[1px] gap-4 rounded-[10px] border-light-green p-4"> {page === 1 ? ( <div className="opacity-60 py-2 px-5" aria-disabled="true"> Previous </div> ) : ( <Link href={`?page=${prevPage}`} className="py-2 px-5" aria-label="Previous Page"> Previous </Link> )} {pageNumbers.map((pageNumber, index) => ( <Link key={index} className={ page === pageNumber ? "bg-blue-500 font-bold py-2 px-5 rounded text-white" : "bg-gray-500 hover:bg-gray-400 font-bold py-2 px-5 rounded text-white" } href={`?page=${pageNumber}`} > {pageNumber} </Link> ))} {page === totalPages ? ( <div className="opacity-60 py-2 px-5" aria-disabled="true"> Next </div> ) : ( <Link href={`?page=${nextPage}`} className="py-2 px-5" aria-label="Next Page"> Next </Link> )} </div> </div> )} </div> </> ); }app\layout.tsx
//app\layout.tsx import type { Metadata } from 'next' import { Inter } from 'next/font/google' import './globals.css' const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { title: 'Next.js 14 MongoDB Pagination', description: 'Generated by create next app', } export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="en"> <body className={inter.className}>{children}</body> </html> ) }lib\connectMongo.ts
//lib\connectMongo.ts import { MongoClient } from "mongodb"; const MONGODB_URI = process.env.MONGODB_URI; let client = null; export async function dbConnect() { if (client) { return client; } if (!MONGODB_URI) { console.log("MongoDb URI not found."); } try { client = await MongoClient.connect(MONGODB_URI); console.log("Connected to MongoDb successfully."); return client; } catch (error) { console.error("Error connecting to the database:", error); } }run C:\nextjs>npm run dev