DEV Community

Alex Spinov
Alex Spinov

Posted on

Next.js 15 Has a Free API That Most Developers Don't Know About

Next.js 15 introduced significant changes to its API layer, including stable Server Actions, partial prerendering, and a revamped caching system. Here is what most developers miss.

Server Actions (Stable in v15)

// app/actions.ts
"use server";

export async function createPost(formData: FormData) {
  const title = formData.get("title") as string;
  const content = formData.get("content") as string;

  const post = await db.post.create({
    data: { title, content }
  });

  revalidatePath("/posts");
  return post;
}
Enter fullscreen mode Exit fullscreen mode

Route Handlers

// app/api/users/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const page = parseInt(searchParams.get("page") || "1");

  const users = await db.user.findMany({
    skip: (page - 1) * 20,
    take: 20
  });

  return NextResponse.json(users);
}

export async function POST(request: NextRequest) {
  const body = await request.json();
  const user = await db.user.create({ data: body });
  return NextResponse.json(user, { status: 201 });
}
Enter fullscreen mode Exit fullscreen mode

Partial Prerendering (PPR)

// app/page.tsx
import { Suspense } from "react";

export const experimental_ppr = true;

export default function Page() {
  return (
    <main>
      <StaticHeader />
      <Suspense fallback={<Loading />}>
        <DynamicContent />
      </Suspense>
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

New Caching Defaults

Next.js 15 changed caching to be opt-in:

// No longer cached by default
const data = await fetch("https://api.example.com/data");

// Explicitly cache
const cached = await fetch("https://api.example.com/data", {
  next: { revalidate: 3600 }
});
Enter fullscreen mode Exit fullscreen mode

Middleware

// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const token = request.cookies.get("token");
  if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/login", request.url));
  }
  return NextResponse.next();
}
Enter fullscreen mode Exit fullscreen mode

Key Changes in v15

  • Server Actions are now stable
  • Caching is opt-in, not opt-out
  • Partial Prerendering for mixed static/dynamic pages
  • React 19 support with new hooks
  • Turbopack stable for development

Need to scrape or monitor web data at scale? Check out my web scraping actors on Apify — ready-made tools that extract data from any website in minutes. Or email me at spinov001@gmail.com for custom solutions.

Top comments (0)