
Getting Started with Next.js 14 App Router

Getting Started with Next.js 14 App Router
So Next.js 14 has landed and is packed with a load of amazing new features, with the App Router taking a lot of the spotlight. So, what is App Router? Well, App Router is one of the two ways of building applications in Next.js. I actually just released a post called Next.js 14: Getting Started with App Router in Next.js 14 which delves into a lot of the changes and things to be aware of when building full web applications with the App Router in Next.js 14.
What is the App Router?
Last November, we announced a new App Router for Next.js based on file routing and React Server Components. We are shifting the Pages Router in Next.js to a deprecated state and plan to eventually remove it in favor of the new App Router, which provides a better foundation for Server-Side Rendering, Static Generation and Incremental Static Regeneration.
Key features of the App Router include:
- File-based routing in the
appdirectory - Server Components by default for better performance
- Nested layouts for shared UI across routes
- Streaming and Suspense support for progressive rendering
- Data fetching improvements with
fetchintegration - Dynamic segments for flexible routing patterns
Setting Up Your First Next.js 14 Project
Apparently Next.js 14 has landed Next.js is a brilliant framework and creating a new project is literally easy. The official Next.js website and docs recommend using Create Next App which is a CLI (Command Line Interface) tool. So we shall follow the recommendation of the author and create a new project. Let’s do it.
bash
npx create-next-app@latest my-nextjs-app
cd my-nextjs-app
npm run dev
The CLI will prompt you with several configuration options:
- TypeScript support
- ESLint configuration
- Tailwind CSS
src/directory structure- App Router (enabled by default)
- Turbopack (Next.js's Rust-based bundler)
After installation, your project structure will look like this:
my-nextjs-app/
├── app/
│ ├── layout.tsx
│ ├── page.tsx
│ └── globals.css
├── public/
├── package.json
└── tsconfig.json
Understanding the App Directory Structure
The app directory is the core of the App Router. Anything you put inside the app directory will become a route. Here’s how routes work:
Basic Routing
File structure directly maps to URL paths:
app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── blog/
│ └── page.tsx → /blog
└── contact/
└── page.tsx → /contact
Each page.tsx file represents the content for that route:
typescript
// app/page.tsx
export default function Home() {
return (
Welcome to Next.js 14
Build modern web applications with the App Router
Dynamic Routes
Use square brackets to create dynamic route segments:
typescript
// app/blog/[slug]/page.tsx
interface Props {
params: {
slug: string
}
}
export default function BlogPost({ params }: Props) {
return (
Blog Post: {params.slug}
This creates routes like /blog/first-post, /blog/second-post, etc.
Catch-all Routes
Use spread syntax to match multiple segments:
typescript
// app/docs/[...slug]/page.tsx
interface Props {
params: {
slug: string[]
}
}
export default function DocsPage({ params }: Props) {
return
}
Layouts and Nested Routes
A layout defines shared UI elements that will be shown on screen for multiple pages of your application. Most common are navigation bars, sidebars or footers.
typescript
// app/layout.tsx
import './globals.css'
export const metadata = {
title: 'My App',
description: 'Built with Next.js 14',
}
export default function RootLayout({
children,
}: {
children: React. ReactNode
}) {
return (
Create nested layouts for specific route groups:
typescript
// app/blog/layout.tsx
export default function BlogLayout({
children,
}: {
children: React. ReactNode
}) {
return (
Server Components vs Client Components
I had a great realisation last night. I’ve been thinking a bit more about the default behaviour of Server Components in Next.js 14, namely that they only run on the server, and not on the client. Well, Next.js 14 RC is out now, so it’s time to dive in and explore this behaviour and more. Optimisation So why do Server Components run only on the server in Next.js 14? Well, that’s an optimisation. With this optimisation, Next.js 14 brings a multitude of advantages.
Server Components (Default)
typescript
// app/products/page.tsx
import { Database } from '@/lib/database'
export default async function ProductsPage() {
// This runs only on the server
const products = await Database.getProducts()
return (
Client Components
Use the 'use client' directive when you need interactivity:
typescript
// app/components/Counter.tsx
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
)
}
Data Fetching in Next.js 14
Next.js 14 is out. One of the key improvements to Next.js 14 is API route data is now available in pages. Yes, you read that right - you can now use the Fetch API in Next.js pages, and API route data is now available to use in pages. Also: result caching and cache revalidation is now proactive.
typescript
// app/posts/page.tsx
async function getPosts() {
const res = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 } // Revalidate every 60 seconds
})
if (! res.ok) {
throw new Error('Failed to fetch posts')
}
return res.json()
}
export default async function PostsPage() {
const posts = await getPosts()
return (
{post.title}
{post.content}
Metadata Management
Next.js 14 provides a powerful metadata API for SEO:
typescript
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next'
interface Props {
params: { slug: string }
}
export async function generateMetadata({ params }: Props): Promise
const post = await getPost(params.slug)
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
type: 'article',
},
}
}
export default function BlogPost({ params }: Props) {
return
}
Best Practices
When working with Next.js 14's App Router, follow these best practices:
- Set default to Server Components on Frontend as they are faster and more secure.
- Keep Client Components small You should only mark components with ’use client’ when they need to.
- ** Leverage layouts** - Use nested layouts to avoid code duplication
- ** Implement error boundaries** - Create
error.tsxfiles for error handling - ** Optimize images** - Use the Next.js
Imagecomponent - ** Generate static exports** - Use
generateStaticParamsfor dynamic routes - ** Monitor performance** - Use Web Vitals and performance monitoring tools
- ** Update dependencies regularly** - Keep Next.js and dependencies current
Common Patterns
Loading States with Suspense
typescript
// app/dashboard/page.tsx
import { Suspense } from 'react'
import { DataComponent } from '@/components/DataComponent'
import { LoadingSpinner } from '@/components/LoadingSpinner'
export default function DashboardPage() {
return (
<Suspense fallback={
)
}
Error Handling
typescript
// app/error.tsx
'use client'
interface Props {
error: Error & { digest?: string }
reset: () => void
}
export default function Error({ error, reset }: Props) {
return (
Something went wrong!
Deployment
Next.js 14 on Vercel Next.js 14 is here and you can now use the power of Next.js to build incredibly fast and scalable web applications. Faster, Easier Scalable Web Applications at any scale, on any Node.js host – including Vercel.
bash
Build for production
npm run build
Start production server
npm run start
Conclusion
Next.js 14 has been released Today Next.js 14 was released. The App Router is a game changing new feature for Next.js. Next.js 14 comes with all new Server Components, improved data fetching, and file-based routing. Learn more about Next.js 14 and start building your next app.
You made it this far in the Doks docs? Congratulations! You must be due for an App Router upgrade. We know, we know, it’s scary. But fear not: the time you’ll spend learning the ropes will be far outweighed by the benefits you’ll gain with a faster site, easier development and management, and a whole lot of awesomeness. You’ve got this.
Lena Schmidt
Writer at DevPulse covering Web Development.


