Skip to content

[RFC] Rendering in Next.js (SSR, Pre-rendering, CSR, SPA) #7355

@timneutkens

Description

@timneutkens

Next.js currently has 2 modes of rendering:

  • Dynamic rendering means render on demand when a request comes in.
  • Pre-rendering means rendering to html at build time using next export

These modes work fine if your application only has pages of a certain type. For example zeit.co/docs is completely static. However more often than not your application is not binary, and requirements for static rendering change over time.

For example, zeit.co has a blog with static content, marketing pages, a dashboard and more. In the current model, zeit.co would be deployed with the serverless target and every page becomes a serverless function, including the blog and marketing pages that can actually be generated at build time.

Furthermore we've seen a common pattern where you'd want the dashboard to be an appshell type application that only shows the header and a loading spinner in the pre-rendered response, then after hydrating the page the data is fetched and rendered to make the application feel faster. This is generally referred to as a client-side rendered application.

Since Next.js is in control of the compilation pipeline we can decide at build time if a page will always get the same result by inferring if the page has data requirements. If it doesn't have data requirements we'll automatically render the page as a static HTML file.

When this proposal is implemented you'll be able to choose between pre-rendering and dynamic rendering on the page level.

Goals

  • Provide fast by default experience
  • Optimize pages that we know are always going to render the same result
  • Allow usage of dynamic, static or client-side only on a per-page level
  • Support client-side only applications that lazy-load data
  • Powerful use-case for dashboards
  • Great for marketing pages that lazy-load login / authentication state

API

This proposal doesn't need any API changes, it's mostly related to changing the semantics and internals of Next.js to export HTML in certain cases during next build.

Initially, we will cover the case where getInitialProps is not defined. Meaning that if a page doesn't have getInitialProps it is automatically exported as HTML.

// pages/about.js
export default () => <p>Hello world</p>

This is always going to render the same, so during build, we export it to an HTML file.

We might also need to detect router usage, but we won't cover that in the initial implementation as it's not as common. In this case you probably don't want to do dynamic rendering.

import { useRouter } from 'next/router'

export default () => {
  const router = useRouter()
  const { query } = router
  
  return <p>Page: {query.page}</p>
}

On the Now side of things @now/next will be updated to upload the .html files generated by the build.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions