Austin Roy Omondi Live long and prosper 👌

How to adopt Next.js into your existing application

4 min read 1223

Adopt Nextjs Into Your Application

Server-side rendering, also known as SSR, has made such a great impact on the frontend developer community, React announced plans to officially introduce Server Components into the library. You may be wondering what the fuss is all about and why one may want to opt for SSR over the regular client-side rendering that React primarily uses.

SSR has several benefits:

  • Better results from SEO (search engine optimization) because search engines are more easily able to crawl SSR rendered sites for keywords and display on the SERPs (search engine results pages) for related content
  • Advantages from SMO (social media optimization) that arise from displaying a preview when shared on social media platforms
  • Faster loading than client side-rendered applications, making SSR sites more responsive and providing a better user experience

These advantages have led to the rise of the Jamstack architecture, which aims to deliver faster and more consistent web experiences by making use of pre-rendering where assets are compiled on the server during building.

Next.js is one of the most beloved SSR packages in the React community and allows developers to take advantage of the benefits of SSR when building their websites with React.

Next.js provides a zero-configuration setup process similar to what Create React App does through a package called Create Next App. Today, we will look at how you can make use of Next.js on a pre-existing React application. This will allow you to add SSR to an existing project.

Migration process

To show you how this migration is done, we will migrate this project from a previous tutorial, a demo of React components for TypeScript codebases, to use Next.js.

The first step will be to clone the repo, which you can do with either SSH, HTTPS, or the new GitHub CLI:

//SSH
git clone [email protected]:austinroy/react-ts-component-demo.git
//HTTPS
git clone https://github.com/austinroy/react-ts-component-demo.git
//GitHub CLI
gh repo clone austinroy/react-ts-component-demo

Install the dependencies with the yarn command and run the application with yarn start. You should see some basic Star Wars information on your browser that is similar to this sandbox.

Updating scripts and dependencies

This application was set up using Create React App, which uses react-scripts as its script runner. You will need to replace this with next.

We made a custom demo for .
No really. Click here to check it out.

Uninstall react-scripts from the project and add next:

yarn remove react-scripts

yarn add next

We used React Router for our page navigation, but Next.js uses a different method of routing, which we will also cover. You will need to also uninstall react-router-dom:

yarn remove react-router-dom

Our next step is to update any scripts that used react-scripts to use next in our scripts section of the package.json file:

...
"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
...

next dev runs a development server on localhost:3000, and next build compiles a production ready version of the application, while next start runs the production version of the application.

Lastly, add .next to .gitignore.

Routes and linking

As we mentioned above, Next.js has a totally different method of handling routing and page linking from React Router and react-router-dom. It has a file system-based router built on the concept of pages, where a page is a React component exported from a .js, .jsx, .ts, or .tsx file in the pages directory.

To implement, we will need to create a pages directory and convert all Route components in our app to files inside pages.

mkdir pages && touch pages/index.tsx pages/WithoutTS.jsx

Now let’s create our homepage. Add the following code to your pages/index.tsx file:

import { DisplayWithTS } from '../src/pages/WithTS'
const TSComponent = () => {
    return(
      <div className="App">
          <a href="/">With TS</a>
          <br/>
          <a href="/WithoutTS">Without TS</a>
          <br/>
          <br/>
          <DisplayWithTS />
      </div>
    )
  }

  export default TSComponent

To demo the JavaScript component, we will build the WithoutTS page. Add the following code to the pages/WithoutTS file:

import { DisplayWithoutTS } from '../src/pages/WithoutTS'
const JSCOmponent = () => {
    return(
      <div className="App">
          <a href="/">With TS</a>
          <br/>
          <a href="/WithoutTS">Without TS</a>
          <br/>
          <br/>
          <DisplayWithoutTS />
      </div>
    )
  }

  export default JSCOmponent

Styling

Similarly to Create React App, next allows you to import styles into components. In Next.js, however, they need to be handled as CSS Modules.

You can, however, add global stylesheets by creating a custom _app.js file in the pages directory:

touch pages/_app.js

Import styles into _app.js and add the following code:

import '../src/App.css'

export default function App({ Component, pageProps }) {
   return <Component className="App" {...pageProps} />
}

You will need to restart the dev server to load up the changes after creating _app.js. Do this and check your browser; you will now have completely replicated the previous appearance of the application as seen in the code sandbox. And just like that, your application is now rendered on the server side with Next.js. Pretty nice!

Cleanup

Now you can erase files that were generated by Create React App from the src directory like App.tsx, App.test.tsx, index.ts , index.css, and serviceWorker.ts, because Next.js now handles everything these files were doing.

You can also rearrange your folder structure a little as you like, but keep in mind that Next.js uses a file system-based routing mechanism when doing so.

Other things to look into

Now you are all set to get started migrating your old projects to Next.js. For more complex projects, however, you may need to dig a little deeper.

  • Access to window, localStorage, navigator, and other Web APIs – these are usually available to client-side rendered apps out of the box, but since Next.js uses pre-rendering, you will need to access them only on the client-side of your SSR app. One way to do this is with the useEffect Hook
  • Image optimization – while our demo application has no images in it, most web applications will make use of image assets somewhere within them. Next.js provides a custom Image Component. next/image is an extension of the HTML <img> element, evolved for the modern web. It provides build time optimizations for resizing, optimizing, and serving images in modern formats like WebP when the browser supports it
  • Environment variables – .env variables or secrets are also supported in Next.js just like with Create React App. However, you will need to change the REACT_APP_ prefix to NEXT_PUBLIC_ to make them available at build time
  • next/head for SEO – Next.js provides a built-in component to append tags to your application’s page head under next/head.

Overall, Next.js is one of the best SSR options currently available. Using server-side rendering in your applications has benefits for both user experience, like faster loading, and for exposure by increasing compatibility with SEO and SMO.

Adding Next.js into your already existing React application is a fairly straightforward process that offers a nice glimpse into what the future of frontend web development may look like, leaving many developers excited for what the upcoming React Server Components will hold.

LogRocket: Full visibility into production Next.js apps

Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your Next app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your Next.js apps — .

Austin Roy Omondi Live long and prosper 👌

Leave a Reply