Next.js & React - The Complete Guide (incl. Two Paths!) by Maximilian Schwarzmüller
- 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 checkprofile.js
: server side session check
Click to Contract/Expend
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
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,
};
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 {};
}
fallback: false
- deal with only specifically generated pages
fallback: true
- good combination with
// getStaticProps() if (!product) { return { notFound: true }; } // component if (!loadedProduct) { return <p>Loading...</p>; }
- good combination with
fallback: "blocking"
- or just this
We can choose onlh one either
getStaticProps()
- with
getStaticPaths()
- with
getServerSideProps()
getServerSideProps()
returns as the same asgetStaticProps()
exceptrevalidate
as it will always run again
export async function getServerSideProps(context) {
const { params, req, res } = context;
return { props: { username: "Max" } };
}
req
andres
are the node js classes
- Request: https://nodejs.org/api/http.html#http_class_http_incomingmessage
- Response: https://nodejs.org/api/http.html#http_class_http_serverresponse
- 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)
- Go to Console
- Create a new project, 'nextjs-course'
- Build -> Realtime Database -> Create Database
- Security rules: Start in test mode
- Add data
{ "sales": { "s1": { "username": "Max", "volume": 100 }, "s2": { "username": "Manuel", "volume": 50 } } }
import import.json
to the firebase
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
npm install --save react-markdown
- it parses meta data and content from a file
npm install --save gray-matter
npm install --save react-syntax-highlighter
npm install --save mongodb
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>
- 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
- 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
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
- create an vercel account
- create a private repo
- push all code to the repo
- vercel -> import git repository
- deploy with default settings
- make a change and push to the github -> CD(continuous deployment)
Full Static Build : no serverside code
# run on 03-pages-file-based-routing
npm run build
npm run export
# it will generate 'out' directory
- 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
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
- 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)
# v4 now
npm install --save next-auth
# in the course it uses v3
# npm install --save-exact next-auth@3
# 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
We shouldn't clash with these pre-defined APIs
next-auth sets some cookies when successfully logged in
export function getServerSideProps() {
// can't use getStaticProps() as it needs to get rendered every incoming request
}
Anyone can send request to the API routes
Thus, they must be protected as well, not only the ui side