Get ready for your next interview with our comprehensive question library
Next.js uses a file-based routing system where the file structure in the pages
directory (or app
directory in App Router) automatically creates routes:
pages/
index.js → /
about.js → /about
contact.js → /contact
blog/
index.js → /blog
[slug].js → /blog/:slug
Each file exports a React component as the default export, which becomes the page component for that route.
The _app.js
file is a custom App component that wraps all page components. It's used to:
function MyApp({ Component, pageProps }) {
return (
<div>
<GlobalHeader />
<Component {...pageProps} />
<GlobalFooter />
</div>
);
}
export default MyApp;
Global CSS can only be imported in _app.js
:
// pages/_app.js
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
CSS Modules allow you to write component-scoped CSS by creating files with .module.css
extension:
/* Button.module.css */
.primary {
background-color: blue;
color: white;
}
// Button.js
import styles from './Button.module.css';
function Button() {
return <button className={styles.primary}>Click me</button>;
}
The public
directory serves static assets directly from the root URL. Files in this directory can be accessed without any path prefix:
public/
favicon.ico → /favicon.ico
logo.png → /logo.png
images/
hero.jpg → /images/hero.jpg
Dynamic routes are created using square brackets in the filename:
pages/
posts/
[id].js → /posts/:id
[...slug].js → /posts/* (catch-all)
// pages/posts/[id].js
import { useRouter } from 'next/router';
function Post() {
const router = useRouter();
const { id } = router.query;
return <h1>Post: {id}</h1>;
}
export default Post;
Link
: Declarative navigation component for client-side transitionsrouter.push()
: Programmatic navigation methodimport Link from 'next/link';
import { useRouter } from 'next/router';
function Navigation() {
const router = useRouter();
const handleClick = () => {
router.push('/about');
};
return (
<div>
<Link href="/about">About Page</Link>
<button onClick={handleClick}>Go to About</button>
</div>
);
}
getStaticProps
fetches data at build time for static generation:
export async function getStaticProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: {
posts,
},
revalidate: 3600, // ISR: revalidate every hour
};
}
function Blog({ posts }) {
return (
<div>
{posts.map(post => (
<article key={post.id}>{post.title}</article>
))}
</div>
);
}
Use when: Content is static or changes infrequently, for better performance and SEO.
getServerSideProps
fetches data on each request at runtime:
export async function getServerSideProps(context) {
const { req, res, params, query } = context;
const data = await fetch(`https://api.example.com/user/${params.id}`);
const user = await data.json();
return {
props: {
user,
},
};
}
Use when: Data changes frequently, requires authentication, or needs request-specific information.
Use standard React patterns like useEffect
or data fetching libraries:
import { useState, useEffect } from 'react';
function Profile() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/user')
.then(res => res.json())
.then(data => {
setUser(data);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
return <div>Welcome, {user.name}!</div>;
}
Use the 'use client'
directive at the top of the file:
'use client';
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
Create a loading.js
file to show loading UI while the page loads:
// app/posts/loading.js
export default function Loading() {
return <div>Loading posts...</div>;
}
// app/posts/page.js
async function PostsPage() {
// This delay will show the loading component
await new Promise(resolve => setTimeout(resolve, 2000));
const posts = await fetch('/api/posts');
return <PostsList posts={posts} />;
}
Create files in the pages/api/
directory (Pages Router) or app/api/
directory (App Router):
Pages Router:
// pages/api/users.js
export default function handler(req, res) {
if (req.method === 'GET') {
res.status(200).json({ users: [] });
} else {
res.setHeader('Allow', ['GET']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
App Router:
// app/api/users/route.js
export async function GET() {
return Response.json({ users: [] });
}
export async function POST(request) {
const data = await request.json();
// Process data
return Response.json({ success: true });
}
Upgrade to Premium to see the answer
Upgrade to PremiumUpgrade to Premium to see the answer
Upgrade to PremiumUpgrade to Premium to see the answer
Upgrade to PremiumUpgrade to Premium to see the answer
Upgrade to PremiumUpgrade to Premium to see the answer
Upgrade to PremiumUpgrade to Premium to see the answer
Upgrade to PremiumAccess all premium content - interview questions, and other learning resources
We regularly update our features and content, to ensure you get the most relevant and updated premium content.
1000 monthly credits
Cancel anytime