My experience migrating projects to Next.js

Official documentation about migration to Next.js is pretty comprehensive and guides you through almost all the common steps that you need to take in the process.

Still, there could be some use cases specific only to your React.js application.


This content originally appeared on DEV Community and was authored by Rinat Rezyapov

Official documentation about migration to Next.js is pretty comprehensive and guides you through almost all the common steps that you need to take in the process.

Still, there could be some use cases specific only to your React.js application.

Pages folder

Next.js bases its file system routing on pages folder. This is a pretty neat approach but comes with some limitations. The problem with classic React.js applications is that some of them might not even have pages folder or have it deeply nested in the folder structure.

root
|
└───src
│   │
│   └───app
│       │   App.tsx
│       │   ...
|       └───pages
│   
└───template
│   │
│   └───components
│   └───colors

More to that - Next.js allows only two locations of pages folder:

  • root/pages
  • root/src/pages

So keep in mind that you'll have to do some folder structure refactoring before moving to Next.js.

Components that use Web API

You probably know that you can't use window object server-side and you need to always check whether window is defined before accessing it.

For components that extensively use Web API (charts, animations) and too complex to refactor, it's easier to dynamically import the whole component from the parent component.

import dynamic from 'next/dynamic';

const ChartsComponent = dynamic(
  async () => dynamic(() import('app/components/ChartsComponent')),
  { ssr: false },
)

Next Router isReady

Sometimes a user is redirected to your React.js application from other services with some information in query parameters. It could be an email about registration confirmation with confirmation token: https://yourReactApp.com/token or redirection from a OAuth provider.
In such cases you usually catch these query parameters using window.location.search and then process them.
I noticed that when I moved my application to Next.js these query parameters didn't appear in Next's router at first render and only on the second render I could see them in router.query. This behaviour broke my authentication process. Turned out that this is because Next's router fields are updated server-side first and only then client-side. To skip the first update with the empty query you have to use router.isReady field in useEffect hook:

import { useRouter } from 'next/router';

const RedirectsCatcherComponent = () => {
  const router = useRouter();
  useEffect((() => {
    if (router.query.token) {
      proceedAuthentication(router.query.token);
    }
  }), [router.isReady])
}

Dockerfile

If you use Docker containers in your infrastructure you could use the example of Dockerfile in the official documentation or if you use npm:

FROM node:alpine AS builder

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
RUN npm install --production

USER node

FROM node:alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app .
EXPOSE 3000

ENV NODE_OPTIONS=--max_old_space_size=1024

CMD ["npm", "start"]

Basically what it does here is it builds static assets using production and dev dependencies and then install only production dependencies that needed to start Next.js server.

Notice ENV NODE_OPTIONS=--max_old_space_size=1024 here. If your Docker container resources are limited, the build process sometimes might crash with the error Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory. This environment variable solves the problem. Just make sure that is slightly lower value is set than Docker container memory limit value.

You are not static anymore

With great power comes great responsibility

I'm sure you decided to use Next.js mainly because you wanted to improve the performance of your React.js application with server-side rendering.
One thing to consider is that you as a frontend developer will be responsible for running Node.js server that will serve static assets. Everything that is running tends to crash, so bear in mind that you will need to consider some kind of failover solution. It could be pm2 or Nomad or even multiple Docker containers in nginx upstream configuration.

Can Next.js replace nginx?

It depends on what kind of job your nginx performs. If it's only modifying headers then Next.js can do it also. It even can set security headers with the help of a third party library.
For some more advanced use cases, such as determining the real user's IP address you would probably need to use custom Next.js server.

Authentication

As I said before, if you are using Next.js you are probably going to use server-side rendering.
A typical client-side React.js application usually uses JWT tokens for authentication and stores them in a browser's storage.
As you may also know browser's storage is not available server-side and you won't be able to get tokens and use them to make authenticated requests to the backend and render authenticated pages server-side.
If it's your case then you need to think about storing authentication tokens in cookies. After that you will be able to get authentication tokens in req.headers.cookie server-side.

async function getServerSideProps(context) {
  if (req.headers.cookie) {
    const token = getToken(req.headers.cookie);
    // make requests
  }
}

If you need to perform authentication client-side you just retrieve the cookies from the browser.

The process of moving from browser's storage to cookies in terms of storing tokens is usually pretty complex, especially if you are using an OAuth protocol.
If you store tokens client-side then you probably have a mechanism that periodically refreshes these tokens and checks if they are valid. You will need to move this mechanism to the backend side since the backend will be responsible for handling tokens and putting them in cookies. If you are using an OAuth provider, it's even harder. So think about this step in advance.

For now, that's it. From my experience, migrating to Next.js most of the time was a surprisingly positive experience, so if you planned to move to Next.js - make preparations and do it now!


This content originally appeared on DEV Community and was authored by Rinat Rezyapov


Print Share Comment Cite Upload Translate Updates
APA

Rinat Rezyapov | Sciencx (2021-04-30T17:41:30+00:00) My experience migrating projects to Next.js. Retrieved from https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/

MLA
" » My experience migrating projects to Next.js." Rinat Rezyapov | Sciencx - Friday April 30, 2021, https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/
HARVARD
Rinat Rezyapov | Sciencx Friday April 30, 2021 » My experience migrating projects to Next.js., viewed ,<https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/>
VANCOUVER
Rinat Rezyapov | Sciencx - » My experience migrating projects to Next.js. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/
CHICAGO
" » My experience migrating projects to Next.js." Rinat Rezyapov | Sciencx - Accessed . https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/
IEEE
" » My experience migrating projects to Next.js." Rinat Rezyapov | Sciencx [Online]. Available: https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/. [Accessed: ]
rf:citation
» My experience migrating projects to Next.js | Rinat Rezyapov | Sciencx | https://www.scien.cx/2021/04/30/my-experience-migrating-projects-to-next-js/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.