icon

Next JS The Best React Framework

summary

Learn how to properly fetch data using Next.js app router and explore the differences from the old page router. Also, understand advanced data fetching techniques with bearer tokens.

tech stack
Next.js
React
published date
last edited time
thumbnail

What is Next.js?

Next.js is a React framework used for building high-quality web applications, and it's completely open source and free to use.

It focuses on making web development easier, faster, and more efficient with React components, along with additional features and optimizations provided by Next.js.

Why do we need Next.js? Why not just use React?

While React is good for making interactive parts of a website, it doesn't do everything on its own. It doesn't come with built-in server-side rendering or static site generation. Doing those things with React can be complicated and needs special skills. React also doesn't handle server-side data fetching or server actions. If you want to add and manage routes, you have to set up something like React Router, which needs extra knowledge. Adding things like Tailwind CSS or TypeScript after installing React requires extra steps. React also doesn't automatically handle dynamic SEO, image, font, or script optimization.

So, There Comes Next.js with All the Solutions.

Very Easy Installation of Next.js with TypeScript and Tailwind CSS

bash

Copy

npx create-next-app@latest
What is your project named? my-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
What import alias would you like configured? @/*

You can install Next.js with just one command, and it automatically sets up everything like,

During the installation of Next.js, it will ask if you want to use Tailwind CSS or TypeScript. Simply choose "Yes" or "No". If you choose "Yes", it will automatically configure it for you, simplifying the setup process.

Simplified Advanced Routing with Nested Layouts, Loading States, and Error Handling

Image

Creating routes has never been easier in Next.js. In a Next.js app, to create a route, you simply need to create a folder with the route name, such as "Blog". Inside this folder, add a page.js file (or page.jsx, .ts, or .tsx for TypeScript support). In this page.js file, define a function like this:

javascript

Copy

export default function Page() {
  return <h1>Hello, Next.js!, This is Blog Route</h1>
}
app/blog/page.js

See how easy it is? The image above also shows what amazing things you can do with it. Adding dynamic routes is very simple. You can assign a separate CSS module to each route and create separate layout, loading, and not-found page files for each folder (route). For more details, check this.

Easy Switching Between Server Side Rendering or Client Side Rendering

javascript

Copy

'use client'
 
import { useState } from 'react'
 
export default function Counter() {
  const [count, setCount] = useState(0)
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

By default, all components and pages created in Next.js are server-side rendered. If you want to add client-side interaction to a page, you need to define "use client" at the top of the file. This signals that the page or component will render on the client side. After this setup, you can use any hooks as needed. For more details, check this.

Full CSS Support with CSS Modules, Tailwind CSS, CSS-in-JS, or Sass

Next.js supports different ways of styling your application, including:

  • Global CSS: Simple to use and familiar for those experienced with traditional CSS, but can lead to larger CSS bundles and difficulty managing styles as the application grows.
  • CSS Modules: Create locally scoped CSS classes to avoid naming conflicts and improve maintainability.
  • Tailwind CSS: A utility-first CSS framework that allows for rapid custom designs by composing utility classes.
  • Sass: A popular CSS preprocessor that extends CSS with features like variables, nested rules, and mixins.
  • CSS-in-JS: Embed CSS directly in your JavaScript components, enabling dynamic and scoped styling.

Simplified Data Fetching with Strong Caching

javascript

Copy

export default async function Home() {
  const res = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const data = await res.json();
  const jsonData = JSON.stringify(data, null, 2);
  return (
    <main className="flex justify-center items-center h-screen">
      <div className="w-96">{jsonData}</div>
    </main>
  );
}
app/page.jsx

Next.js app router provides one of the simplest ways to fetch data on the server side. By default, the fetched data is strongly cached.

javascript

Copy

fetch('https://jsonplaceholder.typicode.com/users/1', { cache: 'no-store' })
// Data is not cached at all

fetch('https://jsonplaceholder.typicode.com/users/1', { next: { revalidate: 3600 } })
// Revalidates the data at most every hour

If you don't want it to cache at all, you can use the first method. If you want your data to be revalidated after a certain time, you can use the second method. For more details, check out this blog.

Next.js comes with various built-in optimizations designed to enhance your application's speed and Core Web Vitals.

Built-in Components Include:

  • Images: Leveraging the native <img> element, the Image Component optimizes images for performance by lazy loading, automatically resizing images based on device size, and reducing image size.
javascript

Copy

import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="profile.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}
  • Link: Utilizing native <a> tags, the Link Component prefetches pages in the background, facilitating faster and smoother page transitions.
javascript

Copy

import Link from 'next/link'
 
export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}
  • Scripts: Built on native <script> tags, the Script Component offers control over the loading and execution of third-party scripts.
javascript

Copy

import Script from 'next/script'
 
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <>
      <section>{children}</section>
      <Script src="https://example.com/script.js" />
    </>
  )
}
  • Font: next/font will automatically optimize your fonts (including custom fonts) and remove external network requests for improved privacy and performance
javascript

Copy

import { Inter } from 'next/font/google'
 
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  )
}

These components simplify optimization for you. You just need to use the tags, and they handle everything else. For instructions on how to use all these components, check out this blog.

Built-in Support for Metadata (SEO)

Metadata is information about your webpage that helps search engines understand your content better, leading to improved SEO (Search Engine Optimization). It also allows you to customize how your content is presented on social media platforms, enhancing user engagement and providing a consistent experience across various platforms.

The Metadata API in Next.js enables you to modify the <head> element of a page. You can configure metadata in two ways:

Static Metadata

javascript

Copy

// simple Metadata
export const metadata: Metadata = {
  title: 'Your webisite title',
  description: 'website desc',
}

To define static metadata, export a Metadata object from a layout.js or static page.js file. You can add this to each route.

javascript

Copy

// advanced Metadata in your main layout file 
export const metadata = {
  metadataBase: new URL(siteMetadata.siteUrl),
  title: {
    template: `%s | ${siteMetadata.title}`,
    default: siteMetadata.title, // a default is required when creating a template
  },
  description: siteMetadata.description,

  openGraph: {
    title: siteMetadata.title,
    description: siteMetadata.description,
    url: siteMetadata.siteUrl,
    siteName: siteMetadata.title,
    images: [siteMetadata.socialBanner],
    locale: "en_US",
    type: "website",
  },
  robots: {
    index: true,
    follow: true,
    // nocache: true,
    googleBot: {
      index: true,
      follow: false,
      noimageindex: true,
      "max-video-preview": -1,
      "max-image-preview": "large",
      "max-snippet": -1,
    },
  },
  twitter: {
    card: "summary_large_image",
    title: siteMetadata.title,
    description: siteMetadata.description,
    images: [siteMetadata.socialBanner],
  },
};

In Metadata, you can also provide Open Graph, robots configuration, and Twitter images as shown in the example above.

Dynamic Metadata

javascript

Copy

// generating Metadata for each dynamically builded Blog
export async function generateMetadata({
  params,
}: {
  params: { slug: string };
}) {
  const data = await getBlogPageData(params.slug);

  return {
    title: data.title,
    description: data.summary,
    openGraph: {
      title: data.title,
      description: data.summary,
      url: siteMetadata.siteUrl + "/blog/" + data.slug,
      siteName: siteMetadata.title,

      locale: "en_US",
      type: "article",
      publishedTime: new Date(data.publishedDate),
      modifiedTime: data.lastEditedAt,
      images: [
        {
          url: data.thumbnail, // Must be an absolute URL
          width: 1200,
          height: 675,
          alt: "thumbnail",
        },
      ],
    },
    author: siteMetadata.author,
    twitter: {
      card: "summary_large_image",
      title: data.title,
      description: data.summary,
      images: [
        {
          url: data.thumbnail,
          width: 1200,
          height: 675,
          alt: "thumbnail",
        },
      ],
    },
  };
}

You can dynamically build metadata for dynamic routes and provide all this configuration as shown in the example above.

To learn how to properly use Metadata in Next.js, please refer to this blog.

Third-Party Libraries Support for Tools Like Google Tag Manager, Google Analytics, Google Maps, and YouTube Embedding

The @next/third-parties library offers a collection of components and utilities that enhance the performance and developer experience of loading popular third-party libraries in your Next.js application.

All third-party integrations provided by @next/third-parties have been optimized for performance and ease of use.

To install the library, use the following command:

bash

Copy

npm install @next/third-parties@latest next@latest

Currently, it supports Google Tag Manager, Google Analytics, Google Maps, and embedding YouTube.

javascript

Copy

import { GoogleAnalytics } from '@next/third-parties/google'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleAnalytics gaId="G-XYZ" />
    </html>
  )
}

In the above code, I have shown you how to easily add Google Analytics. Just insert your Google Analytics ID, and you're all set. For more information on how to use all the tags, please refer to the documentation.

Next.js framework is widely recognized and extensively used in the development community. It boasts robust support and is favored by some of the biggest names on the web, including Notion, Twitch, Nike, Nvidia, Loom, TikTok, Hulu, HBO Max, DoorDash, and many more. And also, this blog website is also built with Next.js

You can explore the impressive showcase of Next.js implementations yourself by visiting

That's why Next.js is considered the best framework and it truly simplifies web development.

💟

That's it for this blog. I wasn't able to cover all of Next.js' features because the list goes on.