Real-world Next.js

Next.js is a Javascript framework for React used for web development. We use the added functionalities of Next.js to build our React components. Unlike React, which uses client-side rendering, Next.js also offers server-side rendering. It can be used as both a frontend and backend framework. Thus we can use it to create API’s. It also allows us to export our website as a static web application. It makes routing easier by allowing file-based routing with the pages directory and the app router.

Next.js also gives us additional components like Link, Image, and Head, which are used for hyperlinks, adding images, or adding tags that can only be inserted in HTML’s head tag, respectively. Styling components is made efficient with added support for Tailwind CSS and CSS-in-JS. Apart from this, it also supports ESLint for enhanced code quality. It’s also SEO-friendly; we don’t require additional third-party tools to optimize our images. We can do this directly within the application.

Getting started with Next.js

We can quickly begin using Next.js in our web applications. All we need is Node.js (16.14 or later) installed. Then, we can manually create a Next.js application and install the required packages or use the create-next-app functionality.

All we have to do is run the following command:

  • cd /usercode/my-nextjs-application && ls are two concatenated commands. The first one, before &&, will take us to our newly created project folder, and the second command, ls, will show the contents of our project.

npx create-next-app@latest && cd /usercode/my-nextjs-application && ls

Before running the following command in the terminal, let’s examine the options to configure our application.

The create-next-app command
The create-next-app command

Once we run the command, the terminal will prompt us to answer a few questions. The default selected options are blue. We can select the defaults or customize our application according to our use case. As shown above, Next.js allows us to integrate TypeScript, ESLint, and Tailwind CSS into our application. We can also opt out of using the Next.js app or page functionality. Instead, we can continue using the src directory within our project’s root folder and place the application code inside. We can answer No to the `src/` directory question if we don’t want that. Otherwise, we can use the app router. If we want to use the pages directory, answer No to the App Router question, and create-next-app will create a pages folder for us.

Now, run the command above to create a Next app. Name the application: my-nextjs-application.

Terminal 1
Terminal
Loading...

Directory structure

After creating our project with all the default configurations, our project directory will look like the image below:

Next.js project directory structure
Next.js project directory structure

Folders/files created by create-next-app are listed below. Let’s review each file and folder:

  • README: This file is crucial to understanding a project, how to start its execution, and what dependencies to install.

  • next-env.d.ts: This is the TypeScript declaration file.

  • node_modules: Installed packages are contained in this folder.

  • package.json: Project dependencies and their versions and scripts to be run are written in this file.

  • public: Static files like images and stylesheets are contained in this folder.

  • tsconfig.json: This is the TypeScript configuration file.

  • app: This folder is the app router. Unlike the pages directory, any page in the app folder would not behave as a route. The client can see only the content returned by page.js or route.js.

  • next.config.js: This is the Next.js configuration file.

  • package.lock.json: This file is automatically generated each time npm modifies the node_modules tree or package.json.

  • postcss.config.json: This is the configuration file for PostCSS.

  • tailwind.config.ts: This is the configuration file configuring Tailwind.

Exploring Next.js features

Next.js provides numerous features to build your web applications with ease. Some of them are given as follows:

Static site generation

Next.js supports static-site generation, which means if a page uses this feature, its HTML will be generated when the app is built. Thus, when we run next build, Next.js will generate an HTML file for this page when this command is run. This HTML can be cached by a CDN and reused on each user request. It greatly improves the speed at which sites are loaded and available to web crawlers and bots for SEO. As discussed below, it’s recommended to use static site generation as much as possible so that a CDN can serve any generated HTML much faster than server-side rendering.

Server-side rendering

Unlike static-site generation, JavaScript sends HTML during runtime from the server to the browser. Next.js can serve as both a frontend and backend framework. With this functionality, we can easily create APIs using Next.js. Moreover, since web applications are rendered on the server, pages load faster and are readily available to web crawlers and bots for SEO. The following code shows a server component inside the page.tsx file in the app router. By default, Next.js uses server-side components.

export default function Home() {
return (
<div> server-side component </div>
)
}

To use client-side components, simply import use client as shown below:

`use client`
export default function Home() {
return (
<div> client-side component </div>
)
}

Routing

Next.js allows for both app routing and routing through the pages directory. React components inside the app folder are server components, but we can also transform them into client components. Both routers fall under file-based routing. A route is defined as nested folders. The following section shows how both types of routing mechanisms are used.

App router

For the app router, a page.tsx file makes all routes publically accessible to the client. Routing can be done by creating folders within the app directory. Each folder will represent a separate path, and the UI to be rendered will be on the page.tsx file for that folder. The following shows the app directory structure. Among the files shown, pages.tsx, layout.tsx, page.module.css, and global.css are autogenerated. The page.tsx file in the root is the home page. layout.tsx files can be used to define a common layout shared between pages, for example, header, footer, or navigation bars. page.module.css is the style sheet for page.tsx present in the root folder. At the same time, global.css is used for defining styles for multiple pages. The about folder below creates a route for the about page of the application. The page.tsx file inside the about folder will render the UI for the about page.

Pages directory

When we route through the pages directory, it makes all pages publically accessible without the need for a page.js file. Any page added in the pages directory will be a valid route and can be accessed from the browser. The general directory structure is shown below. The about.tsx and index.tsx files route to the about and home pages, respectively. While _app.tsx and _document.tsx are auto-generated files. The _app. tsx file is used to override and control page initialization using the app router, for example, to create shared layouts or customize global CSS. The _document.tsx file is a custom document that can be used to update the html and body tags for a page.

Dynamic routing

Routes enable a certain template to be linked to the URL entered by the user in the browser. If the user enters the wrong URL, a 404: This page could not be found error is shown to the user on the browser. This page is automatically routed to wrongly entered URLs. It’s impossible to route all URLs a user can enter in the browser to a UI with static routing. For this purpose, we can use dynamic routing. We can create a page that will be rendered to users for any URL they enter. The following code shows how to implement this. If we run this code, we’ll see the same 404 page, and if we try entering a new URL, say https://ed-5579712711360512.educative.run/my_route or any other, we will still be redirected to the same page. However, if we include nested_route before the my_route segment, we’d see another page that would render the last portion of the dynamic route entered by the user. This nested_route folder holds the [dynamic_route].js file, which enables us to route any dynamic route to this page. Also, note how Next.js allows us to nest our routes within folders, called nested routing. Try it out and make sure that each unique path starts with https://ed5579712711360512.educative.run/nested_route/ . It may take some time to run the code.

import {useRouter } from 'next/router'
const Post = () => {
    const router = useRouter()
    const { dynamic_route } = router.query
    return <h1> Post : {dynamic_route}</h1>
}
export default Post

//without this file we will get a 404 page 
// since we set a dynamic route, now any path entred will redirect us to this page

The Head, Link, and Image components

Next.js provides us with multiple components that can be used instead of plain HTML for rendering. We’ll discuss the Head, Link, and Image components.

The Head component

Next.js provides the head components to include any tags that can only be added to the head of any HTML document, for example, linking stylesheets or javascript files. The following code shows how the head tag can be used inside components.

The Script component

The Script component extends the HTML script tag. With the added feature of adding a strategy property. This property allows you to tweak the behavior of how any third-party scripts will be loaded on the page. it can take on the following values:

  • beforeIntercative: Script is loaded before any Next.js code is executed or any page hydrationThe process of moving any server-side HTML to the client side. occurs.

  • afterInteractive: This is the default property value and will load the script only after some hydration has taken place.

  • lazyOnload: The script is loaded during the browser's idle time.

  • worker: The script is loaded in a web worker.

The Link component

The Link component is used as a substitute for the a tag in HTML for hyperlinks.

The Image component

This component is used for rendering images to the browser. It’s used in place of the img tag in HTML. The following code shows how to use each one of these components inside a React component.

You might wonder, why do we need these HTML alternates. The answer to this is, they make our site SEO-friendly. The Image component displays images using modern image formats like WebP or AVIF so that they are correctly sized for each device. It also prevents layout shifts during image loading and allows for faster page uploads. The Script components strategy the property allows us to set how the browser loads third-party scripts which can boost performance. The Link component speeds up loading by prefetching any links before the user clicks on them.

import Head from 'next/head'
import Script from 'next/script'
import Image from 'next/image'
import Link from 'next/link'
export default function Home() {
return (
<>
<Head>
<title>Educative</title>
</Head>
<Script strategy="lazyOnload">
alert("welcome to my application");
</Script>
<Image src="/Next.png" alt=" Next Logo" width={700} height={300} />
<Link href="/folder1/homepage" >
back to home
</Link>
</>
)
}
  • Lines 1–4: The Head, Script, Image, and Link components are imported in the first four lines. Line 2 defines a React component called Home.

  • Lines 6–11: Inside the component a Head tag is used to set the title property of the home page.

  • Lines 12–14: These lines show how to use the Script tag. The strategy is set to lazyOnload. With this, when the page is rendered, an alert box will display a message to the user.

  • Line 15: This line shows how to use the Image component. It's used in the same way as the img tag in HTML. We have mentioned the image source in src , alternate text using alt and the width and height of the image have also been set in the same using width and height properties.

  • Lines 16–8: These lines use the Link component. Note that these components are alternates to their HTML variants and thus have been used in the same manner. To specify the URL path, we use href and write the hyperlinked text within the Link component.

The following is a complete Next.js web application with most of the features discussed above practically demonstrated. Routing has been implemented using the pages directory. You can see the directory structure, which contains all folders except the node modules. Tweak the code as you like, and then press the “Run” button. The server will take a few minutes for the node modules to install and then be up and running.

import Head from 'next/head'
import Script from 'next/script'
import Image from 'next/image'
import styles from '@/styles/Home.module.css'
import Navbar from './components/navbar'

export default function Home() {
  return (
    <>
      <Head>
        <title>Educative</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </Head>
      <Script strategy="lazyOnload">
        alert("welcome to my application");
      </Script>
      <div className={styles.main_body}>
            <Navbar />
            <div className={styles.banner}>
              <h1> Welcome to Educative's Next.js App</h1>
            </div> 
            <div className={styles.next_properties}>
                  <div className={styles.image}>
                            <Image
                              src="/Next.png"
                              alt="Educative's App"
                              width={700}
                              height={300}                     
                            />
                  </div>
            </div>
      </div>   
    </>
  )
}

Free Resources

HowDev By Educative. Copyright ©2025 Educative, Inc. All rights reserved