BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Next.js 9.3 Released, Improves Static Site Generation

Next.js 9.3 Released, Improves Static Site Generation

This item in japanese

Bookmarks

The Next.js team recently released Next.js 9.3, featuring improved static website generation and preview, and the addition of Sass support, while shipping a smaller runtime.

Next.js added support for static website generation two years ago in version 3. Next.js 9 introduced the concept of Automatic Static Optimization, allowing developers to have hybrid applications that contain both server side-rendered (SSR) and statically generated pages (SSG). Automatic static optimization relies on whether a page had blocking data fetching requirements, as indicated by a getInitialProps method in the code of the page.

Following a RFC dedicated to static site generation, Next.js 9.3 introduces three new methods that aim at making a clear distinction between what will become SSG vs SSR.

The first method getStaticProps is an async function that computes props passed to the page component. The function runs in the Node.js context and receives a context parameter that contains the route parameters – necessary for pages using dynamic routes.

The second async method getStaticPaths is useful when handling dynamic routes. The function computes a list of paths that have to be rendered to HTML at build time, and specifies a fallback behavior when the user of the generated application is navigating to a route that is not included in the generated list of paths. If fallback is false, then any paths navigated by the user that are not returned by getStaticPaths will result in a 404 error page. Otherwise, if the page path was not generated at build time (not in the computed list), it will be generated on-demand when a user requests the page. The release note provides the following example for a blog application featuring dynamic routes:

// pages/posts/[id].js
import fetch from 'node-fetch'

function Post({ post }) {
  // Render post...
}

// This function gets called at build time
export async function getStaticPaths() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map(post => `/posts/${post.id}`)

  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false }
}

// This also gets called at build time
export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // Pass post data to the page via props
  return { props: { post } }
}

export default Post

With this code, Next.js will generate all the blog posts at build time (const paths = posts.map(post => `/posts/${post.id}`), and an error page when the user navigates to a non-existing blog post. Generating the page for one blog post will lead to fetching the content of the post, and passing that as a post prop to the Post React component.

The last async method getServerSideProps will lead to Next.js rendering the page anew on each request (SSR). getServerSideProps thus always runs server-side. The function receives a context parameter that contains the route parameters, the request and response objects, and the query string.

Next.js 9.3’s preview mode allows users to bypass the statically generated page to on-demand render (SSR), a draft page from for example a CMS. Next.js 9.3’s preview mode integrates directly with both getStaticProps and getServerSideProps and requires to create a preview API route. The preview mode allows developers to write a draft on a headless CMS and preview the draft immediately without regenerating the static page.

Next.js 9.3 additionally added both global and component-scoped Sass support (through CSS Modules). The syntax involves a simple import. The release note provides the following example for a global style sheet:

import '../styles.scss'

// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

CSS Modules for Sass files are only enabled for files with the .module.scss extension. The global Sass files must be in the root of the project and imported in the Custom <App>component(./pages/_app.js file).

Next.js 9.3 features differential bundling by default and will only load the necessary polyfills in legacy browsers. The new practice results in over 32 kB eliminated from the first load size for all the users with modern browsers (which do not require of polyfills).

Next.js’s new features have received positive reactions from numerous developers. On Twitter, André Scar said:

This is wonderful. I followed some of the discussion in the SSG RFC, and it is great to see this turn into a real feature! Congrats on everyone.

Next.js 9.3’s new features are non-breaking and fully backward compatible. To update to the new version, Next developers need to install it with npm:

npm i next@latest react@latest react-dom@latest

Next.js is available under the MIT open source license. Contributions and feedback are welcome and may be provided via the GitHub project.

Rate this Article

Adoption
Style

BT