I recently got the chance to migrate a custom CRA app to Next.js for a client. There were around ~4000 modules that were involved directly or indirectly(as npm dependency). This is what I learned through the process.
With a custom CRA set up the only suitable approach is the incremental adoption. But you would have to choose among the following two strategies.
react-router
only by default.If you need to do it through Next.js, you would have to change it’s path.It should be easy to switch b/w either of the two approaches by modifying Next.js. I would suggest a hybrid strategy.
[webpack5](https://nextjs.org/docs/messages/webpack5)
that you can use to disable enforcing the use of webpack v4, which has been removed in Next.js v12import "a.css"
, it is global CSS and Next.js throws an error and asks to move it to _app.js
. Learn how to do it here. If there are many such imports it’s going to be a pain to find out all of themnext dev
and see where it is reporting this error and move all such imports to _app.js
React Router
related changes. Also, read https://nextjs.org/docs/migrating/from-react-routeruseLocation
provided by react-router
has to be replaced with useRouter
provided by next/router
.react-router
is to be replaced with Link component provided by next/link
to
attribute has to be converted to href
attribute.You may need an additional loader to handle the result of these loaders. export type { CCProviders } from "./types";
Module not found: Can't resolve 'react/jsx-runtime' in ...
Link
component allows multiple children but the next/link
doesn’t allow that.At this point, you should have a working page that is rendered by Next.js. It might look to you that your job is done as you are seeing the page perfectly but it might or might not be pre-rendering. I
f you have a pretty simple app(with no data fetch requirements), then Next.js should be automatically rendering the components on the server-side and you are done. But even with a slightly complex app, you would face issues with getting components to render into HTML on the server.
This is owing to the following reasons:
useEffect
never executes on the server. This is where the data fetching code usually exists.You would have to choose the data fetching strategy according to https://nextjs.org/docs/basic-features/data-fetching(which also decides you are going to do SSR or SSG). After that, you would have to refactor your code let Next.js own data fetching.