-
Notifications
You must be signed in to change notification settings - Fork 1
Next Js
- 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
pagesdirectory in Next.js has been the traditional method for defining routes in a Next.js application. Each file within thepagesdirectory corresponds directly to a route. For example,pages/index.jscorresponds to the root route (/), andpages/about.jscorresponds to the/aboutroute. -
App Directory
The
appdirectory 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} />
);
}