Migrating a Create React App (CRA) to Next.js can greatly enhance the performance and capabilities of your application. This guide follows a step-by-step process to ensure a smooth transition.
Next.js supports server-side rendering out of the box, which can significantly improve the performance of your application by rendering pages on the server and sending the fully rendered HTML to the client. This results in faster initial page loads and better SEO.
With Next.js, you can pre-render pages at build time, resulting in faster load times and improved performance. Static Site Generation (SSG) is especially useful for content-heavy sites.
Next.js automatically splits your code into smaller bundles, which are loaded on demand. This reduces the initial load time and improves the performance of your application.
Next.js provides built-in support for CSS and Sass, including CSS Modules. This simplifies the process of styling your application and ensures that styles are scoped locally by default.
Next.js uses a file-based routing system, where the file structure of your project determines the routes of your application. This makes it easier to manage and scale your application as it grows.
Next.js allows you to create API routes within the same application, eliminating the need for a separate backend server. This simplifies the development process and reduces the complexity of your project.
Next.js includes an optimized image component that automatically optimizes images for different devices and screen sizes, resulting in faster load times and improved performance.
Next.js has excellent TypeScript support out of the box, making it easier to build and maintain type-safe applications.
.gitignore
Ensure node_modules
is included in your .gitignore
file to prevent committing unnecessary dependencies.
echo "node_modules" >> .gitignore
Install the latest version of Next.js along with PostCSS and Autoprefixer.
npm install next@latest
npm install postcss autoprefixer
Create a next.config.mjs
file to configure your Next.js application.
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export', // Outputs a Single-Page Application (SPA).
distDir: './dist', // Changes the build output directory to `./dist/`.
}
export default nextConfig
Step 2: Update tsconfig.json
Update your tsconfig.json
file with the necessary configurations for Next.js.
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"strictNullChecks": true
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"./dist/types/**/*.ts"
],
"exclude": ["node_modules"]
}
Create a layout.tsx
file in the app
directory. This will serve as the root layout for your Next.js application.
import type { Metadata } from 'next'
// Import CSS files
import '../styles/globals.css';
export const metadata: Metadata = {
title: 'React App',
description: 'Web site created with Next.js.',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<div id="root">{children}</div>
</body>
</html>
)
}
postcss.config.js
FileCreate a postcss.config.js
file to configure PostCSS.
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Create the server-side and client-side entry points in the app
directory.
app/[[...slug]]/page.tsx
)import '../../index.css'
import { ClientOnly } from './client'
export function generateStaticParams() {
return [{ slug: [''] }]
}
export default function Page() {
return <ClientOnly />
}
Client-Side Entry Point (app/[[...slug]]/client.tsx
)
'use client'
import React from 'react'
import dynamic from 'next/dynamic'
const App = dynamic(() => import('../../App'), { ssr: false })
export function ClientOnly() {
return <App />
}
Ensure all static image imports are updated to relative paths.
// Old Import
import logo from '/logo.png'
// Updated Import
import logo from '../public/logo.png'
// Old Image Tag
<img src={logo} />
// Updated Image Tag
<img src={logo.src} />
Update your environment variables from REACT_APP_
prefix to NEXT_PUBLIC_
.
sed -i 's/REACT_APP_/NEXT_PUBLIC_/g' .env
package.json
Update your package.json
scripts for Next.js.
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
Additionally, update your .gitignore
to include Next.js-specific files.
echo ".next\nnext-env.d.ts\ndist" >> .gitignore
Remove CRA-specific files and dependencies.
rm src/index.tsx src/index.ts src/index.jsx src/index.js public/index.html src/reportWebVitals
npm uninstall react-scripts
Alternatively, you can fully automate this migration for free with Second. Just connect to your GitHub account, select a repo, select the CRA to Next migration module, and then run the job. Try it now.