nextjs revision

๐Ÿ“… 01 Aug 2025

View on Github โ†—

date: 2025-08-01 topics: [nextjs, restapi, api-routes, async, db-handling, ssr, seo] day: 16

๐Ÿ“˜ Day 16 โ€“ REST API Handlers, Async Fetching, SSR & SEO Mastery in Next.js

โœ… What I Worked On

  • Revisited how useEffect() and async functions differ and where to use them
  • Implemented loading states for better UX during fetch
  • Refactored API routes using GET, POST, PUT, DELETE inside App Router
  • Used NextRequest and NextResponse for request/response handling
  • Practiced reading req.body and connecting to a mock DB
  • Explored SSR (Server-Side Rendering) and SEO in Next.js
  • Added static and dynamic metadata for enhanced SEO

๐Ÿ“š What I Learned

โš™๏ธ useEffect() vs async Function

ConceptuseEffect()async Function
PurposeReact side-effect (client-side logic)Run async logic with await
Usage ContextInside React componentsAnywhere (backend, frontend, utilities)
Direct Async Use?โŒ No โ€“ wrap async inside useEffectโœ… Yes, use freely
Common UseFetching, DOM updatesFetching, DB queries, file I/O
useEffect(() => {
  const fetchData = async () => {
    const res = await fetch('/api/data');
    const data = await res.json();
    setData(data);
  };
  fetchData();
}, []);

๐Ÿ”„ Loading State in Next.js

const [loading, setLoading] = useState(true);

useEffect(() => {
  const fetchSomething = async () => {
    setLoading(true);
    await fetch('/api/data');
    setLoading(false);
  };
  fetchSomething();
}, []);
  • loading is toggled to show UI feedback (e.g., spinner/skeleton)
  • Common for client-side fetches in CSR apps

๐Ÿงฉ What is an API Route?

  • Pages Router:
export default function handler(req, res) { ... }
  • App Router:
export async function GET(req) { ... }
export async function POST(req) { ... }

๐Ÿงต REST API with GET, POST, PUT, DELETE

// app/api/users/route.js
import { NextResponse } from 'next/server';

export async function GET(req) {
  return NextResponse.json({ message: 'GET request success' });
}

export async function POST(req) {
  const body = await req.json();
  return NextResponse.json({ message: 'User created', data: body }, { status: 201 });
}

export async function PUT(req) {
  const body = await req.json();
  return NextResponse.json({ message: 'User updated', data: body });
}

export async function DELETE(req) {
  return NextResponse.json({ message: 'User deleted' }, { status: 204 });
}

๐Ÿง  NextRequest & NextResponse

  • Modern way to access request data and send JSON response in App Router
export async function POST(req) {
  const body = await req.json();
  return NextResponse.json({ message: 'Posted', data: body });
}

๐Ÿ› ๏ธ Handling DB Calls (Example)

import connectDB from '@/lib/db';
import User from '@/models/user';

export async function GET() {
  await connectDB();
  const users = await User.find();
  return NextResponse.json(users);
}
  • Must await connectDB() before running queries
  • Data fetched and returned in SSR-friendly format

โšก SSR (Server-Side Rendering)

  • HTML is rendered on server per request
  • Improves SEO, performance, and first-page load time

โœ… Pages Router โ€“ getServerSideProps()

export async function getServerSideProps(context) {
  const res = await fetch('https://api.example.com/posts');
  const data = await res.json();
  return { props: { posts: data } };
}

โœ… App Router โ€“ Fetch directly inside component

export default async function BlogPage() {
  const res = await fetch('https://api.example.com/posts', { cache: 'no-store' });
  const data = await res.json();

  return (
    <div>
      {data.map((post) => <h2 key={post.id}>{post.title}</h2>)}
    </div>
  );
}

๐Ÿ” SEO (Search Engine Optimization)

โœ… Static Metadata

export const metadata = {
  title: "DevFlow โ€“ Ask and Answer Questions",
  description: "A developer Q&A platform built with Next.js",
};

โœ… Dynamic Metadata

export async function generateMetadata({ params }) {
  const post = await fetchPostBySlug(params.slug);
  return {
    title: post.title,
    description: post.excerpt,
  };
}
  • Metadata is injected into <head>, improves Google ranking
  • generateMetadata() enables dynamic SEO per page (slug-based)

โŒ Blockers

  • Initially confused between client-side and server-side behavior, especially how rendering and data access differ
  • Didn't understand why on the server you can directly call the database and return HTML to the browser โ€” now clear that SSR prepares the full HTML before sending it *Took time to realize why enterprise apps often use Next.js or plain HTML/CSS/JS for landing pages โ€” it's mainly for performance, SEO, and faster Time To First Byte (TTFB)
  • Was overusing useState/useEffect to manage state, but learned that in SSR or server components, minimal state management is needed
  • Forgot to await req.json() in POST handler โ€” caused req.body to be undefined
  • Missed { cache: 'no-store' } in App Router SSR fetch โ€” led to stale data issues

๐Ÿง  Reflection

Today I finally connected all the pieces of full-stack Next.js โ€“ RESTful API building, request handling, SSR optimization, and SEO best practices. I now fully understand when to use useEffect vs SSR, how to manage state during fetch, and how to serve optimized pages for both users and crawlers. This makes my future apps more performant, scalable, and searchable.