Next.js Guidelines
Overview
Advantages of using Next.js in projects and good code practices.
Advantages of using Next.js
- Every page is rendered on the server (SSR)
- Prefetching pages
- Automatic code splitting for faster page loads
- Simple client side routing
- Able to implement with Express or any other Node.js HTTP server
- Customizable with your own Babel and Webpack configurations
- Next.js handles SEO optimization for you
Project Structure
project/
|
|– components/
| |- common/ # Components used multiple times across the app
| | |– button.js # Button component
| | |– ...
| |– examplePage/ # Components used solely in examplePage
| | |– ...
|
|– pages/
| |– index.js # Index page - URL: ROOT_URL
| |– examplePage.js # Example page - URL: ROOT_URL/examplePage
| |– ...
|
|- static/ # Contains application assets (e.g. images)
| |- ...
|
Fetching Data
For initial data fetch we use the built-in method getInitialProps using the fetch()
API.
Something to watch out for:
getInitialProps()
is called server-side only on a page refresh. When a is followed (client-side navigation), getInitialProps()
is called client-side.
This means you need to ensure that it can safely be called both ways.
Styling
We recommend using styled-jsx for styling components, as it’s already a built-in feature of Next.js. The aim is to support “shadow CSS” similar to Web Components (which are support server-side rendering). Other styling methods are also supported. External stylesheets and external styling libraries are also supported (but not recommended).
Static File Serving (e.g.: images)
Create a /static folder in the project’s root directory, then reference those files with /static/…
URLs.
More on that here.
Prefetching Pages
Just add the prefetch
prop to any <Link>
and Next.js will prefetch those pages in the background. This is a production-only feature.
Custom <App>
Next.js uses the <App>
component to initialize pages, which we can override and implement our own logic for page initialization.
Perks:
- Persisting layout throughout pages
- Keeping state while navigating
- Custom error handling using
componentDidCatch()
- Inject additional data into pages (e.g. processing GraphQL queries)
To override the <App>
component, simply create a _app.js
file in the pages directory.
More on that here.
Lazy Loading Modules
Next.js does automatic code splitting and it is based on the pages in your app. For example, if one of your modules is used at-least in half of your pages, then it moves into the main JavaScript bundle. If not, that module stays inside the page’s bundle. But sometimes we need much better control and reduce the bundle size. That’s where lazy loading comes in. An example from the official docs can be found here.
Lazy Loading Components
Dynamically loading components using the dynamic-import from Next.js. Helps reduce bundle size by loading components and associated libraries/modules by loading them only when rendered. An example from the official docs can be found here.
Create-Next-App
Another thing worth noting is create-next-app, which creates a Next.js project from scratch. It will generate the initial project structure, basic Next.js configuration and install necessary dependencies.
Conclusion
With Next.js we get a lot of time-consuming and complicated stuff right-out-the-box. It’s easy to setup and we can easily customize the configurations. We recommend checking out the Next.js documentation, as well as the Next.js tutorial, if you haven’t already. We also recommend going through the Javascript guidelines and the React guidelines in our engineering handbook.