With Next.js and Vercel, creating and deploying production-ready web apps has never been easier. It is optimized for running high-performance production workloads and provides a world-class developer experience straight out of the box. Continue reading to learn more about what makes Next.js so appealing to work with and how simple it is to publish your code to production.
Installation and Setup
Ensure that “npm” is installed on your computer:
node -v && npm -v
The corresponding version numbers should be printed to the console. If not, you can find installation instructions for your platform from the official Node.js site.
We can use the following command to scaffold out a new Next.js project if we have the node toolchain installed on our machines:
npx create-next-app my-amazing-app
Start the development server by going to the directory you just created:
cd my-amazing-app && npm run dev
By default, your app will be served at localhost:3000, and when you visit it with your browser, you’ll be greeted with the default welcome screen.
Static Data Fetching
The “getStaticProps” data-fetching hook allows you to provide dynamic data to your pages at build time. This is ideal for marketing pages when data isn’t updated frequently and speed is a top consideration. Replace the default contents of “pages/index.js” with the following code:
import Head from "next/head";
export default function Home({
title = "Hello World!",
metaContent = "Generic SEO pitch",
copy = "I'm having writer's block.",
}) {
return (
<>
<Head>
<title>{title}</title>
<meta content={metaContent} />
</Head>
<div>
<h1>{title}</h1>
<p>{copy}</p>
</div>
</>
);
}
export const getStaticProps = async () => {
// This is a full server-side Node environment,
// which means that you can make network requests,
// talk to databases, read from the file-system,
// and do whatever you want to fetch your data.
return {
props: {
title: "My Amazing Startup",
metaContent: "Amazing SEO poetry",
copy:
"I'm in the business of making people smile. That's all I'm here for.",
},
};
};
Everything is the same as it is in any other React project, with a few exceptions. First, you’ll see that we’re not explicitly importing React because Next.js includes it by default. Next, you can see that we’re able to set our page metadata from the “<Head />” component and don’t need to bring in another third-party library like react-helmet. Finally, we’ve included a “getStaticProps” function that returns a props object with the title, “metaContent”, and “copy” keys. As a result, we can de-structure those props from our top-level page component and read them in. For good measure, we’ve included default values in case the props aren’t supplied. These props are baked immediately into your pages with no runtime overhead when your Next.js project is constructed, resulting in enhanced performance and stability.
Incremental Static Regeneration
Next. The distinction between static and dynamic is blurred by JavaScript. Just because your data is statically fetched doesn’t imply you’ll be stuck with it until you re-deploy. Incremental Static Regeneration allows you to refresh existing pages as traffic comes in by re-rendering them in the background. Simply append the “revalidate” key to the object returned by the “getStaticProps” function, along with the number of seconds you want to wait before revalidating and recreating the page if data changes. You might not notice a change in our somewhat contrived local example, but it will come to life once you start accessing data from a database or CMS.
export const getStaticProps = async () => {
return {
props: {
title: "My Amazing Startup",
copy:
"I'm in the business of making people smile. That's all I'm here for.",
},
revalidate: 1, // number of seconds to wait before revalidating
};
};
Server Side Rendering
You may have very dynamic material that needs to update based on a variety of factors. Perhaps you’d like to look at the request headers of incoming traffic to see how you want to render your page. Next.js provides the “getServerSideProps” function for this purpose, which is similar to the “getStaticProps” function we’ve already seen.
Create a new file in your “pages” directory called “hello-user-agent.js” with the following contents:
import Head from "next/head";
export default function HelloUserAgent({ userAgent = "Nobody" }) {
return (
<>
<Head>
<title>Hello User Agent!</title>
</Head>
<p>
{" "}
Hi <em>{userAgent}</em> !{" "}
</p>
</>
);
}
export const getServerSideProps = async ({ req }) => {
return {
props: {
userAgent: req.headers["user-agent"],
},
};
};
This page has a structure identical to our “index.js” home page, but with one minor modification. We are exposing a function named “getServerSideProps” instead of a “getStaticProps” function below our page component. Notice how we’ve destructed a Node.js HTTP Incoming Message object and read values from it in the body of our function. This page is totally rendered in a server environment using a lightweight Serverless Function, which gives your page new props every time it’s requested. You’ll see your browser’s user agent string printed on the screen if you go to “localhost:3000/hello-user-agent”.
It’s worth noting that rendering a page in this manner has a tiny performance penalty. It can take a few moments (500-800 ms on average) for the function that renders your page to start up if it hasn’t been used in a few minutes. The cold start problem is what this is known as. This difficulty can be mitigated with a good caching approach.
API Routes
API Routes let you design HTTP request handlers with the same file-system routing structure as the frontend. When we used “create-next-app” to create our project, an API route was built for us at “pages/api/hello.js” with the following contents:
export default (req, res) => {
res.statusCode = 200
res.json({ name: 'John Doe' })
}
The function will produce a JSON response if you browse to localhost:3000/api/hello. API Routes are useful for connecting to a database rapidly and delivering results, as well as processing forms and sending emails.
Deploy to Vercel
Now that we’ve got a feel for how Next.js works, we need a way to get it up on the internet. Vercel is a deployment platform for frontend projects made by the same people that created Next.js, so its only natural that the deployment experience feels as simple as the development experience.
Create a new git repository and push it to a Git provider to get started. After you’ve created a URL for your repository, go to https://deploy.new/ to begin the import process. A new account will be created for you if you don’t already have one, and a deployment will be made to your account. It’s as simple as that! The Vercel Edge Network distributes your Next.js project all over the world. Every time you push changes or create a new branch, your URL will be updated and a new deployment will be created for you. The Vercel platform’s documentation might help you learn more about it.
Although the Git workflow is great for iterating on a production app, you may utilize the Vercel CLI to make a deployment by running the “vercel” command from your project root.
Final Thoughts
Next.js is a robust framework for projects of any size, although it hides a lot of the finer points and emphasizes minimalism. It has a hybrid rendering strategy that allows you to choose whether you want static markup with pre-populated props supplied at build time or server-rendered pages with dynamic data requirements for each request on a per-page basis. API routes make it easier to set up a backend without having to use Express or other API frameworks. We’ve gone through the most important aspects of Next.js, but we’ve only scratched the surface. To learn more, see the official documents and check out the interactive learning tutorial for creating your own blog from the ground up!
