Back to Blog

March 15, 2024
Next.js has become one of the most popular React frameworks for building modern web applications. In this guide, we'll explore the key features that make Next.js an excellent choice for your next project and walk through setting up a basic application.
Let's start by creating a new Next.js project. Open your terminal and run:
npx create-next-app@latest my-next-app
cd my-next-app
npm run devThis will create a new Next.js project with TypeScript, ESLint, and Tailwind CSS configuration. The development server will start at http://localhost:3000.
A typical Next.js project structure looks like this:
my-next-app/
├── app/
│ ├── layout.tsx
│ ├── page.tsx
│ └── globals.css
├── public/
│ └── assets/
├── components/
├── package.json
└── next.config.jsNext.js 13+ uses the App Router, which is based on the file-system. Here's how to create basic routes:
// app/page.tsx
export default function Home() {
return (
<main>
<h1>Welcome to Next.js!</h1>
</main>
);
}To create nested routes, simply create folders in the app directory:
app/
├── page.tsx // → /
├── about/
│ └── page.tsx // → /about
└── blog/
└── [slug]/
└── page.tsx // → /blog/post-1, /blog/post-2Next.js provides several ways to fetch data in your applications:
// Server Component
async function getData() {
const res = await fetch('https://api.example.com/data');
if (!res.ok) throw new Error('Failed to fetch data');
return res.json();
}
export default async function Page() {
const data = await getData();
return <main>{/* Render data here */}</main>;
}API routes allow you to build backend endpoints within your Next.js app.
// pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from 'next';
export default function handler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ message: 'Hello from Next.js API Route!' });
}The Next.js Image component automatically optimizes images for size and performance.
import Image from 'next/image';
export default function Avatar() {
return (
<Image
src="/me.png"
alt="My Avatar"
width={200}
height={200}
placeholder="blur"
/>
);
}Middleware runs before requests are processed, useful for authentication, redirects, and rewriting URLs.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
if (!request.nextUrl.pathname.startsWith('/api')) {
// perform logic
}
return NextResponse.next();
}ISR allows you to update static pages after build without a full rebuild.
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60, // Revalidate every 60 seconds
};
}Store sensitive config in .env.local and prefix public vars with NEXT_PUBLIC_.
// .env.local
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgres://user:pass@localhost:5432/dbNextAuth makes adding authentication and OAuth providers straightforward.
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';
export default NextAuth({
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID!,
clientSecret: process.env.GITHUB_SECRET!,
}),
],
});Enable locale routing with built-in i18n support in next.config.js.
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'es'],
defaultLocale: 'en',
},
};Monitor Lighthouse scores, use React Profiler, and analyze bundle size via webpack-bundle-analyzer.
Deploy your Next.js app seamlessly with Vercel CLI or through Git integration.
npm install -g vercel
vercel login
vercel --prodNext.js combines powerful features with an easy developer experience. Explore these sections to build scalable, high-performance web apps.