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.jsReact 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/linkto 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.