Migrating from CRA (create-react-app) to Next.js

January 7, 20212 min read

I have recently migrated the React app bootstrapped with create-react-app to Next.js. The main reason was to improve SEO by making the app more indexable with Next.js which enables server-side rendering. This blog post will cover the necessary steps in the migration process.


next package (version 10) should be installed.

Npm scripts

There should be 3 required scripts in package.json.

  • build builds the app for production usage (the app is built in .next directory).
  • dev runs the development server on the given port.
  • start runs the production server on the given port.
"scripts": {
"build": "next dev -p 1234",
"dev": "next build",
"start": "next start -p 1234"

Environment variables

Environment variables should be prefixed with NEXT_PUBLIC_ so they can be used in the browser. dev and start scripts can use variables defined in .env.local and .env.production.local files respectively.

// .env.local

Head tags

Page-specific meta tags should be stored in the component function between Head (imported from next/head) tags. Common link tags should be stored in component function in pages/_document.js between Head (imported from next/document) tags. Viewport and charset meta tags should be placed in a separate component between Head (imported from next/head) tags with specified key attributes. With this approach, the default values will be changed. Other meta tags should follow the same principle as common link tags.

content="width=device-width, initial-scale=1"

Routing and pages

Pages are associated with a route based on their file name, e.g. pages/home.jsx is mapped to /home. Default pages directory (./pages) can be changed to ./src/pages by renaming src property inside next.config.js to ./src. Custom Not found page can be implemented in pages/404.js file. Link component from the React router should be replaced with Link component from next/link.

// next.config.js
module.exports = {
src: './src'

Service worker

A service worker can be registered in the App component from pages/_app.js file using useEffect hook.

function App({ Component, pageProps }) {
useEffect(() => registerServiceWorker(), []);
return <Component {...pageProps} />;

Third-party library CSS

External CSS can be imported at the beginning of pages/_app.js file.

import 'bootstrap/dist/css/bootstrap.min.css';


© 2022