Skip to content

Next.js & React - The Complete Guide (incl. Two Paths!) by Maximilian Schwarzmüller

Notifications You must be signed in to change notification settings

blog-template/nextjs-complete-max

 
 

Repository files navigation

Next.js & React - The Complete Guide (incl. Two Paths!)

Next.js & React - The Complete Guide (incl. Two Paths!) by Maximilian Schwarzmüller

Folder structure

  • 04-prj-routing: Event project 01
  • 06-prj-data-fetching: Event project 02
  • 07-prj-optimizations: Event project 03
  • 09-prj-api-routes: Event project 04
  • 11-prj-blog: Blog project
  • 13-auth: Auth project
    • user-profile.js: client side session check
    • profile.js: server side session check

Details

Click to Contract/Expend

Section 04. Project Time: Working with File-based Routing

77. Adding Buttons & Icons

heroicons

Section 05. Page Pre-Rendering & Data Fetching

89. How NextJS Prepares & Pre-renders Pages

Two forms of pre-rendering

  • Static Generation
    • pre-generate a page during building time
    • pages are prepared ahead to time and can be cached by the server / CDN serving the app
    • export async function getStaticProps(context) {}
  • Server-side Rendering

95. Utilizing Incremental Static Generation (ISR)

DOC: Incremental Static Regeneration

Re-generate it on every request, at most every X seconds

  • Serve "old" page if re-generation is not needed yet
  • Generate, store and server "new" page otherwise

in Dev version, it will regenerate every reload
but in Production, it will generate every 10 seconds as defined

return {
  revalidate: 10,
};

98. Working With Dynamic Parameters

it can be done using useRouter() but that will render only on front side

// localhost:3000/p1
export async function getStaticProps(context) {
  const { params } = context;
  const productId = params.pid;
  return {};
}

99. Introducing "getStaticPaths" For Dynamic Pages

DOC: getStaticPaths

104. Fallback Pages & "Not Found" Pages

  1. fallback: false
    • deal with only specifically generated pages
  2. fallback: true
    • good combination with
      // getStaticProps()
      if (!product) {
        return { notFound: true };
      }
      // component
      if (!loadedProduct) {
        return <p>Loading...</p>;
      }
  3. fallback: "blocking"
    • or just this

105. Introducing "getServerSideProps" for Server-side Rendering (SSR)

We can choose onlh one either

  • getStaticProps()
    • with getStaticPaths()
  • getServerSideProps()

106. Using "getServerSideProps" for Server-side Rendering

  • getServerSideProps() returns as the same as getStaticProps() except revalidate as it will always run again

107. getServerSideProps and its Context

export async function getServerSideProps(context) {
  const { params, req, res } = context;
  return { props: { username: "Max" } };
}

req and res are the node js classes

110. Introducing Client-Side Data Fetching (And When To Use It)

  • Data changing with high frequency (e.g. stock data)
  • Highly user-specific data (e.g. last orders in an online shop)
  • Partial data (e.g. data that's only used on a part of an page)

111. Implementing Client-Side Data Fetching

firebase

  1. Go to Console
  2. Create a new project, 'nextjs-course'
  3. Build -> Realtime Database -> Create Database
    • Security rules: Start in test mode
  4. Add data
    {
      "sales": {
        "s1": {
          "username": "Max",
          "volume": 100
        },
        "s2": {
          "username": "Manuel",
          "volume": 50
        }
      }
    }

Section 06. Project Time: Page Pre-rendering & Data Fetching

118. Preparations

import import.json to the firebase

121. Optimizing Data Fetching

getStaticPaths() - fallback

  • false: we created all possible pages
  • true: it means we have fallback component which is <p>Loading...<p>
  • blocking: will server-render pages

Section 11. Complete App Example: Build a Full Blog A to Z

188. Rendering Markdown As JSX

npm install --save react-markdown

190. Adding Functions To Read & Fetch Data From Markdown Files

npm gray-matter

  • it parses meta data and content from a file
npm install --save gray-matter

195. Rendering Code Snippets From Markdown

react-syntax-highlighter

npm install --save react-syntax-highlighter

199. Storing Messages With MongoDB In A Database

npm install --save mongodb

201. Adding "head" Data

It is very important for post content page as it optimises search engines (SEO)

<Head>
  <title>{props.post.title}</title>
  <meta name="description" content={props.post.excerpt} />
</Head>

Section 12. Deploying NextJS Apps

207. Building NextJS Apps: Your Options

  1. Standard Build
    • next build
    • Produces optimized production bundles and a server-side app: Requires NodeJS server
    • Pages are pre-rendered (if possible) but NodeJS server is required for API routes, server-side pages and page revalidations
    • Re-deploy needed if code changes or you don't use revalidations and need page updates
  2. Full Static Build
    • next export
    • Produces 100% static app (HTML, CSS, JS): No NodeJS server required
    • Doesn't work if your app uses API routes, server-side pages or wants to use page revalidations
    • Re-deploy needed for all code and content changes

211. Running a Test Build & Reducing Code Size

npm run build

Route (pages)                                      Size     First Load JS
┌ ● / (ISR: 60 Seconds)                            1.05 kB        78.8 kB
├   └ css/0b7eed4ff99cfd8a.css                     606 B
├   /_app                                          0 B            74.5 kB
├ ○ /404                                           181 B          74.7 kB
├ λ /api/contact                                   0 B            74.5 kB
├ ○ /contact                                       1.3 kB         75.8 kB
├   └ css/f8039d3041f1b6e3.css                     709 B
├ ● /posts (ISR: 60 Seconds)                       861 B          78.7 kB
├   └ css/bf52dc61e5ba2b27.css                     436 B
└ ● /posts/[slug] (ISR: 5 Seconds) (772 ms)        272 kB          350 kB
    └ css/1c165c261101802e.css                     436 B
    ├ /posts/mastering-javascript (391 ms)
    └ /posts/getting-started-with-nextjs (381 ms)
+ First Load JS shared by all                      75.3 kB
  ├ chunks/framework-8c5acb0054140387.js           45.4 kB
  ├ chunks/main-2364f599a24c3599.js                25.7 kB
  ├ chunks/pages/_app-1aa950c7dc621994.js          2.6 kB
  ├ chunks/webpack-ee7e63bc15b31913.js             815 B
  └ css/2a9ae2bcaf0d7f3f.css                       783 B

/posts/[slug] (ISR: 5 Seconds) (772 ms) 272 kB 350 kB is too big!!

react-syntax-highlighter - light build

└ ● /posts/[slug] (ISR: 5 Seconds) (772 ms)        272 kB          350 kB
# -> After refactoring
└ ● /posts/[slug] (ISR: 5 Seconds) (762 ms)        49.9 kB         128 kB

And this is before compression.
NodeJS will compress these files

npm run build
npm start
# Warning: For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended. Run 'yarn add sharp', and Next.js will use it automatically for Image Optimization.
npm install sharp --save

212. A Full Deployment Example (To Vercel)

  1. create an vercel account
  2. create a private repo
  3. push all code to the repo
  1. vercel -> import git repository
  2. deploy with default settings
  3. make a change and push to the github -> CD(continuous deployment)

214. Using the "export" Feature

Full Static Build : no serverside code

# run on 03-pages-file-based-routing
npm run build
npm run export
# it will generate 'out' directory

219. How Does Authentication Work (In React & NextJS Apps)?

Two ways to authenticate

  • Server-side Sessions
    • Store unique identifier on server, send some identifier to client
    • Client sends identifier along with requests to protected reousrces
  • Authentidcation Tokens (recommended for SPA)
    • Create (but not store) "permission" token on server, send token to client
    • Client sends token along with requests to protected resources

Reasons why using tokens

SPAs works with tokens instead of sessions because

  • Pages are served directly and populated with logic without hitting the server
    • (Some nextjs pages are not though)
  • Backend APIs work in a "stateless" way (they don't care about connected clients)
    • Servers don't save information about authenticated clients

JWT (JSON Web Tokens)

  • JSON Web Token
    • Issuer Data
    • Custom Data
    • Secret Signing Key
      • Only the signing server is able to verify an incoming token
  • Signed, NOT encrypted (can be parsed + read by anyone)

220. Must Read: Install the Right next-auth Version

next-auth v4 upgrade guide

221. Using The "next-auth" Library

# v4 now
npm install --save next-auth
# in the course it uses v3
# npm install --save-exact next-auth@3

222. Adding A User Signup API Route

# prettify except .next folder
prettier -w . '!**/.next'
npm install --save mongodb
npm install --save bcryptjs
import { hash } from "bcryptjs";
hash(password, 12); // for salt number, the higher the more secure

225. Adding the "Credentials Auth Provider" & User Login Logic

Doc: NextJS REST API

We shouldn't clash with these pre-defined APIs

227. Managing Active Session (On The Frontend)

next-auth sets some cookies when successfully logged in

230. Adding Server-Side Page Guards (And When To Use Which Approach)

export function getServerSideProps() {
  // can't use getStaticProps() as it needs to get rendered every incoming request
}

234. Protecting API Routes

Anyone can send request to the API routes
Thus, they must be protected as well, not only the ui side

About

Next.js & React - The Complete Guide (incl. Two Paths!) by Maximilian Schwarzmüller

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 76.6%
  • CSS 23.4%