Migrating from CRA (create-react-app) to Next.js
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.
Prerequisites
next
package (version 13) should be installed@next/eslint-plugin-next
package should be installed as a dev dependency
Npm scripts
There should be three 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 build","dev": "next dev -p 1234","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.localNEXT_PUBLIC_API_URL=http://localhost:8080
Linting
Update the eslint configuration to include the Next.js eslint plugin.
// .eslintrc.jsmodule.exports = {extends: ['plugin:@next/next/recommended'],parserOptions: {ecmaFeatures: {jsx: true},ecmaVersion: 2022,sourceType: 'module'}};
Head tags
Set page-shared meta
and link
tags within the root layout component (app/layout.jsx
).
export default function RootLayout({ children }) {return (<html lang="en"><head><link rel="icon" href="/favicon.svg" /><link rel="manifest" href="/manifest.json" /><meta name="theme-color" content={THEME_COLOR} /></head><body>{children}</body></html>);}
Export page-specific meta
tags within metadata
variables inside server components. Client components have to use "use-client"
directive.
export const metadata = {title: 'nextjs-starter',description: 'Minimal Next.js boilerplate',};
Routing and pages
Pages are associated with a route based on their file name, e.g., app/home/page.jsx
is mapped to /home
. Index page component is stored in app/page.jsx
file.
Implement a custom Not found page in the app/not-found.jsx
file. Replace the Link
component from the React router with the Link
component from the next/link
.
Service worker
Register a service worker in the root layout component from app/layout.jsx
file using the useEffect
hook. Store it in the public
folder.
'use client';export default function RootLayout({ children }) {useEffect(() => {registerServiceWorker();}, []);// ...}
State management
This topic is covered in State management with Next.js and React post.
Boilerplate
Here is the link to the boilerplate I use for the development. It contains the examples mentioned above with more details.