By ChatGPT & Benji Asperheim | 2024-09-20Blog Thumbnail

Next JS vs React JS

In this blog post we'll go over the differences between a typical React app, and the Next.js framework (a server-side rendered (SSR) and static site generated framework) used in conjunction with a React app.

DISCLAIMER: The majority of this article was written by ChatGPT, but edited and touched up by a human.

Next.js Overview

Let's go over the basics of Next.js, what its use cases are, and how it's used.

Does Next JS use React?

Unlike a standard React app, which renders content on the client side and requires additional setup for SSR, Next.js provides these capabilities out of the box. It acts as an abstraction layer on top of React, handling the compilation and bundling processes to enable SSR and other optimizations seamlessly.

In essence, Next.js simplifies the development of performant, SEO-friendly web applications by:

  • Providing Built-In Routing: Next.js uses a file-based routing system, eliminating the need for external libraries like React Router.
  • Enabling SSR and SSG: It allows pages to be rendered on the server or pre-generated at build time, improving load times and search engine visibility.
  • Offering Automatic Code Splitting: This ensures that each page only loads the necessary JavaScript, enhancing performance.
  • Including API Routes: You can create backend endpoints within the same project, streamlining the development process.

So, while Next.js does act as a sort of SSR compilation layer on top of React, it also offers a suite of tools and conventions that simplify building complex web applications. It abstracts away much of the configuration required for SSR, allowing you to focus on writing your application's logic and UI.

When to use Next JS vs React

When deciding when to use Next JS vs React, it's essential to consider the specific needs of your project. React is a powerful library for building user interfaces, providing flexibility and a component-based architecture ideal for single-page applications. However, if you're looking to enhance performance and optimize for SEO, Next.js offers server-side rendering, static site generation, and built-in routing, making it a superior choice for dynamic, content-rich websites.

For projects requiring quick loading times and better search engine visibility, Next.js shines. Conversely, if your application is less content-focused and demands greater interactivity, React might be the better option. Ultimately, understanding your project's requirements and long-term goals will guide you in choosing the right tool.

Difference Between React and NextJS

  • Traditional React App: A client-side rendered application built using React, often set up with tools like Create React App (CRA). It handles routing, data fetching, and rendering entirely on the client side.
  • Next.js App: A React framework that enables server-side rendering (SSR), static site generation (SSG), and provides built-in features like routing and API routes. It simplifies the setup for performance optimizations and SEO benefits.

Next JS vs React: A Comparison of Folder Structures

In this section, we will explore the folder structure best practices for both Next JS and React.

React JS Structure Best Practices

For React, the folder structure best practices would look something like this:

  • Flexibility: The project structure is flexible and can be organized as per developer preference.
  • Common Directories:
  • src/: Contains components, styles, assets, etc.
  • public/: Static files like index.html, images.

React Example Structure:

my-react-app/
├── public/
│   └── index.html
├── src/
│   ├── components/
│   ├── App.js
│   └── index.js
├── package.json
└── README.md

Next JS Project Structure

Next.js used to have a project structure like so:

my-nextjs-app/
├── pages/
│   ├── api/
│   │   └── hello.js
│   ├── index.js
│   └── about.js
├── public/
│   └── images/
├── styles/
│   └── Home.module.css
├── package.json
└── README.md

However, in Next.js v13, there were some changes made to the file structure and routing approach compared to previous versions.

Changes in the Next JS Project Structure

1. App Directory: In Next.js 13 and later, a new app directory is introduced as an alternative to the pages directory. This allows for a more flexible routing system and improved data fetching methods.

2. File Structure:

  • Old Structure: In earlier versions, you had a pages directory where each file directly corresponded to a route.
  • New Structure: The app directory in Next.js 13 includes files like layout.tsx and page.tsx for defining layouts and pages, which makes it more powerful and modular.

3. Manual Setup: You don't need to manually create src/app/pages. Instead, you should use the provided structure in the app directory. The new routing mechanism simplifies some patterns, while also requiring you to adapt to the new conventions.

Transition from Pages to App Router

If you're following the new structure, here's a simplified view of how it works:

  • layout.tsx: Defines a layout for your pages.
  • page.tsx: Represents the content of the route.
  • Any additional directories within app can represent nested routes.

See the following boilerplate project generated by the latest version of Next.js:

├── README.md
├── next-env.d.ts
├── next.config.mjs
├── package-lock.json
├── package.json
├── src
│   └── app
│       ├── favicon.ico
│       ├── fonts
│       │   ├── GeistMonoVF.woff
│       │   └── GeistVF.woff
│       ├── globals.css
│       ├── layout.tsx
│       ├── page.module.css
│       └── page.tsx
└── tsconfig.json

4 directories, 13 files

The old "pages" structure is still valid for Next.js projects using the traditional routing system. However, with Next.js 13 and beyond, the app directory structure is the recommended approach, which can be quite different.

If you're using Next.js 13 and the App Router, you should follow the new conventions without needing to create a pages directory inside app. Just use the provided files in src/app.

It's a good idea to keep this in mind when setting up your NextJS file structure:

  • Opinionated Structure: Next.js enforces a specific structure, especially for pages and API routes.
  • Key Directories:
  • pages/: Each file represents a route.
  • public/: Static files accessible at the root URL.
  • styles/: Stylesheets (optional).

Benefits of the New Structure

  • Enhanced Modularity: The ability to define layouts at different levels makes it easier to manage shared UI elements.
  • Improved Data Fetching: You can use async functions directly in page.tsx to fetch data, allowing for streamlined data handling.
  • Loading States: The loading file allows for better user experiences by displaying loading indicators while content is being fetched.

How is Next JS Different from React?

There are a few differences in how certain features are implemented or used due to Next.js's additional functionalities. The syntax for JSX (JavaScript XML) is the same in both React and Next.js, because Next.js is built on top of React, but let's go over some of the differences in how JSX is used in each.

Special Functions in Next.js

Next.js introduces special functions for data fetching that are not used in typical React apps:

  • getStaticProps
  • getServerSideProps
  • getStaticPaths

These functions are exported from page components and are used during the build process or server-side rendering.

Next.js Special Function Example:

// pages/index.js
export async function getStaticProps() {
  // Fetch data here
  return {
    props: {
      /*...*/
    },
  };
}

export default function Home(props) {
  // Use fetched data
}

Next.js Link Component

React uses react-router-dom for routing and navigation:

// React with react-router-dom
import { Link } from "react-router-dom";

<Link to="/about">About<Link>;

However, Next.js uses its own Link component from next/link:

// Next.js
import Link from "next/link";

<Link href="/about">About<Link>;

NOTE: In Next.js, the Link component wraps an <a> tag. In older versions, you had to include an <a> inside Link, but since Next.js 11, you can pass the link text directly.

Images in Next.js

Next.js handles image optimization very well with the next/image library. In a standard react app you typically use a traditional <img> tag, or third-party libraries for image handling:

<img src="/images/photo.jpg" alt="Photo" />

However, Next.js provides the Image component for automatic image optimization:

import Image from "next/image";

<Image src="/images/photo.jpg" width={600} height={400} alt="Photo" />;

Overview of Next JS Image Lazy Loading

Here's a simple example of how to implement lazy loading for images in a Next.js application:

// pages/index.js
import Image from "next/image";

const Home = () => {
  return (
    <div>
      <h1>Lazy Loading Images in Next.js</h1>
      <p>This image will be lazy loaded:</p>
      <Image
        src="/path/to/your/image.jpg" // Path to your image
        alt="Description of the image"
        width={600} // Desired width
        height={400} // Desired height
        loading="lazy" // Optional, default is lazy
      />
    </div>
  );
};

export default Home;
  • Image Component: Use the Image component from next/image to automatically handle lazy loading.
  • Width and Height: Always specify the width and height properties. This helps Next.js allocate space for the image while it loads, preventing layout shifts.
  • Loading Attribute: The loading="lazy" attribute is optional because lazy loading is the default behavior for images in Next.js.

Using the next/image component not only enables lazy loading but also optimizes images automatically for different screen sizes and formats, improving performance and user experience.

CSS and Styling for a Next.js App

When using inline styles in Next.js, you can apply styles directly to your components without creating separate CSS files. This approach is useful for quick styling or dynamically changing styles based on component state. However, for larger projects, it's generally better to use CSS modules or styled-components for maintainability.

  • React: You might need additional configuration for CSS Modules or use CSS-in-JS libraries.
  • Next.js: Supports CSS Modules out of the box when the file is named with the .module.css extension.

The following is an example of how to use styles in a Next.js web app:

// pages/index.js
const Home = () => {
  return (
    <div>
      <h1 style={{ color: "blue", textAlign: "center" }}>Welcome to My Next.js App!</h1>
      <p style={{ fontSize: "18px" }}>This is a simple example of inline styles.</p>
    </div>
  );
};

export default Home;

In this example, inline styles are applied to the header and paragraph directly, allowing for quick customization of their appearance.

Next JS React Environment Variables

In a Next.js app you can use the @next/env library to (see the Next.js environment variables documentation for more details).

Install the package like so:

npm install @next/env

Then just create a envConfig.ts to load the variables with the following code:

import { loadEnvConfig } from "@next/env";

const projectDir = process.cwd();
loadEnvConfig(projectDir);

NextJS vs React: Page Component Export

If you intend to create a Next JS single page app, then you should keep in mind the key differences in how a component is exported in React vs Next.js:

React Components: These can either be named, or default export components using the export default keywords:

// Named export
export function Home() {
  /*...*/
}

// Default export
export default function Home() {
  /*...*/
}

Next JS Components: Page components should be the default export of the file in the pages/ directory:

// Next.js page component
export default function Home() {
  /*...*/
}

NextJS SSR

Next.js Server-Side Rendering (SSR) allows you to render pages on the server at request time, delivering fully populated HTML to the client. This enhances performance and SEO since search engines can easily crawl the content.

Server-Side Rendering (SSR) and Static Site Generation (SSG):

In Next.js, you have the ability to pre-render pages:

  • SSR: Pages are rendered on each request (getServerSideProps).
  • SSG: Pages are generated at build time (getStaticProps).

In React, to achieve SSR or SSG, you'd need additional tools or frameworks.

Overall Differences Between Next JS and React

Similarities: Both use JSX syntax for rendering components.

Differences:

  • Special Functions: Next.js using special get functions not found in a traditional React app
  • Special Components: Next.js introduces components like Link, Head, and Image.
  • Routing: Next.js uses file-based routing; React requires a routing library.
  • Data Fetching Methods: Next.js has built-in data fetching methods for SSR and SSG.
  • Exporting Pages: In earlier versions of Next.js, you had a pages directory where each file directly corresponded to a route. In newer versions of Next.js a new app directory is introduced as a more flexible alternative to the pages directory.

React Router vs Next JS

  • Manual Setup: Uses libraries like react-router-dom for client-side routing.
  • Definition: Routes are explicitly defined in code.

React Routing Example:

// src/App.js
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/about" component={About} />
        <Route path="/" component={Home} />
      <Switch>
    <Router>
  );
}

export default App;

Next JS React Router

In Next.js, routing is handled differently compared to traditional React Router. Instead of using a separate router package, Next.js has a built-in file-based routing system. The introduction of the /app directory replaces the traditional /pages directory, offering a more flexible and modular approach to routing and layout management. Here's how the new structure works:

Next JS Examples Using the 'app' Directory

File-Based Routing: The /app directory uses file-based routing, where the file structure directly maps to the application's routes. Each folder inside /app can contain specific files for layout and page components.

Key Files:

  • page.tsx / page.js: This file represents the content of a route. Each page file corresponds to a specific route in your application.
  • layout.tsx / layout.js: This file defines the layout for its child routes. Layouts can be nested, allowing you to create complex UI structures.
  • error.tsx / error.js: Handles error pages for that specific route.
  • loading.tsx / loading.js: Displays a loading state while the page is being prepared.

Nested Routes: You can create nested folders inside /app to manage sub-routes easily. For example, if you have an /app/blog directory, the corresponding route would be /blog.

Next JS React Router: Simple Route Example

Here's a basic example of how a Next.js component would look:

// pages/index.js
import Link from "next/link";

const Home = () => {
  return (
    <div>
      <h1>Welcome to My Website</h1>
      <nav>
        <ul>
          <li>
            <Link href="/about">About<Link>
          </li>
          <li>
            <Link href="/blog">Blog<Link>
          </li>
        </ul>
      </nav>
    </div>
  );
};

export default Home;

Next JS React Router: Dynamic Route Example

Here's how you can handle a dynamic route:

// pages/blog/[id].js
import { useRouter } from "next/router";

const BlogPost = () => {
  const router = useRouter();
  const { id } = router.query; // Get the dynamic id from the URL

  return <h1>Blog Post ID: {id}</h1>;
};

export default BlogPost;

Navigating Between Routes in Next.js

Next.js uses the Link component for client-side navigation. This allows for smooth transitions between pages without full page reloads, maintaining a single-page application feel.

Next JS vs Create React App

When comparing Next.js to Create React App (CRA), it's important to recognize their fundamental differences in purpose and capabilities. Next.js, initiated with npx, offers a full-fledged framework for building server-rendered applications, enabling features like server-side rendering (SSR), static site generation (SSG), and API routes out of the box.

In contrast, Create React App focuses primarily on creating single-page applications (SPAs) with a client-side rendering model. While CRA provides a solid foundation for React applications, it lacks the built-in optimization and routing capabilities that Next.js delivers, making Next.js a more powerful choice for projects that require enhanced performance and SEO features.

Next JS npm and npx Commands

Best practices for Next JS suggest following the Next.js documentation and running the npx create-next-app@latest, like in the following example, to create a new app:

npx create-next-app@latest
Need to install the following packages:
create-next-app@14.2.13
Ok to proceed? (y) y

✔ What is your project named? … blog-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /Users/benji/Downloads/Coding-Projects/blog-app.

Using npm.

Initializing project with template: app


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- eslint
- eslint-config-next

⠏

Change into the new project directory, and then you run the app with npm like so:

npm run dev

Finally, navigate to http://localhost:3000 in your browser to view the app.

Next JS Screenshot of Next JS vs React NextJS Tutorial

Next JS Advantages

Next.js has several key advantages over a regular React app, but it also has a few "gotchas" and drawbacks.

Traditional React App

Advantages:

  • Simpler setup for pure client-side applications.
  • Greater flexibility in project structure.
  • Familiar for developers used to SPA patterns.

Disadvantages:

  • Less optimal for SEO (since content is rendered after JavaScript loads).
  • Requires additional configuration for SSR or SSG.
  • Client-side data fetching can lead to slower initial page loads.

Advantages of Next JS over React

Advantages:

  • Improved SEO and performance with SSR and SSG.
  • Built-in routing and API routes reduce setup time.
  • Image optimization and code splitting out of the box.
  • Easy deployment to serverless platforms.

Disadvantages:

  • More opinionated structure may limit flexibility.
  • Steeper learning curve due to SSR concepts.
  • May introduce complexity for simple applications.

When to Use Next JS vs React

Use Traditional React App When:

  • Building a simple SPA without the need for SSR.
  • You require maximum flexibility in project setup.
  • SEO is not a primary concern (e.g., internal dashboards).

Use Next.js App When:

  • Building a website where SEO and performance are important (e.g., blogs, e-commerce).
  • You want to leverage SSR/SSG for faster initial page loads.
  • You prefer built-in solutions for routing and API endpoints.

Conclusion

Next.js is a framework built on top of React, enhancing it with additional features like server-side rendering, static site generation, and built-in routing.

Discover expert insights and tutorials on adaptive software development, Python, DevOps, creating website builders, and more at Learn Programming. Elevate your coding skills today!