A Deep Dive into Next.js 14 App Router
The release of Next.js 14 brings exciting updates, especially with the introduction of the new App Router. This dynamic, component-based routing system takes routing in Next.js to the next level, enabling developers to build scalable and modular applications with ease. Let’s walk through the key features of this new router and how it enhances app development.
1. Nested Routes and Layouts
In traditional routing systems, managing layouts for different sections of an app can get messy. Next.js 14 simplifies this by introducing nested layouts, where different parts of the application can share a global layout and still have their own specific layouts for different routes.
Example: Nested Layouts
// app/layout.js (Global Layout)
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<Navbar />
<main>{children}</main>
<Footer />
</body>
</html>
);
}
// app/profile/layout.js (Profile Layout)
export default function ProfileLayout({ children }) {
return (
<div className="profile-layout">
<Sidebar />
<div className="content">{children}</div>
</div>
);
}
// app/profile/page.js (Profile Page)
export default function ProfilePage() {
return <ProfileDetails />;
}
In this example:
- The global layout (navbar and footer) wraps all pages.
- The profile layout (sidebar and content area) adds an extra layer for routes like
/profile
.
This approach avoids code duplication, making it easier to manage the overall structure of your application.
2. Loading States with Suspense
Next.js 14 integrates better support for React’s Suspense component, enabling finer control over loading states. This means you can show specific loading indicators for parts of your app while data is being fetched asynchronously.
Example: Using Suspense for Loading States
// app/profile/page.js (Profile Page)
import { Suspense } from 'react';
import ProfileDetails from './ProfileDetails';
import LoadingSpinner from './LoadingSpinner';
export default function ProfilePage() {
return (
<Suspense fallback={<LoadingSpinner />}>
<ProfileDetails />
</Suspense>
);
}
// app/profile/ProfileDetails.js (Profile Details Component)
import { getCurrentUserProfileData } from './getCurrentUserProfileData';
export default async function ProfileDetails() {
const profileData = await getCurrentUserProfileData();
if (!profileData) return null;
return (
<div>
{/* ... Others code*/}
</div>
);
}
With Suspense, users can experience a smooth transitions, such as viewing a loading spinner while the profile details load in the background. This creates a polished, user-friendly experience, eliminating awkward empty screens during data fetching.
3. Dynamic Routing with Segments
Dynamic routing is now more intuitive in Next.js 14 with the concept of segments. Segments allow you to create flexible routes based on dynamic values in the URL, which is perfect for building pages that depend on user input or other variables.
Example: Dynamic Route for Channels
// app/channel/[channelId]/page.js
import { use } from 'react';
import Messages from './Messages';
async function fetchChannelData(channelId) {
const response = await fetch(`https://api.example.com/channel/${channelId}`);
const data = await response.json();
return data;
}
export default function ChannelPage({ params }) {
const channel = use(fetchChannelData(params.channelId));
return (
<div>
<h1>{channel.title}</h1>
<Messages messages={channel.messages} />
</div>
);
}
In this setup:
[channelId]
is a dynamic segment in the URL.- The
use
function fetches data asynchronously based on thechannelId
.
When a user navigates to /channel/123
, Next.js automatically fetches the data for channel 123 and renders the page dynamically.
4. Parallel Routes
Parallel routes are a powerful feature in Next.js that allows you to display multiple sections or pages on the same screen simultaneously, all within a shared layout. Think of it as a way to render multiple “views” on the same page without switching between them.
Example Scenario:
Imagine you’re building a dashboard where users can view different sections like Analytics, Revenue, and Notifications simultaneously. Normally, these might be separate pages, but with parallel routes, all of them can be shown together in a modular way.
How Parallel Routes Work in Next.js
Parallel routes are defined using something called slots. A slot is like a placeholder for a particular section of your layout. Each slot corresponds to a specific part of the UI, and Next.js makes it easy to define these using a special folder structure.
For example, in your dashboard:
- @analytics for the Analytics section.
- @revenue for Revenue.
- @notifications for Notifications.
Each of these sections will have its own content and will be displayed together in one layout. Here’s how you can set this up.
Folder Structure Example:
app/
layout.js # Main layout file
@analytics/ # Analytics slot
page.js
@revenue/ # Revenue slot
page.js
@notifications/ # Notifications slot
page.js
page.js # Main page
Example: layout.js
File
In the layout.js
file, you define how the slots will be displayed within the layout. Here’s a simple example:
// app/layout.js
export default function RootLayout({
children,
analytics,
revenue,
notifications,
}) {
return (
<div>
<div>{children}</div> {/* Main content */}
<div>{analytics}</div> {/* Analytics section */}
<div>{revenue}</div> {/* Revenue section */}
<div>{notifications}</div> {/* Notifications section */}
</div>
);
}
Example: Slot Components
Now, let’s define each of these slots. Each slot is a standalone component, so you can easily work on them separately:
// app/@analytics/page.js
export default function Analytics() {
return <div>Analytics</div>;
}
// app/@revenue/page.js
export default function Revenue() {
return <div>Revenue</div>;
}
// app/@notifications/page.js
export default function Notifications() {
return <div>Notifications</div>;
}
How It All Comes Together:
Each slot (like @analytics
, @revenue
, and @notifications
) gets automatically passed into the layout.js
file as a prop. This allows you to structure your dashboard in a way that shows all sections at once. In this case, the Analytics, Revenue, and Notifications components are displayed in their respective areas on the page.
Benefits of Parallel Routes
- Code Modularity: Each section (or slot) is managed separately, making your code easier to maintain and organize.
- Team Collaboration: Different teams can work on different slots independently without interfering with one another.
- Sub-navigation: Each slot can have its own sub-navigation and independent routing logic. This means users can navigate through one section (e.g., Analytics) without affecting the other sections (e.g., Revenue).
In summary, parallel routes offer an advanced way to manage complex layouts by splitting a single layout into multiple, independently managed sections, providing a more flexible and efficient user experience
5. Intercepting Routes
Intercepting routes in Next.js allows you to change how navigation works without fully navigating away from the current page. You can display an alternative view (like a modal) while keeping the current page context, and the URL still updates so it’s shareable. On page reload, the correct content loads based on the URL.
Example: In a photo feed app, clicking a photo typically navigates to a new page. With intercepting routes, clicking a photo opens a modal, displaying the photo without leaving the feed. The URL changes to reflect the selected photo, so if someone accesses the URL directly or reloads the page, the full-page view of the photo loads.
How to Implement
In Next.js, you can intercept routes using a folder naming convention (.)
:
- Inside
app
folder, create a new folder named(.)folder1
. This will intercept the route fromapp
to/folder1
. - In
(.)folder1
, create apage.tsx
file:
export default function InterceptedF1() {
return <h1>(.) Intercepted F1 page</h1>;
}
Now, when navigating to /folder1
, the intercepted content will display. On page reload, the original folder1
content will load.
Advanced Patterns
You can intercept routes at different levels with patterns like:
(..)
for one level up.(...)
for intercepting from the root.
This lets you flexibly manage how routes behave in your app.
Conclusion
Next.js 14’s App Router offers powerful new tools for building dynamic, scalable applications. Features like nested layouts, Suspense, dynamic routing with segments, parallel routes, and intercepting routes make it easier than ever to manage complex applications while improving user experience. Whether you’re building a small app or a large-scale platform, these features give you the flexibility to create modular and efficient web apps.
With these new tools at your disposal, it’s time to dive into Next.js 14 and take your app development to the next level!
For learning more you can visit