Comparing Next.js and After.js for SSR React apps
Tags: react, javascript
Published: 2020-05-18 18:48:17

---
title: Comparing Next.js and After.js for SSR React apps
published: true
date: 2020-04-28 16:00:55 UTC
tags: react,javascript
canonical_url: https://blog.logrocket.com/comparing-next-js-after-js/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/qs0u0pu9zv2pxxagrtyo.jpeg
---
**Written by [John-Au Yeung](https://blog.logrocket.com/author/johnau-yeung/)**✏️

Next.js and After.js are both frameworks that let us build server-side-rendered React apps without the hassle of setting up SSR from scratch from a create-react-app project. In this article, we’ll compare Next.js and After.js and explore their differences.

## Differences between Next.js and After.js

The major difference between Next.js and After.js is in the routing mechanism.

With Next.js, we don’t specify the routes directly; instead, we let Next.js deal with the routing automatically. It maps URLs to our components by checking the project’s file structure and mapping URLs directly to components with that. On the other hand, with After.js, we’ve to specify the routes explicitly. After.js uses React Router to do the routing.

Most of the other features like data fetching and how pages are created are pretty much the same between the two.

The way projects are created is done pretty much the same way with their own CLI programs.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

To create a Next.js project, we run:

```jsx
npm init next-app
//or
yarn create next-app
```

To create an After.js project, we run:

```jsx
yarn global add create-after-app
create-after-app
```

## Page creation

Both Next.js and After.js let us create pages by adding React components. To illustrate, we’ll create an app using the [News API](https://newsapi.org/) with Next.js and After.js. All we have to do is create components, and then it’ll display in our app.

In Next.js, if we just create the page in the `pages` folder, then we can navigate to it via the URL with the same name.

For instance, in Next.js, we can create `index.js` in the `pages` folder as follows:

```jsx
import NavBar from '../components/navbar'
import fetch from 'isomorphic-unfetch';
import HeadTag from '../components/head-tag';

export async function getStaticProps() {
  const res = await fetch(`https://newsapi.org/v2/top-headlines/?language=en&apiKey=${process.env.apiKey}`)
  const data = await res.json()
  return {
    props: {
      data,
    },
  }
}

const Home = ({ data }) => (
  <div>
    <HeadTag />
    <NavBar />
    {data.articles.map(a => (
      <div key={a.title}>
        <h1>{a.title}</h1>
        <p>{a.description}</p>
        <p>{a.content}</p>
      </div>
    ))}
  </div>
)

export default Home
```

The `getStaticProps` function will let us fetch data, and then we can get it from the props with the same name in our component.

We can create an about page in `about.js` as follows:

```jsx
import NavBar from '../components/navbar'
import HeadTag from '../components/head-tag'

const Home = () => (
  <div>
    <HeadTag />
    <NavBar />
    <p>This is a news app.</p>
  </div>
)

export default Home
```

Then we can navigate directly to them by going to `/` and `/about`, respectively.

In the `components` folder, we can create components that we can reference in the page by creating the following files:

```jsx
//head-tag.js

import Head from 'next/head'

const HeadTag = () => (
  <Head>
    <title>News App</title>
  </Head>
)

export default HeadTag
```
```jsx
//navbar.js

import Link from 'next/link'

const NavBar = () => (
  <nav>
    <Link href="/">
      <a>Home</a>
    </Link>

    <Link href="/about">
      <a>About</a>
    </Link>
  </nav>
)

export default NavBar
```

In our After.js app, we created the following components in the `src` folder:

```jsx
//Home.js

import React, { Component } from 'react';
import NavBar from './NavBar';
import fetch from 'isomorphic-unfetch';

class Home extends Component {
  static async getInitialProps() {
    const res = await fetch(`https://newsapi.org/v2/top-headlines/?language=en&apiKey=${process.env.RAZZLE_APIKEY}`)
    const data = await res.json();
    return { data };
  }

  render() {
    const { data } = this.props;
    return (
      <div>
        <NavBar />
        {data.articles.map(a => (
          <div key={a.title}>
            <h1>{a.title}</h1>
            <p>{a.description}</p>
            <p>{a.content}</p>
          </div>
        ))}
      </div>
    );
  }
}

export default Home;
```

We get the data in the `initialProps` static method, and then we can access it via the props.

```jsx
//About.js

import React, { Component } from 'react';
import NavBar from './NavBar';

class About extends Component {
  render() {
    return (
      <div>
        <NavBar />
        <p>This is a new app</p>
      </div>
    );
  }
}

export default About;
```

The components that we reference in the pages can be created in the same folder:

```jsx
import React from 'react';
import { Link } from 'react-router-dom';

class NavBar extends React.Component {

  render() {
    return (
      <div>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </div>
    );
  }
}

export default NavBar;
```

As we can see, these are all just standard components. The difference is that we used the `Link` component from React Router for page navigation links in After.js, and in the Next.js project, we add page navigation link with Next.js’ own `Link` component.

All that being said, the experience for creating pages is pretty much the same in each framework.

## Routing

Routing is where Next.js and After.js are quite different.

Next.js’ routing works right out of the box without much hassle. Once we create the pages, we can navigate to them directly or with links rendered by the `Link` component.

On the other hand, After.js is a lot trickier. If we have a page component that has the `getInitialProps` method to fetch data, then we can’t add it to the routes file as an async component.

In our `routes.js` file, which is in the `src` folder of our After.js project, we have:

```jsx
import React from 'react';

import { asyncComponent } from '@jaredpalmer/after';
import Home from './Home';

export default [
  {
    path: '/',
    exact: true,
    component: Home,
  },
  {
    path: '/about',
    exact: true,
    component: asyncComponent({
      loader: () => import('./About'), // required
      Placeholder: () => <div>...LOADING...</div>, // this is optional, just returns null by default
    }),
  },
];
```

The `About.js` doesn’t fetch data before it renders, so we can include it as an async route. However, the `Home` component can’t be included as an async route because we have the `getInitialProps` async method to get data.

Routing is simply easier to deal with in a Next.js project, where it works right out of the box. Routing is more configurable with After.js, but we’ve got to configure it ourselves.

## Data Fetching

Data fetching in both Next.js and After.js is done when the component is first rendered. As we can see from the previous section, `index.js` in our Next.js project fetches data in the async `getStaticProps` function. In the After.js project, we use the `getInitialProps` static method of the component class to fetch data before rendering the page.

In both components, the fetched data is available as props within the component.

The environment variables are stored in `next.config.js` in the Next.js project as follows:

```jsx
module.exports = {
  env: {
    apiKey: 'your_api_key',
  },
}
```

And in the After.js project, environment variables are stored in the `.env` file, and the keys for environment variables that we can use inside the project must be prefixed with `RAZZLE_`.

For example, we can write it like the following:

```jsx
RAZZLE_APIKEY=your_api_key
```

In both frameworks, environment variables are available as a property of the `process.env` object.

## Conclusion

Both Next.js and After.js can be used to build server-side rendered projects. They’re useful for building server-side rendered apps without much effort.

The main difference between Next.js and After.js is the routing. Next.js maps URLs to components by their name and whether the component files are in the `pages` folder. In contrast, After.js uses React Router for routing, and we’ve got to configure it ourselves.

* * * 
## Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React 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 React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [Comparing Next.js and After.js for SSR React apps](https://blog.logrocket.com/comparing-next-js-after-js/) appeared first on [LogRocket Blog](https://blog.logrocket.com).