NextJS is an amazing JavaScript framework that helps you build amazing and performant web applications. Recently, they released a new change, and for page components, now it uses the app folder which comes with many different options. In this article, we will cover what this new structure brings.
Client vs Server components
When using the app folder, NextJS treats all the components as server-side components. That means you can't use things like window and other browser-specific objects and functions. However, there is a way to make them run client-side, and that is done by adding a "use client" string at the top of your file.
"use client"
// .. rest of the code
Root specific files
global-error.js
You can place this component in the root of the app folder. And if any error occurs during the rendering that is not handled, the output of this component is rendered. All error components need to be client-side components. This component receives two parameters, an error containing details about specific errors, and a reset function that you could use to retry rendering.
"use client" // must be client-side
export default function Error({
error,
reset,
}) {
console.log(error, reset)
return (
<div>
<h2>Something went wrong!</h2>
</div>
);
}
not-found.js
This component is rendered when you try to access an undefined route. NextJS does have some default components, but you can use this component to override the default one.
export default function NotFound () {
return (
<div>Custom page not found</div>
)
}
Nested routes
page.js
Page component is, just like the name says, a component you use for your page. As mentioned before, by default they are all rendered server-side, and if you want to force client-side rendering, you need to place "use client" at the top. If you place this component in the root of the app folder, it will act as the root page.
// example
export default function HelloWorld() {
return (
<div>
Hello, World!
</div>
)
}
error.js
The error component works just like the global-error one. The difference is in that this component is route specific. If your route throws an error during the rendering, this component gets rendered instead.
layout.js
Layout components can be also placed in the root of the app folder or nested. Sometimes you want some styling, structure, or logic shared on some pages but not on all. And this is the place where you could place it. Layouts take one parameter, children, which is your page or some nested layout.
export default function ExampleLayout({children}) {
return (
<section>
{/* Include shared UI here e.g. a header or sidebar */}
{children}
</section>
);
}
template.js
Templates are very similar to the layouts, with some differences. The first one is that order-wise, templates are inside of the layout. Another important difference is that the template state is not persistent between routes that share that template. This is something that can be used for likes of enter and exit animations.
loading.js
If you want to have some nice loading displays, this is the component you could use and it is shown while the page is loading. If you have it at the same level as the layout, the content of the layout will automatically be wrapped into suspense, and use this component as the loading component.
Conclusion
NextJS released app directory only recently, and it is a big change. However, they seem to be sticking with it for the future, and it does bring some interesting options, and I hope this guide can help you transition to it easier. The code used in the examples above can be found in my GitHub repository.
For more, you can follow me on Twitter, LinkedIn, GitHub, or Instagram.