Next.js is a popular Node.js framework that allows for easy server-side rendering of React applications and provides a range of other powerful features. In this tutorial, we will explore some of the main features of Next.js and guide you through the process of getting started with it.
Introduction
Working on a modern JavaScript application powered by React is exciting, but it comes with some challenges. One of these challenges is the initial load time of the application. Since the content is rendered on the client-side, it takes longer for the page to become visible to the user. Additionally, if your website is publicly available, you may face content SEO issues since search engines prefer to receive content rather than figuring it out from JavaScript.
The solution to these problems is server-side rendering, also known as static pre-rendering. Next.js simplifies the process of server rendering by providing a zero-configuration, single-command toolchain for React apps. It offers a common structure that allows you to build a frontend React application while transparently handling server-side rendering for you.
Main Features
Here are some of the key features of Next.js:
- Hot Code Reloading: Next.js automatically reloads the page when it detects any changes saved to disk.
- Automatic Routing: Next.js maps any URL to the filesystem, making it easy to organize pages in the
pages
folder without any additional configuration. - Single File Components: Next.js integrates with styled-jsx, making it simple to add component-scoped styles.
- Server Rendering: Next.js allows you to render React components on the server side before sending the HTML to the client.
- Ecosystem Compatibility: Next.js seamlessly integrates with the JavaScript, Node, and React ecosystem.
- Automatic Code Splitting: Next.js renders each page with only the necessary JavaScript and libraries, optimizing performance.
- Prefetching: The
Link
component in Next.js supports aprefetch
prop, which automatically prefetches page resources in the background, including code that is missing due to code splitting. - Dynamic Components: Next.js enables dynamic import of JavaScript modules and React Components.
- Static Exports: Next.js allows you to export a fully static site using the
next export
command.
Installation
Next.js supports all major platforms including Linux, macOS, and Windows. To start a Next.js project, you can use npm to install the required dependencies:
npm install next react react-dom
Getting Started
Create a package.json
file with the following content:
{
"scripts": {
"dev": "next"
}
}
Running the npm run dev
command will start a Next.js server on localhost:3000
. Initially, you will see a friendly 404 page with a clean design.
Next.js handles other error types such as 500 errors as well.
Create a Page
Inside the pages
folder, create an index.js
file with a simple React functional component:
export default () => (
<div>
<p>Hello World!</p>
</div>
);
When you visit localhost:3000
, this component will be rendered.
The page structure in Next.js is based on the filesystem structure. Pages are placed inside the pages
folder, and the page URL is determined by the page file name. The filesystem serves as the pages API.
Server-side Rendering
Open the page source (View -> Developer -> View Source) in Chrome, and you will see that the HTML generated by the component is sent directly in the page source. This indicates that the rendering is done on the server rather than the client-side.
Next.js aims to provide a developer experience for server-rendered pages similar to the ease of dropping PHP files and calling them in a basic PHP project. Although the internal implementation is different, Next.js makes it simple to create server-rendered pages.
Add a Second Page
Let’s create another page named contact.js
inside the pages
folder:
export default () => (
<div>
<p>
<a href='mailto:[[email protected]](/cdn-cgi/l/email-protection)'>Contact us!</a>
</p>
</div>
);
Visiting localhost:3000/contact
will render this page, which, like the first page, is also server-rendered.
Hot Reloading
Notice that you didn’t have to restart the npm
process to load the second page. Next.js handles hot reloading for you, automatically reloading the page when changes are detected.
Client Rendering
While server rendering is ideal for the initial page load, client-side rendering is essential for enhancing the user experience when navigating within the website. Next.js provides a Link
component that allows you to create links between pages.
Update the index.js
file with the following code:
import Link from 'next/link'
export default () => (
<div>
<p>Hello World!</p>
<Link href='/contact'>
<a>Contact me!</a>
</Link>
</div>
);
Now, when you click on the link, the Contact page loads immediately without requiring a page refresh. Next.js enables client-side navigation with full support for the History API, ensuring that the back button works correctly.
If you command-click the link, the same Contact page will open in a new tab, but this time it will be server-rendered.
Dynamic Pages
Next.js is well-suited for building dynamic pages, such as a blog. Let’s create a blog post listing and make it open individual posts with dynamic content.
Update the index.js
file with the following code:
import Link from 'next/link'
const Post = (props) => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<div>
<h2>My blog</h2>
<ul>
<li>
<Post title='Yet another post' />
<Post title='Second post' />
<Post title='Hello, world!' />
</li>
</ul>
</div>
)
This code creates a list of posts and sets the title query parameter based on the post title. Each post is rendered as a separate list item.
Create a new file named post.js
inside the pages
folder and add the following code:
export default (props) => <h1>{props.url.query.title}</h1>
Now, when you click on a post title, the individual post with its title will be rendered in an h1
tag.
Using clean URLs without query parameters is also possible in Next.js. The Link
component accepts an as
attribute, allowing you to pass a slug. Update the code accordingly:
import Link from 'next/link'
const Post = (props) => (
<li>
<Link as={`/${props.slug}`} href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<div>
<h2>My blog</h2>
<ul>
<li>
<Post slug='yet-another-post' title='Yet another post' />
<Post slug='second-post' title='Second post' />
<Post slug='hello-world' title='Hello, world!' />
</li>
</ul>
</div>
)
CSS-in-JS
Next.js offers built-in support for styled-jsx, which is a CSS-in-JS solution provided by the same development team. However, you can use any CSS-in-JS library you prefer, such as Tailwind CSS.
Here’s an example using styled-jsx:
export default () => (
<div>
<p>
<a href='mailto:[[email protected]](/cdn-cgi/l/email-protection)'>Contact us!</a>
</p>
<style jsx>{`
p {
font-family: 'Courier New';
}
a {
text-decoration: none;
color: black;
}
a:hover {
opacity: 0.8;
}
`}</style>
</div>
)
The styles defined using jsx
within the style
tag are scoped to the component. To edit global styles, add the global
attribute to the style
tag:
export default () => (
<div>
<p>
<a href='mailto:[[email protected]](/cdn-cgi/l/email-protection)'>Contact us!</a>
</p>
<style jsx global>{`
body {
font-family: 'Benton Sans', 'Helvetica Neue';
margin: 2em;
}
h2 {
font-style: italic;
color: #373fff;
}
`}</style>
</div>
)
Exporting a Static Site
Next.js makes it easy to export your application as a fully static site that can be deployed on various static site hosts such as Vercel, Netlify, Cloudflare Pages, or Firebase Hosting. You don’t need to set up a Node environment for static deployments.
Deploying to Vercel
If your site includes more than just static pages and utilizes API routes, Vercel is highly recommended for hosting. Vercel, the company behind Next.js, provides hosting specifically tailored for Next.js applications.
Vercel allows you to deploy API routes as serverless functions automatically, and provides granular control and logging. It is a great hosting platform for any website, but especially well-suited for Next.js applications.
Read More on Next.js
For more information on Next.js, be sure to check out the free Next.js Handbook.
Tags
next.js, react, server-side rendering, frontend development, javascript, web development