Next Js - AdarshTheki/mern-stack-learn GitHub Wiki
- Pages Directory vs. App Directory
- Key Differences
- Client-Side Rendering (CSR)
- Server-Side Rendering (SSR)
- Static Site Generation (SSG)
- Error Handling
- Image Optimization
-
Pages Directory
The
pages
directory in Next.js has been the traditional method for defining routes in a Next.js application. Each file within thepages
directory corresponds directly to a route. For example,pages/index.js
corresponds to the root route (/
), andpages/about.js
corresponds to the/about
route. -
App Directory
The
app
directory is a newer addition to Next.js, introduced to enable more granular control over routing and component organization.
Feature | Pages Directory | App Directory |
---|---|---|
Routing | File-based, automatic | File-based, more modular |
Rendering | Client/Server/Static | Client/Server Components |
Custom Components |
_app.js , _document.js
|
Custom layouts and templates |
Data Fetching |
getStaticProps , getServerSideProps
|
Server Components, useSWR
|
Use Case | Simple to medium complexity | More complex applications |
In CSR, data fetching happens on the client side after the initial page load. The useSWR
hook is used here to handle fetching with Stale-While-Revalidate strategy.
import useSWR from 'swr';
const fetcher = (...args) => fetch(...args).then((res) => res.json());
export default function App() {
const { data, error } = useSWR('/api/link', fetcher);
if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
// Render the fetched data
}
In SSR, data is fetched on the server for each request, and the HTML is generated on the server with the fetched data.
// (SSR) Server Side Render to fetch data
export async function getServerSideProps() {
const data = await (await fetch('https://dummyjson.com/products?limit=10')).json();
return {
props: {
data,
},
};
}
In SSG, the HTML is generated at build time, and it can be statically served. Dynamic routes can also be handled using getStaticPaths
.
- Get all ids:
getStaticPaths()
- Get dynamic id to fetch data:
getStaticProps()
// app/users/[id]/page.js
export async function getStaticPaths() {
const data = await (await fetch(`https://dummyjson.com/products`)).json();
const users = data.products.map((item) => item.id);
return {
paths: users.map((userId) => ({ params: { id: `${userId}` } })),
fallback: false,
};
}
export async function getStaticProps({ params }) {
const data = await (await fetch(`https://dummyjson.com/products/${params.id}`)).json();
return {
props: {
data,
},
};
}
Next.js provides a built-in Error
component to handle errors gracefully in the application. You can return an error code from getStaticProps
or getServerSideProps
and render the Error
component based on that.
import Error from 'next/error';
export async function getStaticProps() {
const res = await fetch('/api/data');
const errorCode = res.ok ? false : res.status;
const data = await res.json();
return { props: { errorCode, data } };
}
export default function App({ errorCode, data }) {
if (errorCode) return <Error statusCode={errorCode} />;
return <div>Data {JSON.stringify(data)}</div>;
}
-
Next.js Image Configuration :
next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
pathname: '/**',
},
],
},
};
- Custom Image Loader
'use client';
const imageLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
};
export default function Page() {
return (
<Image loader={imageLoader} src='me.png' alt='Picture of the author' width={500} height={500} />
);
}