nextjsreacttutorial

Installation of Next.js - App Router (app/)

A comprehensive guide to installation of Next.js - App Router (app/)

April 7, 20256 min read
Installation of Next.js - App Router (app/)

Next.js is a React framework for building full-stack web applications. Learn more at nextjs.org/docs.

Why Use a Framework?

A framework like Next.js provides pre-defined routes that enable fast communication between the server (SSR - Server Side Rendering) and the client (CSR - Client Side Rendering). You also avoid complications related to connecting your pages.

Your full-stack web application should be fast, scalable, stable, and secure.

Prerequisites

We will use Windows, Command Prompt, and VSCode for this tutorial.

Getting Started

In Command Prompt, navigate to the folder where you want to build your project and run:

npx create-next-app@latest

You'll see the following prompts during installation:

QuestionMy AnswerWhy
What is your project named?my-appChoose any name you like
Use TypeScript?YesImproves code quality, prevents bugs, and is industry standard
Use ESLint?YesHelps you write cleaner, consistent code
Use Tailwind CSS?YesAwesome for fast UI building and responsiveness
Use src/ directory?YesKeeps your project structure organized and scalable
Use App Router?YesThe future of Next.js - supports layouts, loading states, and server components
Use Turbopack?NoStill experimental - stick with Webpack for now
Customize import alias?YesCleaner imports: @/components/Button instead of ../../../components/Button

For the last question about import alias configuration, just press Enter to accept the default @/*.

Then navigate to your project and install dependencies:

cd my-app
npm install
code .

Note: This installs the latest versions of Next.js, React, TypeScript, and Tailwind CSS.

Caution: Tailwind 4.x is significantly different from previous 3.x versions!

Project Structure

After installation, you'll have:

Note: at the time the article was written, the current version for Next was 15.2.4; now it is 16.x.x

NextJS folder file structure

  • src/app/page.tsx — Home page (equivalent to pages/index.tsx in Pages Router)
  • src/app/layout.tsx — Root layout (equivalent to pages/_app.tsx in Pages Router)
  • src/app/globals.css — Global styles with Tailwind imported as @import "tailwindcss";

Tip: If your imports show red squiggly lines in VSCode, add .tsx to the end of the import path and then remove it. This refreshes the TypeScript language server.

Building the Application

We'll add three pages and three components.

Pages

src/app/page.tsx (Home)

export default function HomePage() {
  return (
    
      Welcome to My App
      This is the home page built with Next.js App Router and Tailwind CSS.
    
  )
}

src/app/intro/page.tsx

export default function IntroPage() {
  return (
    
      Introduction
      Here you can introduce yourself, your project, or your company.
    
  );
}

src/app/about/page.tsx

export default function AboutPage() {
  return (
    
      About
      This is the about page. Talk about your mission, vision, or background.
    
  );
}

src/app/contact/page.tsx

import ContactForm from '@/components/form/ContactForm'

export default function ContactPage() {
  return (
    
      Contact Us
      Feel free to reach out by filling the form below.
      
    
  )
}

Layout

src/app/layout.tsx

import './globals.css'
import type { Metadata } from 'next'
import Header from '@/components/Header'
import Footer from '@/components/Footer'

export const metadata: Metadata = {
  title: 'My App',
  description: 'Built with Next.js App Router',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    
      
        
        {children}
        
      
    
  )
}

Note: Red squiggly lines for Header and Footer imports will disappear once you create those component files.

Components

Create a components folder inside src, then add the following files.

src/components/Header.tsx

"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";

export default function Header() {
  const pathname = usePathname();

  const navItems = [
    { href: "/", label: "Home" },
    { href: "/intro", label: "Intro" },
    { href: "/about", label: "About" },
    { href: "/contact", label: "Contact" },
  ];

  return (
    
      
        MyApp
        
          {navItems.map((item) => (
            
              <Link
                href={item.href}
                className={`hover:underline ${
                  pathname === item.href ? "text-yellow-400" : ""
                }`}
              >
                {item.label}
              
            
          ))}
        
      
    
  );
}

src/components/Footer.tsx

export default function Footer() {
  return (
    
      &copy; {new Date().getFullYear()} MyApp. All rights reserved.
    
  );
}

src/components/form/ContactForm.tsx

"use client";

import { useState } from "react";

export default function ContactForm() {
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    message: "",
  });

  const handleChange = (
    e: React.ChangeEvent
  ) => {
    const { name, value } = e.target;
    setFormData((prev) => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log("Form submitted:", formData);
    alert("Message sent!");
    setFormData({ name: "", email: "", message: "" });
  };

  return (
    
      
        Name
        
      

      
        Email
        
      

      
        Message
        
      

      
        Send Message
      
    
  );
}

As your project grows, organize components like this:

components/
├── ui/
│   ├── Button.tsx
│   ├── Input.tsx
│   └── Spinner.tsx
├── layout/
│   ├── Layout.tsx
│   └── Sidebar.tsx
├── nav/
│   ├── Header.tsx
│   ├── Footer.tsx
│   └── MobileMenu.tsx
├── forms/
│   ├── LoginForm.tsx
│   └── ContactForm.tsx
└── icons/
    └── SearchIcon.tsx

Common component categories include UI/reusable elements, layout components, navigation, form components, specialized widgets, icons, themed components, and transition components (using Framer Motion or GSAP).

Working with Assets

Images

Place images in public/images/ and reference them directly:

Or use the optimized next/image component:

import Image from 'next/image';


Fonts

Place custom fonts in public/fonts/ and register them in src/app/globals.css:

@font-face {
  font-family: 'Fira Code';
  src: url('/fonts/FiraCode-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

body {
  font-family: 'Fira Code', monospace;
}

Running Your Application

Open the terminal in VSCode and run:

npm run dev

You should see:

▲ Next.js 15.2.4
- Local:        http://localhost:3000
- Network:      http://192.168.1.12:3000

✓ Ready in 1578ms

Open http://localhost:3000 in your browser to see your app.

Troubleshooting Hydration Errors

If you see a red hydration notice, it's likely caused by a browser extension injecting attributes into the DOM.

Why This Happens

Next.js SSR outputs clean HTML, but browser extensions (password managers, ad blockers, dark mode tools) may inject attributes like cs-shortcut-listen="true". When React hydrates on the client, it detects a mismatch between server and client HTML.

How to Confirm

Open an incognito window or disable all extensions, then reload your app. If the error disappears, an extension is the culprit.

Common Culprits

Password managers (LastPass, 1Password), ad blockers, dark mode extensions (Dark Reader), accessibility tools, and dev tool plugins.

Solutions

Disable the extension during development, test in a browser profile without extensions, or simply ignore the warning if it only appears in your development environment with extensions enabled.


Your layout code is fine. The mismatch comes from injected attributes by browser extensions, not from your application code.