- vừa được xem lúc

Combining client side and server side rendering on same page using next.js

0 0 76

Người đăng: Sirajus Salekin

Theo Viblo Asia

We can easily create Client rendered pages (CSR) and Static generated pages (SG) using Next.js. But, often times, you'll want your page to use a combination of those different rendering methods. Like, you want your static page to be generated with some data from api, then once the users browser has hydrated the static page, you want CSR to kick in. There is one way we can use this, by using the excellent SWR plugin from Vercel (`creators of Next.js). Let's have a quick look about it in this article.

First, let's create a next app by running

npx create-next-app blog-swr-demo -y

Now we need to create a mock api to serve us articles/posts. Let's create a new file in pages/posts.js and paste in

export default (req, res) => { res.status(200).json({ posts: [ {title: "A", content: "asdf"}, {title: "B", content: "qwert"}, {title: "C", content: "zxcv"}, {title: "D", content: "mnopq"}, {title: "E", content: "aeiou"} ] }) }

Now, we'll install the SWR plugin

npm i swr

And create our blog component and also import the useSWR hook from the plugin we just installed

import useSWR from "swr" export default function Blog() { return ( <div> Demo blog { posts.map((post) => <h4>{post.title}</h4> <p>{post.content}</p> ) } </div> )
}

Now, let's render the blog posts using the useSWR hook

import useSWR from "swr" async function fetcherFunc(url) { const res = await fetch(url); return res.json();
} export default function Blog() { const url = "http://localhost:3000/api/posts"; const {data, error} = useSWR(url, fetcherFunc); if (!data) return <div>fetching</div> const {posts} = data; return ( <div> Demo blog { posts.map((post) => <div> <h4>Article: {post.title}</h4> <p>{post.content}</p> <br/> </div> ) } </div> )
}

Now let's create the static generated file for our page, for this we'll modify our code like

export default function Blog(props) { // <<<<<<< changed here
// const url = "http://localhost:3000/api/posts";
// const {data, error} = useSWR(url, fetcherFunc);
// if (!data) return <div>fetching</div> const {posts} = props; // <<<<<<<< Also here return ( <div> Demo blog { posts.map((post) => <div> <h4>Article: {post.title}</h4> <p>{post.content}</p> <br/> </div> ) } </div> )
} export async function getStaticProps(context) { const res = fetch("http://localhost:3000/api/posts"); const posts = await (await res).json() return { props: { posts } }
}

Let's generate the page. For that run

npm run build

You'll see this after it's successfully built

> _@.com build
> next build info - Creating an optimized production build info - Compiled successfully
info - Collecting page data info - Generating static pages (4/4)
info - Finalizing page optimization Page Size First Load JS
┌ ○ / 3.46 kB 66.9 kB
├ └ css/c50ddf22b716c7b6b76d.css 660 B
├ /_app 0 B 63.4 kB
├ ○ /404 3.46 kB 66.9 kB
├ λ /api/hello 0 B 63.4 kB
├ λ /api/posts 0 B 63.4 kB
└ ● /blog 1.96 kB 65.4 kB
+ First Load JS shared by all 63.4 kB ├ chunks/e82d01500e11e0131e78851aa17fd9f5e63d6c88.ebefd9.js 2.47 kB ├ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.519eb7.js 11.3 kB ├ chunks/framework.e2fe4a.js 41.8 kB ├ chunks/main.1a4cca.js 6.67 kB ├ chunks/pages/_app.6b4817.js 531 B ├ chunks/webpack.50bee0.js 751 B └ css/6e9ef204d6fd7ac61493.css 194 B λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
○ (Static) automatically rendered as static HTML (uses no initial props)
● (SSG) automatically generated as static HTML + JSON (uses getStaticProps) (ISR) incremental static regeneration (uses revalidate in getStaticProps)

Note, the if we keep adding posts to our mock api while our blog is running, the data doesn't get refreshed. We need to reload the page to do that

Let's fix that now. For that, we will pass the revalidateOnMount option in our useSWR hook So, the final code will be

import useSWR from "swr" async function fetcherFunc(url) { const res = await fetch(url); return res.json();
} export default function Blog(props) { const url = "http://localhost:3000/api/posts"; const {data, error} = useSWR(url, fetcherFunc, {initialData: props, revalidateOnMount: true }); const {posts} = data; if (!posts) return <div>fetching</div> return ( <div> Demo blog { posts.map((post) => <div> <h4>Article: {post.title}</h4> <p>{post.content}</p> <br/> </div> ) } </div> )
} export async function getStaticProps(context) { const res = fetch("http://localhost:3000/api/posts"); const {posts} = await (await res).json() return { props: { posts } }
}

Let's check

Source code

https://github.com/Salekin-1169/blog-swr-demo

Learning Material

The official docs (obviously)

Bình luận

Bài viết tương tự

- vừa được xem lúc

Viết một chiếc app quản lý Hạn sử dụng của thực phẩm

Mở đầu. Tôi là 1 kỹ sư công nghệ thông tin mới ra trường. Trong thời gian học Đại học, từ năm 1 tới năm 4, tôi đi làm thêm tại TSUTAYA (chuỗi cửa hàng bán sách, video...v.v nổi tiếng bên Nhật). Về chiếc App tôi đã phát triển. App tôi phát triển là Web App giúp quản lý hạn sử dụng của đồ ăn.

0 0 40

- vừa được xem lúc

Routing trong Next.js

Trước đó bạn có thể đang tò mò về Next.js, vào đây luôn bạn ơi. (go). .

1 0 44

- vừa được xem lúc

Cài đặt chuyển đổi ngôn ngữ trong một project NextJS

Ở phiên bản Nextjs Version 10 mới đây, việc sử dụng i18n đã trở nên dễ dàng hơn qua tính nâng cao là Internationalized Routing. Cài đặt cấu hình cơ bản. Tại file next.config.

0 0 55

- vừa được xem lúc

Cấu hình eslint airbnb, prettier cho dự next.js sử dụng typescript

Chào mọi, mình đã quay lại đây. Hôm nay mình sẽ đem đến một chủ đề linter cụ thể cấu hình eslint cho dự án next.

0 0 177

- vừa được xem lúc

Handling custom page navigation on Next.js

Last month we discussed about different kind of routing on Next.js. Here's a short example of creating a component that moves the user to next page. import { useRouter } from 'next/router'.

0 0 71

- vừa được xem lúc

Next Image một feature, một nâng cấp tuyệt vời version nextjs 10

NextJS đã cho ra mắt version 10 cách đây 2 tháng với hơn 20 fearture nâng cấp đáng giá. Chúng ta có thể kể ra những features nổi bật như. . Next/Image: với khẳ năng render image cho các kích thước màn hình tương ứng.

0 0 49