Day 02 Day 2

Day 2

Day 2

~1 hour Intermediate Hands-on Precision AI Academy

Today's Objective

A Next.js app with a working contact form that uses a Server Action to validate and save data — no API route needed, no useState, just a form that works.

A Next.js app with a working contact form that uses a Server Action to validate and save data — no API route needed, no useState, just a form that works.

API Routes with Route Handlers

API routes in the App Router are called Route Handlers. Create a route.ts file in any directory under app/ to define HTTP methods as exported functions.

src/app/api/posts/route.ts
TYPESCRIPT
import { NextResponse } from 'next/server'

const posts = [
  { id: 1, title: 'Hello World' },
  { id: 2, title: 'Next.js is Great' },
]

// GET /api/posts
export async function GET() {
  return NextResponse.json(posts)
}

// POST /api/posts
export async function POST(request: Request) {
  const body = await request.json()

  if (!body.title) {
    return NextResponse.json(
      { error: 'Title required' },
      { status: 400 }
    )
  }

  const newPost = { id: posts.length + 1, ...body }
  posts.push(newPost)
  return NextResponse.json(newPost, { status: 201 })
}

Server Actions — Forms Without APIs

Server Actions let you define server-side functions that forms call directly — no API route, no fetch() call, no useState. The form submits and the action runs on the server. Works even with JavaScript disabled.

src/app/contact/page.tsx
TYPESCRIPT
'use server'  // at the top of an actions file

import { revalidatePath } from 'next/cache'

async function submitContact(formData: FormData) {
  'use server'  // or inline like this

  const name = formData.get('name') as string
  const email = formData.get('email') as string
  const message = formData.get('message') as string

  // Validate
  if (!name || !email || !message) {
    throw new Error('All fields required')
  }

  // Save to DB, send email, etc.
  console.log({ name, email, message })

  // Revalidate the page cache
  revalidatePath('/contact')
}

export default function ContactPage() {
  return (
    <form action={submitContact}>
      <input name="name" required />
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button type="submit">Send</button>
    </form>
  )
}

Data Fetching Patterns

Next.js has three data fetching patterns. Understanding when to use each one is the key to building fast apps.

Data Fetching Patterns
Static (SSG)
Data fetched at build time. Ultra-fast. For content that rarely changes (blog, docs).
Server-side (SSR)
Data fetched on every request. Always fresh. For user-specific or real-time data.
Incremental (ISR)
Static, but revalidates after N seconds. Best of both worlds for most sites.
src/app/blog/page.tsx
TYPESCRIPT
// ISR: revalidate every 60 seconds
export const revalidate = 60

// Or disable caching entirely (SSR)
export const dynamic = 'force-dynamic'

// Or make fully static (SSG)
export const dynamic = 'force-static'

async function getBlogPosts() {
  const res = await fetch('/api/posts', {
    next: { revalidate: 60 }  // ISR on per-fetch level
  })
  return res.json()
}

Middleware and Protected Routes

Middleware runs before every request and can redirect, rewrite, or add headers. Use it to protect routes without loading the full page first.

src/middleware.ts
TYPESCRIPT
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const token = request.cookies.get('auth-token')

  // Protect /dashboard routes
  if (request.nextUrl.pathname.startsWith('/dashboard') && !token) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*']
}

Go Further on Your Own

Nice work. Keep going.

Day 3 is ready when you are.

Course Progress
40%

Want live instruction and hands-on projects? Join the AI bootcamp — 3 days, 5 cities.

What's Next

The foundations from today carry directly into Day 3. In the next session the focus shifts to Day 3 — building directly on everything covered here.

Supporting Videos & Reading

Go deeper with these external references.

Day 2 Checkpoint

Before moving on, verify you can answer these without looking:

Live Bootcamp

Learn this in person — 2 days, 5 cities

Thu–Fri sessions in Denver, Los Angeles, New York, Chicago, and Dallas. $1,490 per seat. June–October 2026.

Reserve Your Seat →
Continue To Day 3
Day 3