SuperJupiter
Back to Articles
Cheatsheet

Next.js App Router Cheatsheet: Essential Patterns and Best Practices

March 21, 20258 min read

The Next.js App Router represents a significant evolution in React-based web development, introducing powerful features like React Server Components, nested layouts, and simplified data fetching. This cheatsheet provides a quick reference to help you navigate the App Router with confidence.

File Conventions

The App Router uses a file-system based router where folders define routes and special files handle UI.

app/
├── layout.tsx      # Root layout (required)
├── page.tsx        # Home page
├── about/
│   └── page.tsx    # /about route
├── blog/
│   ├── layout.tsx  # Layout for blog section
│   ├── page.tsx    # /blog index route
│   └── [slug]/     # Dynamic route segment
│       └── page.tsx # /blog/:slug route

Special files in the App Router:

  • page.tsx - Publicly accessible route
  • layout.tsx - Shared UI for a segment and its children
  • loading.tsx - Loading UI for a segment
  • error.tsx - Error UI for a segment
  • not-found.tsx - Not found UI
  • route.ts - API endpoint

Routing Patterns

Dynamic Routes

// Single dynamic segment
app/blog/[slug]/page.tsx      // Matches /blog/:slug

// Multiple dynamic segments
app/shop/[category]/[item]/page.tsx  // Matches /shop/:category/:item

// Catch-all segments
app/docs/[...slug]/page.tsx   // Matches /docs/:slug* (one or more)

// Optional catch-all segments
app/docs/[[...slug]]/page.tsx // Matches /docs and /docs/:slug*

Accessing Route Parameters

// app/blog/[slug]/page.tsx
export default function BlogPost({ params }: { params: { slug: string } }) {
  return <div>Post: {params.slug}</div>
}

// app/shop/[category]/[item]/page.tsx
export default function Product({ 
  params 
}: { 
  params: { category: string; item: string } 
}) {
  return (
    <div>
      Category: {params.category}
      Item: {params.item}
    </div>
  )
}

Data Fetching

Next.js App Router provides several ways to fetch data in your application:

Server Components (Recommended)

// app/users/page.tsx
async function getUsers() {
  const res = await fetch('https://api.example.com/users')
  if (!res.ok) throw new Error('Failed to fetch users')
  return res.json()
}

export default async function UsersPage() {
  const users = await getUsers()
  
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  )
}

Data Fetching with Revalidation

// Revalidate at most every 60 seconds
fetch('https://api.example.com/data', { next: { revalidate: 60 } })

// Force cache
fetch('https://api.example.com/data', { cache: 'force-cache' })

// Skip cache (equivalent to cache: 'no-store')
fetch('https://api.example.com/data', { cache: 'no-store' })

// Revalidate on-demand
// In a Server Action or Route Handler:
import { revalidatePath, revalidateTag } from 'next/cache'

// Revalidate a specific path
revalidatePath('/blog')

// Revalidate a specific cache tag
revalidateTag('blog-posts')

Server Components

By default, all components in the App Router are React Server Components. This allows you to:

  • Fetch data directly in your components
  • Access backend resources directly
  • Keep sensitive information on the server
  • Reduce client-side JavaScript

Client Components

When you need interactivity or browser APIs, use Client Components:

'use client'

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

Metadata API

Next.js provides a Metadata API for managing your application's metadata:

// Static metadata
// app/page.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Home',
  description: 'Welcome to our website',
}

export default function Page() {
  return <div>...</div>
}

// Dynamic metadata
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next'

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug);

  return (
    <>
      <Metadata>
        title: post.title,
        description: post.excerpt,
      </Metadata>
      <div>...</div>
    </>
  );
}

Conclusion

This cheatsheet covers the essential patterns and best practices for working with the Next.js App Router. As you build more complex applications, you'll discover additional features and optimisations that the App Router provides.

For more detailed information, refer to the official Next.js documentation.

Need Help With Your Next.js Project?

At SuperJupiter, we specialise in building high-performance Next.js applications. Whether you're starting a new project or optimising an existing one, our team can help.

Contact us for a consultation