The two and a half + one flavors of next.js's pre-rendering
Tags: nextjs, webdev, node
Published: 2021-08-08 17:31:48

Confused by the title? Don't be, we will take a look at the different pre-rendering options provided by `next.js`.

According to the documentation, `next.js` has **two** flavors of pre-rendering Static Generation (SSG) and Server-side Rendering (SSR):

> Two forms of Pre-rendering
> `next.js` has two forms of pre-rendering: Static Generation and Server-side Rendering. The difference is in when it generates the HTML for a page.
> [https://nextjs.org/docs/basic-features/pages#two-forms-of-pre-rendering](https://nextjs.org/docs/basic-features/pages#two-forms-of-pre-rendering)

What are the other **one and a half** options? Let's take a deep breath and go for a deep dive!


## 1st flavor: [Static Generation (SSG)](https://nextjs.org/docs/basic-features/pages#two-forms-of-pre-rendering)

The HTML is generated at build time and will be reused on each request. It's the recommended one, because SSG pre-rendered pages are easy to cache and fast to deliver. Usually they have a lower `time for first paint` and less `blocking time`.
In case you need dynamic data you can combine it with Client-side Rendering.

To prepare a page for Static Generation (SSG) use `getStaticProps` and it is run on build time.

### Minimal example
```
import Page from '../Page';
export default Page;

export async function getStaticProps() {
    return { props };
}
```

## 2nd flavor: [Server-side Rendering (SSR)](https://nextjs.org/docs/basic-features/pages#two-forms-of-pre-rendering)

The HTML is generated on each request. You can easily add dynamic data or consume external API's and render their data to the HTML file before serving it to the client.

To prepare a page for Server-side Rendering (SSR) use `getServerSideProps` and is run on every request instead of on build time.

Of course you can create a "hybrid" `next.js` app by using Static Generation and Server-side Rendering depending on the page.

### Minimal example
```
import Page from '../Page';
export default Page;

export async function getServerSideProps() {
	const props = await getData();
    return { props };
}
```

## 2nd and a half flavor: [Incremental Static Regeneration (ISG)](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration)

The HTML is generated at build time and this cached version is shown initially.
Then, the current, updated version is generated, shown and replaces the cached version of the page and consequent visitors will receive the new version immediately.
It’s like a hybrid solution of SSG and SSR with a [stale-while-revalidate](https://datatracker.ietf.org/doc/html/rfc5861#section-3) caching strategy. Using ISR instead of SSR will massively increase your application’s performance and improve your Lighthouse score as well as your user's experience.

To prepare a page for Static Generation (SSG) use `getStaticProps` with the `revalidate` property.


### Minimal example
```
import Page from '../Page';

export default Page;

export async function getStaticProps() {
    return { props, revalidate: 30 };
}
```


## Plus one flavor: `$ next export`

All the above examples are build for production with `$ next build` and they are relying on the build-in `node.js` server.  Even with the static sites from SSG you need a host with `node.js` support (for example [https://www.vercel.com](vercel) or [https://www.netlify.com](netlify)).

If you're running `$ next export` instead, `next.js` will create a [truly static version](https://nextjs.org/docs/advanced-features/static-html-export) of your page which you can drop into any webserver and thus can be served from any host.

But be careful, of course this works only with SSG-ready pages and even then [some `next.js` features are not available](https://nextjs.org/docs/advanced-features/static-html-export):

- Incremental Static Generation (ISG) is not supported
- API Routes are not supported
- `getServerSideProps` are not supported
- `Internationalized Routing` is not supported
- The `next/image` component's default loader is not supported


## Summary:
`next.js`'s flavors or pre-rendering:
- [Static Generation (SSG)](https://nextjs.org/docs/basic-features/pages#two-forms-of-pre-rendering)
- [Server-side Rendering (SSR)](https://nextjs.org/docs/basic-features/pages#two-forms-of-pre-rendering)
- [Incremental Static Regeneration (ISG)](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration)
- [True static HTML with `$ next export`] (https://nextjs.org/docs/advanced-features/static-html-export)


---

Follow me on [Twitter: @martinkr](http://twitter.com/_martinkr) and consider to [buy me a coffee](https://www.buymeacoffee.com/martinkr)