DEV Community

Bismark
Bismark

Posted on • Edited on

G-Client (Course Management APP) Journal

G-Client (Course Management APP) Journal

Technologies Used

  • Next.js
  • Shadcn
  • TypeScript
  • NextRequest

Part 1: Navigating the Challenges of Next.js Development

Starting a new project always comes with its set of challenges. Even though I'm familiar with Next.js, setting up essential tools for my development process was trickier than expected. This journal documents my journey through overcoming compatibility issues, setting up necessary tools, and implementing dark mode in my project.

Struggles with Shadcn Setup

Shadcn is my favorite component library due to its ease of use and flexibility. However, when integrating it into my project, I encountered issues. My project was initially set up with Next.js 15, which is not fully supported by Shadcn yet. During installation, I faced errors and compatibility warnings, causing delays in my setup.

How I Fixed It:

  1. Downgraded Next.js – Since Shadcn works best with Next.js 14, I modified my package.json to specify version 14 and reinstalled dependencies.
  2. Reinstalled dependencies – Running npm install ensured that my packages aligned with Next.js 14.
  3. Reconfigured Shadcn – Once the installation issues were resolved, I ensured that the components worked seamlessly across my app.

After making these adjustments, everything functioned as expected, and I could use Shadcn components without any further issues.

Implementing Light and Dark Mode in Next.js

A major feature I wanted in my application was a clean and scalable solution for light and dark mode. Initially, this seemed straightforward, but I faced challenges ensuring persistence across sessions and handling hydration mismatches.

Steps to Implement Dark Mode in Next.js:

  1. Create a Theme Provider – This provider manages the theme state and persists user preferences.
  2. Wrap the Provider in Layout – Ensuring the entire application is covered.
  3. Suppress Hydration Errors – Using useEffect and suppressHydrationWarning to handle hydration mismatches.
  4. Update Tailwind Configuration – Adding darkMode: 'class' in tailwind.config.js allowed theme manipulation via CSS classes.

After implementing these steps, the theme switching worked seamlessly across my project, enhancing the user experience.

Final Thoughts

The initial setup was frustrating, but overcoming these challenges made the development process much smoother. If you're working with Next.js 15 and encountering issues with Shadcn or dark mode implementation, I hope my experience helps you troubleshoot effectively.


Part 2: Understanding Request and NextRequest in Next.js API Routes

Introduction

In Next.js API routes, handling requests efficiently is crucial for building performant applications. The NextRequest object extends the default Request object, providing enhanced capabilities such as structured URL parsing, easier access to cookies, and improved request metadata handling.

Differences Between Request and NextRequest

The standard Request object is suitable for handling basic HTTP requests, while NextRequest offers additional utilities tailored for Next.js middleware and API routes.

Example: Using Request

export async function GET(req: Request) {
    const body = await req.json();
    return new Response(JSON.stringify({ message: 'Request received' }), {
        status: 200,
        headers: { 'Content-Type': 'application/json' },
    });
}
Enter fullscreen mode Exit fullscreen mode

Example: Using NextRequest

import { NextRequest, NextResponse } from 'next/server';

export async function GET(req: NextRequest) {
    const body = await req.json();
    const pathname = req.nextUrl.pathname;
    const searchParams = req.nextUrl.searchParams;
    const clientIp = req.ip;
    const cookies = req.cookies.getAll();

    return NextResponse.json({ 
        message: `Received data: ${JSON.stringify(body)}`,
        path: pathname,
        query: Object.fromEntries(searchParams),
        ip: clientIp,
        cookies: cookies,
    });
}
Enter fullscreen mode Exit fullscreen mode

When to Use Each

  • Use Request for basic API handling when additional Next.js-specific utilities are not needed.
  • Use NextRequest when working with middleware, edge functions, or when structured URL parsing and request metadata are required.

Understanding these differences ensures that I use the right tool for the job, optimizing my Next.js API routes for better efficiency and maintainability.


Part 3: Implementing Authentication with NextAuth.js

Introduction

Authentication is a crucial part of any course management system. I decided to implement authentication using NextAuth.js due to its flexibility and built-in support for multiple providers.

Setting Up NextAuth.js

  1. Install NextAuth.jsnpm install next-auth
  2. Create an API Route – NextAuth requires a dynamic API route in pages/api/auth/[...nextauth].ts.
  3. Configure Providers – I chose GitHub authentication for simplicity.

Example Setup:

import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github";

export default NextAuth({
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

With authentication in place, users can log in securely and access personalized course data.


Part 4: Optimizing Performance with ISR and Caching

Introduction

Since my app involves displaying course content, optimizing performance was a priority. Incremental Static Regeneration (ISR) and caching strategies helped reduce server load and improve user experience.

Implementing ISR

ISR allows me to update static pages without rebuilding the entire site.

export async function getStaticProps() {
    const courses = await fetchCourses();
    return { props: { courses }, revalidate: 10 };
}
Enter fullscreen mode Exit fullscreen mode

This ensures the course list updates every 10 seconds while keeping page loads fast.


Part 5: Deploying and Monitoring the Application

Introduction

After development, I needed to deploy and monitor the app to ensure smooth performance.

Deployment with Vercel

Since Next.js integrates seamlessly with Vercel, deployment was straightforward:

  1. Pushed my code to GitHub.
  2. Linked my repository to Vercel.
  3. Configured environment variables.
  4. Deployed with a single click.

Monitoring Performance

To track errors and optimize performance, I integrated tools like:

  • Vercel Analytics for real-time insights.
  • Sentry for error tracking.
  • Google Lighthouse for performance audits.

This setup helps maintain a stable and high-performing application.


Conclusion

This journal captures my technical journey in setting up and optimizing my course management app, G-Client. From troubleshooting compatibility issues with Shadcn to implementing dark mode, authentication, performance optimizations, and deployment strategies, each challenge taught me valuable lessons. As I continue developing this project, I expect to encounter more hurdles, but with every problem comes an opportunity to learn and improve.

Top comments (0)