Summary
Migrating from Next.js Pages router
to Next.js App router
provides several benefits and introduces new concepts for organizing your Next.js project. In this guide, we will walk you through the process of migrating to the App router
, explaining important concepts and highlighting key steps along the way. We will also explore the integration of Tailwind CSS
into the project.
Introduction
Next.js
is a popular React framework for building server-side rendered and static websites. With the introduction of the App router
, Next.js offers a more structured approach to organizing your application's routes and components. This migration guide will help you understand the steps involved in adopting the Next.js App router
and using it alongside Tailwind CSS
.
Prerequisites
Before we begin, make sure you have the following requirements in place:
- Node.js 16.8+ installed on your system.
- A basic understanding of Next.js and Tailwind CSS.
Step 1: Installing Required Packages
To get started, navigate to your Next.js project directory
and install the latest required packages for Next.js and Tailwind CSS. Open your terminal and run the following command:
npm install next@latest react@latest react-dom@latest tailwindcss@latest
This command will update your project with the latest versions of Next.js, React, React DOM, and Tailwind CSS.
Step 2: Updating the Next.js and Tailwind Configuration
Next, we need to update the Next.js configuration to enable the App directory and configure Tailwind CSS accordingly. Locate the next.config.js
file in your project and add the following lines:
module.exports = {
experimental: {
appDir: true,
},
// Other configuration options...
};
Enabling the appDir
option allows Next.js to recognize the App directory as the main directory for your application's routes.
Now, open the tailwind.config.js
file and update the content
property as follows:
module.exports = {
// Other configuration options...
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./app/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
};
This change ensures that Tailwind CSS scans the App directory for CSS utility classes.
Step 3: Creating First App Page Component and Root Layout
To take full advantage of the App router, we need to reorganize our directory structure and create the initial App page component and root layout.
Create a new directory called
app
in your project's root directory. This directory will hold your App-specific components and files.To avoid conflicts with new App router files, rename the existing
pages
directory toold-pages
or choose a different name that is distinct from the defaultpages
directory.Edit the
page.tsx
file inside theapp
directory with a simple React component representing your homepage:
import React from 'react';
export default function HomePage() {
return <div>This is my new App Route Home Page</div>;
}
- Start your Next.js development server using the
npm run dev
command. This will generate the
layout.tsx
file automatically for you.
$ npm run dev
...
wait - compiling /page (client and server) ...
Your page app/page.tsx did not have a root layout. We created app/layout.tsx for you.
After the server starts, your project structure should look like this:
- app
- index.tsx
- layout.tsx
- Since we now have a root layout file, we can add our Tailwind CSS styles to it. Open the
layout.tsx
file and import theglobals.css
file:
import '../styles/globals.css';
Step 4: Naming Convention
The App router follows a naming convention for its files. The files should be named page.tsx
, layout.tsx
, loading.tsx
, etc., depending on their purpose. This convention helps Next.js identify and associate the components correctly with their routes.
Step 5: Understanding Layouts
The layout.tsx
file in the App directory serves as a global layout for all child views. This means that any components placed in the layout file will be shared across multiple pages unless you create a new layout specifically for a particular page or group of pages. The layout file is an excellent place to define global settings, such as importing global libraries or configuring services like AWS Amplify.
For example, you can configure AWS Amplify in the layout.tsx
file as follows:
import awsconfig from '../src/aws-exports';
import { Amplify, AuthModeStrategyType } from 'aws-amplify';
Amplify.configure({
...awsconfig,
ssr: true,
DataStore: {
authModeStrategyType: AuthModeStrategyType.MULTI_AUTH,
},
});
interface RootLayoutProps {
children: React.ReactNode;
}
export default async function RootLayout({ children }: RootLayoutProps) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}
The layout component is responsible for rendering the shared structure, such as the HTML and body tags, while the children
prop represents the content specific to each page.
Step 6: Using the "use client" Directive
By default, all code within the App router runs on the server. To execute code on the client-side, such as React hooks, you need to use the "use client"
directive at the beginning of your document.
For example, in app/page.tsx
, you can use the "use client"
directive and implement a simple counter:
"use client"
import { useState } from "react";
export default async function Page() {
const [counter, setCounter] = useState(0);
return (
<div>
<p>Counter: {counter}</p>
<button onClick={() => setCounter(prev => prev + 1)}>+1</button>
</div>
);
}
The "use client"
directive indicates that this code should run on the client-side, allowing the use of client-specific features like React hooks.
Step 7: Sending Components to the Client
The App router provides a convenient way to send only the necessary components to the client. This approach improves performance by reducing the amount of code sent to the browser.
For example, you can fetch data on the server and render a specific component on the client:
// All this code will be executed on the server
import { withSSRContext } from 'aws-amplify';
import { serialize } from 'next-mdx-remote/serialize';
import { Posts } from '../../../src/models';
import Post from '../../../components/Post';
async function fetchPost(slug) {
const { DataStore } = withSSRContext();
const post = await DataStore.query(Posts, slug);
const mdxSource = await serialize(post.content);
return {
date: post.createdAt,
title: post.title,
content: mdxSource,
slug,
};
}
export default async function SlugPage({ params }) {
const { slug } = params;
const post = await fetchPost(slug);
// The <Post/> component will be rendered on the client-side, as we use "use client" within it.
return <Post {...post} />;
}
Another good example, it is our Root Layout Component
.
The Root Layout is a server component that calls the NavBar and AuthBtn components.
AuthBtn Component use the useAuthenticator
hook which can only work on client components.
We call the AuthBtn component
from our NavBar component
. Both are client components.
AuthBtn component:
"use client";
import Link from "next/link";
import { useAuthenticator } from "@aws-amplify/ui-react";
import { Auth } from "aws-amplify";
export default function AuthBtn({ setter }) {
const { authStatus } = useAuthenticator((context) => [context.authStatus]);
return (
<>
{authStatus && authStatus !== "authenticated" ? (
<SignInButton setter={setter} />
) : (
<SignOutButton setter={setter} />
)}
</>
);
}
This approach ensures that only the necessary components are sent to the client, reducing the initial load time and improving the overall performance of your application.
For more details information about client components go to https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive.
Step 8: Leveraging SEO Metadata
The App router provides a convenient way to handle metadata, such as page titles, descriptions, and keywords. You can export metadata from your views and layouts to ensure proper SEO optimization.
In your view components, export the metadata as follows:
export const metadata = {
title: 'App Route',
description: 'First metadata in app route',
keywords: ['react', 'nextjs'],
};
You can also define general metadata in your layout component. Next.js is intelligent enough to prioritize view-specific metadata over layout metadata.
export const metadata = {
title: 'App Route',
description: 'First metadata in app route',
keywords: ['react', 'nextjs'],
};
export default function Layout({ children }) {
return (
<main>
{children}
</main>
);
}
By leveraging metadata, you can improve the search engine visibility and discoverability of your application's pages.
Our Website running NextJS App Router
See our current Website laveraging App Router in our github repo: https://github.com/albac/albac.dev
Look at our current structure to see how we organize your pages and components:
app/api/davinci:
route.ts
app/api/turbo:
route.ts
app/blog-edit:
[id]/
app/blog-edit/[id]:
page.tsx
app/chatgpt:
[model]/
app/chatgpt/[model]:
page.tsx* layout.tsx
app/legal:
privacy-policy/ terms-conditions/
app/legal/privacy-policy:
page.tsx
app/legal/terms-conditions:
page.tsx
app/projects:
loading.tsx page.tsx
app/signin:
page.tsx
app/storagemanager:
page.tsx*
app/profile:
loading.tsx image-profile.tsx page.tsx
Conclusion
Migrating to the Next.js App router introduces a more structured approach to organizing your application's routes and components, making it easier to build and maintain complex applications. In this guide, we specifically looked at how you can migrate a blog application to the App router.
By migrating your blog application to the Next.js App router, you gain a more structured and organized approach to building your blog. The separation of concerns, client-side rendering capabilities, and SEO optimization features provided by the App router enhance the overall user experience and make your blog more efficient and discoverable.
We hope this guide has been helpful in understanding and implementing the Next.js App router in your blog application. For more detailed information and examples, refer to the official Next.js documentation on https://nextjs.org/docs/app.
References
- Next.js Documentation App: https://nextjs.org/docs/app
- Next.js Official Migration Documentation: https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration
- Amplify Documentation: Use Amplify with Next.js App Router (App Directory): https://docs.amplify.aws/lib/ssr/q/platform/js/#use-amplify-with-nextjs-app-router-app-directory
Top comments (1)
awesome article. thanks for sharing. would love to get your opinion on what we do (
marketplace.visualstudio.com/items...
docs.intuita.io/docs/vs-code-exten...
notion.so/intuita/Nextjs-Pages-to-... ).
lemme know if you want me to show you a demo. linkedin.com/in/alexbit/