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:
-
Downgraded Next.js – Since Shadcn works best with Next.js 14, I modified my
package.json
to specify version 14 and reinstalled dependencies. -
Reinstalled dependencies – Running
npm install
ensured that my packages aligned with Next.js 14. - 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:
- Create a Theme Provider – This provider manages the theme state and persists user preferences.
- Wrap the Provider in Layout – Ensuring the entire application is covered.
-
Suppress Hydration Errors – Using
useEffect
andsuppressHydrationWarning
to handle hydration mismatches. -
Update Tailwind Configuration – Adding
darkMode: 'class'
intailwind.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' },
});
}
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,
});
}
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
-
Install NextAuth.js –
npm install next-auth
-
Create an API Route – NextAuth requires a dynamic API route in
pages/api/auth/[...nextauth].ts
. - 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!,
}),
],
});
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 };
}
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:
- Pushed my code to GitHub.
- Linked my repository to Vercel.
- Configured environment variables.
- 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)