Next.js - App Router

lorenzojkrl

Lorenzo Zarantonello

Posted on July 30, 2024

Next.js - App Router

In previous posts, I tried Next.js using the Pages router. In this post and the following, I am exploring the new App router.

Creating The Application

To create a project with Next.js version 14, you simply need to start a command from the terminal by using

npx create-next-app@latest
Enter fullscreen mode Exit fullscreen mode

The "latest" option will download the latest version of the framework. All project dependencies will be installed, and then you will be asked to enter the project's name.

Installing Next.js 14

I kept the default selection, meaning that we will use

  • TypeScript
  • Tailwind CSS
  • ESLint
  • The app Router

Note that all project files will be available in the root folder because there won't be a src folder.

Once the installation is complete, navigate inside the project folder. In my case:

cd next14-app-router
Enter fullscreen mode Exit fullscreen mode

and start the server that will serve your Next.js app on http://localhost:3000/ with the command

npm run dev
Enter fullscreen mode Exit fullscreen mode

You can see this and other commands in the script object of the package.json file in the root folder of your application (in my case, inside the folder named next14-app-router).

package.json in Next.js

Also, the dependencies object shows I am using version 14.0.1 of next which allows us to install Next.js.

Next.js Demo App

Now that the project is running, it is worth it to get an idea of the files and folders that were created by default.

Application folders and files

Next.js default setup

From top to bottom, we have:

  • .next - Stores cache files to speed up the development and build process. It also contains server files to handle server-side-rendering (SSR), and other minified files to serve the app.
  • app - Contains components, logic, and routes of your application. We will mostly work inside the app folder.
  • public - Contains images you use in your app (e.g. static files)
  • .eslintrc.json - Configuration file for lining
  • .gitignore - Defines what should not be tracked by git
  • next-env.d.ts - TypeScript declaration to improve type-checking
  • next.config.js - Configuration file for Next.js
  • package.json & package-lock.json define your project dependencies
  • postcss.config.js, tailwind.config.ts, tsconfig.json - Configuration files, respectively for CSS, Tailwind, and TypeScript compiler
  • README.md - Can be used to explain your project or include relevant info

The app folder

Inside the app folder, you can see a favicon file that is used to add an icon to the tab of the browser in which the app is running.

global.css

A global.css file sets CSS rules that will be used throughout the Next.js project. You can add more CSS by using Tailwind where you need it or by using CSS Modules that will allow you to keep the CSS separate from the JavaScript/TypeScript code.

The global.css file is imported in layout. tsx which is also called the RootLayout component.

layout.tsx

In Next.js, a layout is a component that represents a part of the UI shared among multiple pages. A layout is a good place to manage some global state, global style, or place components that should be displayed on every page (or route) within your Next.js application—for instance a navigation menu.

In the following example, the text I'll be there for you will be there for you on every page of your app because it is part of the RootLayout component.

// layout.tsx

...
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <div>I'll be there for you</div>
        {children} // pages passed as children components
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

Layouts receive the individual pages as children components, through the "children" property. The children property is handled automatically when you navigate to a specific page, allowing the page to be injected directly into the layout.

By default, a layout is applied to all pages in the "pages" directory of your project.

Think of the Layout component as a wrapper for every other component in your Next.js app.

Layout visualization

For completeness, I should mention that layout.tsx in RootLayout does a few more things.

It imports the Inter next font and assigns it to the inter variable. Then it is passed as a class to the body element to be used as a default font in the app.
In so doing, Next.js simplifies the way you get and use Google fonts in the app. Find more about font optimization.

It imports Metadata so you can easily set the metadata of your app. If you change the title of the metadata object you will change the title of the tab in which your app is running.

// layout.tsx

...
export const metadata: Metadata = {
  title: "Next14 App Router",
  description: "Generated by create next app",
};
...
Enter fullscreen mode Exit fullscreen mode

You can see these changes in the developer console under the Elements tab inside the head tag. See the bottom of the following image.

Elements tab

page.tsx

The file page.tsx is a default page that contains the Home component.
By default, the initial app will pass the Home component as a child of RootLayout.

By changing Home to the following, you will have a new starting point for your app.

// page.tsx

export default function Home() {
  return <main>Hello Next.js</main>;
}
Enter fullscreen mode Exit fullscreen mode

If you see horizontal lines, just go to global.css and remove the style assigned to the body class so it looks like this:

// global.css

...
body {
  color: rgb(var(--foreground-rgb));
}Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed
Enter fullscreen mode Exit fullscreen mode

At this point, your app should show the sentences "I'll be there for you" coming from RootLayout and "Hello Next.js" from Home.

Warning

You might notice a warning in your console. If the warning is "Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed" or something similar, it means one or more extensions are adding some code to your app while it is executed on the browser.

It is good practice to disable extensions while developing but you can also set the suppressHydrationWarning attribute to true in the body tag in RootLayout.

<body className={inter.className} suppressHydrationWarning={true}>
Enter fullscreen mode Exit fullscreen mode

Read more on StackOverflow.

💖 💪 🙅 🚩
lorenzojkrl
Lorenzo Zarantonello

Posted on July 30, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related