Ayyo, What’s up man!!
Hi guys, we’re back to the next topic in this Next.js Series which is Pre-rendering and Data Fetching in Next.js, and in the first post of Pre-rendering and Data Fetching, we’ll find Learn more about Static Generation.
1. What is pre-rendering?
- Pre-rendering: Next.js will pre-generate the HTML for each page, instead of all being done in the client like Reactjs.
- There are 2 types of Pre-rendering: Static generation and Server-side rendering
- Static generation: The HTML will be generated all at the beginning and used each request.
- Server-side rendering: HTML will be generated each request.
- Pre-rendering helps our website have better performance and SEO ability
2. Static Generation
- Is a Pre-rendering method where HTML will be generated at build time (created at the beginning).
- The HTML along with all the data that makes up the content of the web page is generated before, when you build your application.
- Is the method recommended by Next.js to use
- Our website is cached by the CDN and made available to users almost instantaneously.
- Suitable for websites: blogs, docs, marketing, e-commerce product pages,…
2.1 Static Generation without data
- In case the page is created without getting data from the outside (API, file system, …), the pages will be generated right from the buildtime.
2.2 Static Generation with data
- Not always our pages are just HTML without data from outside, you may need to get data from 3rd party API, or get from file system, … and Next.js also always support.
Static Generation with Data using getStaticProps
- It works very simply, when you export a page component, you can also export an
async
function called getStaticProps :getStaticProps
will run at build time- In this function you can call 3rd party API to get data
- Code it will look like this
1 2 3 4 5 6 7 8 9 10 11 12 | export default function Home(props) { ... } export async function getStaticProps() { // Lấy data từ bên ngoài (API, file, ...) const data = ... // Giá trị của props kia sẽ được truyền vào component Home return { props: ... } } |
- Roughly we can understand this code will be that
getStaticProps
will tell Next.js
12 Này, Page này có 1 số data lấy từ bên ngoài, khi mà bạn pre-render lúc build time, bạn nhớ xử lý để mà trang Home kia lấy được sử dụng nhé.
Complete example: Here I create a file pages/post/index
, in which I will call the API https://jsonplaceholder.typicode.com/posts
to get the data in the function getStaticProps
, return an object props as posts: data
, in the PostList
component I get the posts
props, this is just like normal React and uses posts
to render a list of posts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import Link from 'next/link' function PostList({ posts }) { return ( <> <h1>List of Posts</h1> {posts.map(post => { return ( <div key={post.id}> <Link href={`posts/${post.id}`}> <h2> {post.id} {post.title} </h2> </Link> <hr /> </div> ) })} </> ) } export default PostList export async function getStaticProps() { const response = await fetch('https://jsonplaceholder.typicode.com/posts') const data = await response.json() return { props: { posts: data } } } |
Static Generation with Dynamic Parameters
- Example: Another case is when there is a list of posts, we will need to go to that post details, usually we will use the id of that post and get the post details, but that id called Dynamic Parameters
- Take a look at the code below to better understand how to get data with Dynamic Parameters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // pages/posts/[postId].js function Post({ post }) { return ( <> <h2> {post.id} {post.title} </h2> <p>{post.body}</p> </> ) } export default Post export async function getStaticProps(context) { const { params } = context const response = await fetch( `https://jsonplaceholder.typicode.com/posts/${params.postId}` ) const data = await response.json() return { props: { post: data } } } |
- We create the file
pages/posts/[postId].js
here we will have thepostId
which is the params id of each post, this is Dynamic Parameters, the above code is in.getStaticProps
adds a params ofcontext
, and from there we can get thepostId
to fetch the data of the post with the id above the path, the rest is still the same as the example above. - Let’s try to run the above code. Opps is wrong
- Now Next.js requires us to add
getStaticPaths
, here, if you want to use Dynamic Parameters withgetStaticProps
, you need to define the generated paths in advance, for example I get a list of posts, I want to get the data only Details of each post by id, I will need to declare the list of post id in advance ingetStaticPaths
for example:
1 2 3 4 5 6 7 8 | // Generates `/posts/1` and `/posts/2` export async function getStaticPaths() { return { paths: [{ params: { postId: '1' } }, { params: { postId: '2' } }], fallback: false, // can also be true or 'blocking' } } |
- How many posts there are, the other
paths
will have that same id, just add the abovegetStaticPaths
to thepages/posts/[postId].js
file and we can run without error. - Now I will edit the full file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import { useRouter } from 'next/router' function Post({ post }) { const router = useRouter() if (router.isFallback) { return <div>Loading...</div> } return ( <> <h2> {post.id} {post.title} </h2> <p>{post.body}</p> </> ) } export default Post export async function getStaticProps(context) { const { params } = context const response = await fetch( `https://jsonplaceholder.typicode.com/posts/${params.postId}` ) const data = await response.json() if (!data.id) { return { notFound: true } } return { props: { post: data } } } export async function getStaticPaths() { const response = await fetch('https://jsonplaceholder.typicode.com/posts') const data = await response.json() const paths = data.map(post => { return { params: { postId: `${post.id}` } } }) return { paths: paths, fallback: true } } |
- And now we can see the details of the post.
- In the above code you will see that the return section at
getStaticPaths
has afallback
, so what isfallback
? We will learn aboutfallback
ingetStaticPaths
too.
getStaticPaths
and fallback
- fallback has 3 values:
- fallback: false
- fallback: true
- fallback: ‘blocking’
- Learn more at: https://nextjs.org/docs/api-reference/data-fetching/get-static-paths#fallback-blocking
2.3 Some notes about getStaticProps
- Note 1:
getStaticProps
only runs on the server side- This function will never run on the client side
- The code written in
getStaticProps
won’t even equal the js bundle sent to the browser
- Note 2:
- Can write server side code directly in
getStaticProps
- Can perform file system access or database query in
getStaticProps
- You also don’t have to worry about exposing the API key in
getStaticProps
because it won’t be sent back to the browser
- Note 3:
getStaticProps
will only work inpages
but not in normal components- It is used for pre-rendering and not used for fetching data on the client-side
- Note 4:
getStaticProps
must return 1 object and the object must contain props key which is 1 object- In the above example, I return an object with key props and in props is an object with the key being
posts
- Note 5:
getStaticProps
will run build time- But when developing locally,
getStaticProps
runs every time it is requested.
2.4 Some notes about getStaticPaths
- You should use
getStaticPaths
if you are pre-rendering static pages and using dynamic routes and data returned from headless CMS, database, getStaticPaths
must be used withgetStaticProps
.- You cannot use
getStaticPaths
withgetServerSideProps
. - You can export
getStaticPaths
from Dynamic Route also usinggetStaticProps
. - You cannot export getStaticPaths from a non-page file (e.g.
components
folder). - You must export getStaticPaths as a standalone function and not as a property of the page component.
3. Summary
- I finally wrote quite a bit to share with everyone about Pre-rendering and Data Fetching, with the first part about Static Generation (SSG), about
getStaticProps
andgetStaticPaths
- You can read more from Next.js docs to learn more
- In the next part, I will share about server-side rendering in Next.js
I have a reference on the official website of Next.js and the Youtube channel Codevolution
Thank you for watching, looking forward to receiving your comments for better knowledge and articles!