Skip to content

Commit 948cd4c

Browse files
Next Rendering: ISR and SSG
1 parent 216e510 commit 948cd4c

File tree

4 files changed

+163
-2
lines changed

4 files changed

+163
-2
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// getServerSideProps with dynamic pages
2+
// No need of getStaticPaths
3+
// As there are no static paths to regenerate
4+
5+
const UserIdPage = (props) => {
6+
return <h1>{props.id}</h1>;
7+
};
8+
9+
export default UserIdPage;
10+
11+
export const getServerSideProps = async (context) => {
12+
const { uid: userId } = context.params;
13+
14+
return {
15+
props: {
16+
id: `userid-${userId}`,
17+
},
18+
};
19+
};

Nextjs/nextjs-rendering/pages/index.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import fs from "fs";
22
import path from "path";
33

4+
import Link from "next/link";
5+
46
// STATIC
57
// Static HTML files, no data
68

@@ -11,6 +13,12 @@ import path from "path";
1113
// The page is generated during build time
1214

1315
// ISR (Incremental Site Regeneration)
16+
// Static HTML Files + data (regenerated)
17+
// The files are regenerated after X seconds
18+
// After the request
19+
// The page is regenerated after a request only if it's older than X seconds
20+
// "revalidate" property is returned through getStaticProps
21+
// The regeneration takes place on server side
1422

1523
// SSR (Server Side Rendering)
1624

@@ -25,7 +33,9 @@ const Home = (props) => {
2533
{products.map((product) => {
2634
return (
2735
<li key={product.id}>
28-
<h3>{product.title}</h3>
36+
<Link href={`/products/${product.id}`}>
37+
<h3>{product.title}</h3>
38+
</Link>
2939
<p>{product.description}</p>
3040
</li>
3141
);
@@ -35,15 +45,30 @@ const Home = (props) => {
3545
);
3646
};
3747

38-
export const getStaticProps = async () => {
48+
export const getStaticProps = async (context) => {
49+
console.log("regenerating...");
50+
// console.log(context);
3951
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
4052
const jsonData = fs.readFileSync(filePath);
4153
const data = JSON.parse(jsonData);
4254

55+
if (!data) {
56+
return {
57+
notfound: true,
58+
};
59+
}
60+
61+
if (data.products.lenght == 0) {
62+
return {
63+
redirect: {},
64+
};
65+
}
66+
4367
return {
4468
props: {
4569
products: data.products,
4670
},
71+
revalidate: 10,
4772
};
4873
};
4974

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import fs from "fs";
2+
import path from "path";
3+
4+
// getStaticProps Error:
5+
// The getStaticProps funcion gives error when rendering SSG pages with dynamic route
6+
// The dynamic routes indicates that the page should be dynamic
7+
// Whereas the getStaticProps method indicates it is pre-rendered
8+
// This gives error
9+
10+
// Link Prefetching:
11+
// When using <Link> element, Next.js will prefetch props for the linked pages
12+
// And then React will generate it on client side
13+
// This saves time loading the props
14+
// The pre-rendered page will only be served when user directly navigates to the page
15+
// NextJs does this optimization automatically in the backend
16+
17+
// FALLBACK Prop
18+
// The Fallback prop can be used to pre-load only selected paths
19+
// The paths which are not pre-rendered, are rendered just in-time on client
20+
// Which otherwise give 404 error
21+
// The props are loaded at runtime, thus are undefined on intial load
22+
// This must handles
23+
// Thus, this works like standard react code
24+
// The initial page is empty
25+
//
26+
// 'blocking' value
27+
// The third way is to pre-render the page on server
28+
// The props are loaded on server
29+
// And the complete rendered page is sent to the client
30+
// This increases the request time but the user gets to see the complete page
31+
//
32+
// All these features gives flexibility to pre-render pages which are frequently visited
33+
// The rest other pages can be built on time
34+
35+
const ProductDetails = (props) => {
36+
const { product } = props;
37+
38+
if (!product) {
39+
return <p>Loading...</p>;
40+
}
41+
42+
return (
43+
<div>
44+
<h1>Product Details</h1>
45+
46+
<h3>{product.title}</h3>
47+
<p>{product.description}</p>
48+
</div>
49+
);
50+
};
51+
52+
const getData = async () => {
53+
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
54+
const jsonData = fs.readFileSync(filePath);
55+
const data = JSON.parse(jsonData);
56+
57+
return data;
58+
};
59+
60+
export const getStaticProps = async (context) => {
61+
const { pid } = context.params;
62+
63+
const data = await getData();
64+
const product = data.products.find((product) => product.id === pid);
65+
66+
if (!product) {
67+
return {
68+
notFound: true,
69+
};
70+
}
71+
72+
return {
73+
props: {
74+
product: product,
75+
},
76+
};
77+
};
78+
79+
export const getStaticPaths = async (context) => {
80+
const data = await getData();
81+
82+
const ids = data.products.map((p) => p.id);
83+
const pathsWithParams = [ids[0], ids[1]].map((id) => ({
84+
params: { pid: id },
85+
}));
86+
87+
return {
88+
paths: pathsWithParams,
89+
// fallback: false,
90+
fallback: true,
91+
// fallback: "blocking",
92+
};
93+
};
94+
95+
export default ProductDetails;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// getServerSideProps
2+
// The getServerSideProps method executes for each request on server
3+
// It returns same properties as getStaticProps
4+
// The only difference is the timing and "context"
5+
// It has access to various additional properties like request and response
6+
// Which can be used to access things like cookies
7+
8+
const UserProfile = (props) => {
9+
return <h1>{props.username}</h1>;
10+
};
11+
12+
export default UserProfile;
13+
14+
export async function getServerSideProps(context) {
15+
const { params, req, res } = context;
16+
17+
return {
18+
props: {
19+
username: "John Doe",
20+
},
21+
};
22+
}

0 commit comments

Comments
 (0)