Migrating From create-react-app to Next.js

Migrating From create-react-app to Next.js

In this article, I’m going to walk you through the steps I took to migrate my React app to Next.js.

It’s super easy and can be done in a couple of hours. Next.js is a lightweight React framework, so it’s not like comparing oranges to apples. It’s opinionated though, which means a few things are a little bit different.

Step by Step: Converting a CRA to Next.js

Create a new Next.js project.

First up, run this command in your terminal to create the starting point for your new app.

$ npx create-next-app

Drop your components into your Next.js project.

In your fresh Next.js project, you have to create a components folder. Use that one for all of the re-usable components.

Now, you’ll want to turn your components that represent actual pages into, well, pages. That’s what the pages folder is for. Each file in pages represents a page on your website. Go ahead, put your page components there. The naming convention for pages is all lowercase. Your root page should thusly be called index.js.

Routing: React vs Next.js

While plain React either renders as a true Single Page Application—much like a phone app on the web—or renders routes with the help of a router component, Next.js ships with an internal routing mechanism. It mirrors the file paths to your pages and even allows for dynamic routes (slugs, ID’s and such).

With that in mind, you need to create the directory structure that mirrors your router configuration. Given its popularity, you were probably using react-router, so you could do a project wide search for <Route and migrate them one by one.

With the page setup out of the way, you now need to change the links throughout your project to native ones. As I said earlier, Next.js comes with a routing solution pre-packaged and these have a slightly different syntax.

First, replace every import of react-router’s link:

import {Link} from "react-router-dom"

With the equivalent in Next.js:

import Link from “next/link"

Now, the syntax is as follows:

 <Link to="/destination/path">Link Caption</Link> 
 becomes <Link href="/destination/path">Link Caption</Link>.

Essentially just switching out to with href.

If, however, you were using styles and CSS classes on a link, you have to change the code a little bit more.

Links in Next.js are simply decorators and only accept one prop: href. Hence, you have to put your styles and classes on an anchor tag directly and wrap it with the Link decorator like so:

<Link href="/destination/path">
    <a className="underline test-gray-600">Link Caption</a>
 </Link>

CSS

The steps in this section will be different for everybody reading this. There’s a myriad ways to write CSS. Be it one vanilla CSS file, SASS, styled-components or using one of the thousand CSS frameworks.

Install @zeit/next-sass

Create a file next.config.js at root level of project:

const withSass = require('@zeit/next-sass');
module.exports = withSass({
  webpack (config, options) {
      return config;
  }
});

Assets : React vs Next.js

While in React, you can simply import assets like images, vectors and fonts straight away, buy not so in Next.js. You will have to add a webpack loader for that type of asset to your next.config.js first.

For image files, I’m using next-images. Just go to your next.config.js file, if you already have one, or create one in the root of your project now. If you just had to create a config file these two lines of code are all you need:

const withImages = require('next-images');
module.exports = withImages();

Should you already have a config for, say, your CSS framework of choice, you might be wondering how to also use next-images on top of that. Just wrap the current config in it.

Here’s my config for example:

const withSass = require('@zeit/next-sass');
const withImages = require('next-images')
 module.exports = withImages(withSass({
webpack (config, options) {
     return config;
  }
}));

Injecting custom scripts

  • Create _document.js file under pages directory:

  • Import Document, { Head, Main, NextScript } from next/document.

 export default class MyDocument extends Document {
  render () {
   return (
     <html lang="en">
       <Head />
       <body>
         <Main />
         <NextScript />
       </body>
     </html>
   )
 }
}

Conclusion

In essence, Next.js is a React framework, that’s just a little bit opinionated. This makes it very easy to migrate a React app over to Next as you’ve seen in this article.

You should, hopefully, now have a running Next.js app, at least locally.