SSR + Paginated Home Page Feed Render a feed of the latest posts with a collectionGroup query This lesson is available for PRO members or as a single course purchase. Sign-in and choose a plan below. SignUp for Unlimited PRO Access OR *Enrollment provides full access to this course (and updates) for life. đŧ Login to Watch đ SSR User Profile Page ISR Incremental Static Regeneration đ Firebase Lib Use this function to convert a Firestore timestamp to a number. file_type_js_official lib/firebase.js export const fromMillis = firebase.firestore.Timestamp.fromMillis; Home Page Post Feed The first batch is rendered on the server, while all subsequent queries are executed clientside. file_type_js_official pages/index.js import PostFeed from '../components/PostFeed'; import Loader from '../components/Loader'; import { firestore, fromMillis, postToJSON } from '../lib/firebase'; import { useState } from 'react'; // Max post to query per page const LIMIT = 1; export async function getServerSideProps(context) { const postsQuery = firestore .collectionGroup('posts') .where('published', '==', true) .orderBy('createdAt', 'desc') .limit(LIMIT); const posts = (await postsQuery.get()).docs.map(postToJSON); return { props: { posts }, // will be passed to the page component as props }; } export default function Home(props) { const [posts, setPosts] = useState(props.posts); const [loading, setLoading] = useState(false); const [postsEnd, setPostsEnd] = useState(false); const getMorePosts = async () => { setLoading(true); const last = posts[posts.length - 1]; const cursor = typeof last.createdAt === 'number' ? fromMillis(last.createdAt) : last.createdAt; const query = firestore .collectionGroup('posts') .where('published', '==', true) .orderBy('createdAt', 'desc') .startAfter(cursor) .limit(LIMIT); const newPosts = (await query.get()).docs.map((doc) => doc.data()); setPosts(posts.concat(newPosts)); setLoading(false); }; return ( <main> <PostFeed posts={posts} /> {!loading && !postsEnd && <button onClick={getMorePosts}>Load more</button>} <Loader show={loading} /> {postsEnd && 'You have reached the end!'} </main> ); } Chapters Prerequisites đ¨ 1 README Watch this video before starting the course! free 2:12 âī¸ 2 React Basics Learn the fundamentals of React.js and reactive UI development free 13:15 đĨ 3 Firebase Basics Learn the fundamentals of Firebase Authentication, Firestore, and Storage free 25:22 đšī¸ 4 Next.js Basics Learn the fundamentals of Next.js and server-side rendering free 11:50 App đ§Ŧ 5 Technical Overview Blueprint and technical decisions behind the app free 4:47 đģ 6 Next.js Setup Setup a Next.js app and explore the file system 5:41 đ¤ 7 TypeScript Setup Next.js with TypeScript (optional) 2:07 đĨ 8 Firebase Setup Install and configure Firebase in a Next.js project 5:09 đ 9 Routing Manage dynamic routing and links in Next.js 4:54 đ 10 Loader Create a loading spinner to manage loading states across the app 1:30 đĢ 11 Navbar Create a dynamic navigation bar with React 3:24 đ§ 12 Toast Use react-hot-toast to trigger animated toast messages 1:30 Users đ§đģâđ¤âđ§đŋ 13 Auth Intro Technical overview of Firebase Auth with custom usernames 2:10 đ¤ 14 Google SignIn Authenticate via OAuth with Google SignIn 2:51 đ 15 Auth Context Manage the global auth state with the React Context API 3:07 đŖ 16 Auth Hook Join Firestore data to the current user with a custom react hook 3:57 đ¨âđ¤ 17 Custom Usernames Add custom usernames to Firebase users and asynchronously validate uniqueness 7:02 SSR đ 18 SSR & SEO in Next Technical overview of server-side rendering and SEO free 4:27 đž 19 Data Model How to model data relationships between users, posts, and hearts 2:04 đ 20 SSR User Profile Page Implement server-side rendering to fetch data on the server 5:43 đ 21 SSR + Paginated Home Page Feed Render a feed of the latest posts with a collectionGroup query 3:40 đĻž 22 ISR Incremental Static Regeneration Use incremental static regeneration (ISR) to rebuild pages on the fly 3:45 đ 23 Realtime Data Hydration Transition or hydrate server-rendered content to a realtime stream of data from Firestore 2:30 đ 24 Custom 404 Page Render a custom 404 page for dynamic pages that do not exist. 1:17 đˇī¸ 25 Metatags for SEO Generate dynamic metatags for search engine optimization and social linkbots 2:01 CRUD Features đ 26 Admin Pages Create an AuthCheck component to render content for signed-in users 1:50 đ° 27 Create Data with Firestore Create a new post document in Firestore with a custom slug ID 5:20 âī¸ 28 Post Editing Form Use react-hook-forms to create a form to edit posts in markdown 5:33 âī¸ 29 Form Validation Add form validation with react-hook-forms 2:02 đ 30 Image Uploads Create an image file uploader with Firebase storage 4:55 Hearts đ 31 Hearts, Likes, Claps Create a many-to-many relationship where users can heart many posts 4:12 Deploy đ 32 Backend Security Use Firestore Rules to ensure features are secure across the entire stack 6:30 đ 33 Vercel Deployment Deploy the app with continuous integration on Vercel 2:01 đ 34 Firebase Deployment Deploy the app to Firebase hosting 0:00