diff --git a/docs/Next.js.md b/docs/Next.js.md new file mode 100644 index 00000000..22cf982e --- /dev/null +++ b/docs/Next.js.md @@ -0,0 +1,389 @@ +### Terminology + +- SSR: server-side rendering +- SSG +- ISR +- Edge +- Lambda + +### DOM + +Document Object Model: The in-browser tree of HTML elements representing the page. + +### Client + +The user's environment, the browser. The front-end is the code running in that environment. +On Compass, it can be any browser (Chrome, Firefox, etc.). + +### Server + +Any remote infrastructure, i.e., not running in the user's environment / OS. The back-end is the code that runs in that environment. +On Compass, there are two servers: +- Web server: hosted on Vercel at `compassmeet.com`, which mostly provides the web pages to the client. That's the server we are talking about in the rest of the document. +- Core server: hosted on Google Cloud at `api.compassmeet.com`, a server with more resources and permissions to update the database. It's in charge of any operation related to non-web data (i.e., no HTML or CSS) such as accounts, profiles, messages, and votes. + +--- +### React + +React is a client-side UI library. +Its core job: create and update a **virtual DOM**, then reconcile that with the **real DOM** in the browser. +React itself **does not** define routing, data fetching conventions, or server rendering (it allows it, but doesn’t provide a full system). + +**Key behavior:** + +- React components run on the **client** by default. +- React can be rendered on the **server** (via frameworks like Next.js), but this requires additional tooling. +- React uses a Virtual DOM to compute minimal changes, then applies them to the real DOM. + +--- +### Hydration + +When a framework pre-renders HTML on the server, the browser receives static markup (HTML, JS and CSS). React then runs on the client and attaches event listeners and internal state to that markup. +Hydration bridges static HTML (build time) and interactive React behavior (run time). + +You only need hydration if you have server-rendered HTML that must become interactive. + +--- + +### Next.js: What it adds + +Next.js is a React framework that controls **where** code runs (server vs client), **when** it runs (build vs request time), and how HTML is generated. It adds routing, rendering strategies, data fetching conventions, and server infrastructure. + +Next.js introduces: + +- Server Components vs Client Components +- Route-based rendering +- Built-in server rendering pipelines +- Build-time optimizations + +--- + +### Client vs Server in Next.js + +**Server Components:** + +- Render **on the server**, never shipped to the client. +- Can safely access databases, filesystem, secrets. +- Output is serialized to HTML + a data format React uses to assemble the UI. + +**Client Components (`"use client"`):** + +- Render **in the browser**. +- Shipped to the client as JS bundles. +- Needed for interactivity (state, events, effects). + +Notes: + +- You can mix Server and Client components; the boundary matters for bundle size and where code executes. +- Only Client Components hydrate. + +--- + +### Build-Time vs Run-Time + +#### Build-Time (during `next build`) + +- The compiler analyzes the app, identifies server boundaries, optimizes routing. +- Static pages (SSG) are rendered to final HTML. +- Partial data may be pre-fetched if using static data functions. +- Bundles for client components are built. + +#### Run-Time + +- Server Components for SSR are executed on each request. +- Serverless or edge functions run as needed. +- Client Components hydrate and run effects in the browser. + +--- + +### Rendering Strategies + +#### SSR (Server-Side Rendering) + +- Used a webpage or API endpoint (to get server-side data like build ID). +- Generated on **every request**. +- Good for dynamic data that must be fresh. +- Initial load: server renders HTML → client hydrates. +- Runs server logic each time a user requests the page. + +Can be dynamic or edge. +###### λ (Dynamic) + +- **Server-rendered on demand using Node.js** +- Each request hits a Node.js server (or serverless function) +- Full access to Node APIs, filesystem, secrets, DB connections +- Typical use: **SSR pages with dynamic data** not suitable for edge +- Latency depends on server location + +###### ℇ (Edge Runtime) + +- **Server-rendered on demand using Edge Runtime** +- Runs on global edge nodes (CDN locations) +- Faster response due to geographic proximity +- Limited APIs: no filesystem, limited Node.js modules, mostly fetch and standard web APIs +- Typical use: **low-latency SSR or ISR at the edge** + +#### SSG (Static Site Generation) + +- HTML is generated **at build time**. +- Served as static files. +- Zero server cost at request time. +- Best for data that changes rarely. + +#### ISR (Incremental Static Regeneration) + +- A hybrid of SSG + scheduled revalidation. +- Page is generated at build, then regenerated **in the background** after a specified interval. +- Allows static pages with reasonably fresh content without full rebuilds. + +Example behavior: + +- First request after the revalidation window triggers a background regeneration. +- Users keep seeing the old page until the new one is ready, then updates swap in. + +There are components that: + +- Run once **on the server** to generate HTML (SSR phase) +- Then run again **in the browser** for hydration (client phase) + +--- + +### What Runs Where: Quick Table + +| Task / Code | Build Time | Server Run Time | Client Run Time | +| -------------------------- | ---------- | ---------------- | --------------- | +| Pre-rendering SSG pages | Yes | No | No | +| ISR regeneration | No | Yes (background) | No | +| SSR rendering | No | Yes | No | +| React event handling | No | No | Yes | +| `useEffect` | No | No | Yes | +| Server Component rendering | No | Yes | No | +| Client Component hydration | No | No | Yes | + +--- + +# 1. Component Type Detection + +## A. **Client Component (App Router)** + +A component is a **Client Component** if: + +- The file begins with `"use client"`, or +- It uses **client-only hooks** (`useState`, `useEffect`, `useRef`, etc.), or +- It references **browser APIs** (`window`, `document`, `localStorage`, etc.), or +- It uses **client navigation** (`Router.replace`, `useRouter`), or +- It uses **interactive JSX handlers**: `onClick`, `onSubmit`, etc. + +**Implications:** + +- Runs **only in browser** +- **Hydrates** on the client +- **No SSR** of its data +- May receive HTML shell from server, but logic/data loads on client + +Client Components = browser-only, hydrated, interactive. + +--- + +## B. **Server Component (App Router)** + +A component is a **Server Component** if: + +- No `"use client"` +- No client hooks +- No browser APIs +- No interactive handlers +- Uses server-only capabilities (DB queries, file system, server fetch, secrets) + +**Implications:** + +- Runs on **server at build time** (if static) and/or **server at request time** +- **No hydration** for the server part +- Can output HTML directly +- Can trigger SSG / SSR / ISR depending on cache mode or revalidate + +--- + +# 3. Rendering Strategy (Pages Router Rules) + +In the **Pages Router**, rendering is dictated entirely by which data-fetching function you export. + +Below are the functions and exactly what they imply. + +--- + +# 4. `getServerSideProps` — What It Does and What It Implies + +```js +export async function getServerSideProps(context) { ... } +``` + +### What it does: + +- Runs **on the server for every request**. +- Provides props to the page component. +- Has access to: + - database + - filesystem + - environment variables + - cookies, headers, auth context + +### What it implies: + +- The page is **SSR** (Server-Side Rendered). +- HTML is generated **on each request**. +- **No SSG** or ISR possible. +- The page is never static. + +### Rendering outcome: + +- **SSR HTML** + hydration for any client-side React in the page. + +--- + +# 5. `getStaticProps` — What It Does and What It Implies + +```js +export async function getStaticProps(context) { ... } +``` + +### What it does: + +- Runs **once at build time**. +- Fetches data needed for static generation. +- Provides props to the component. + +### What it implies: + +- The page is **SSG** (Static Site Generated). +- The output is static HTML + static JSON. +- Zero server rendering at request time. + +### Rendering outcome: + +- **Purely static HTML** served from CDN. +- Hydration if component includes client logic (but no server execution). + +### When ISR occurs: + +- If you return `{ revalidate: N }` from `getStaticProps`, the page becomes **ISR**. + +Example ISR config: + +```js +export async function getStaticProps() { + return { + props: { ... }, + revalidate: 60 // seconds + } +} +``` + +--- + +# 6. `getStaticPaths` — What It Does and What It Implies + +Used for **dynamic SSG pages** (e.g., `[id].js`). + +```js +export async function getStaticPaths() { ... } +``` + +### What it does: + +- Runs **at build time**. +- Tells Next.js which dynamic routes to pre-render. +- Works together with `getStaticProps`. + +### What it implies: + +- Page is **SSG** or **ISR** depending on `getStaticProps`. +- The routing structure is fixed at build time unless fallback mode is used. + +### Fallback modes define run-time: + +- `fallback: false` → Only pages listed exist; 404 for others +- `fallback: true` → Generate pages at runtime, then cache them as static +- `fallback: "blocking"` → Block until server generates static page + +Fallback generation effectively behaves like **ISR** for pages not pre-rendered. + +--- + +# 7. Summary Table (Pages Router) + +| Export | When It Runs | Rendering Model | Triggered By | +| -------------------- | -------------------- | -------------------------------------- | --------------------------- | +| `getServerSideProps` | On **every request** | **SSR** | Always dynamic | +| `getStaticProps` | **Build time** | **SSG** (or **ISR** with `revalidate`) | No runtime server | +| `getStaticPaths` | **Build time** | **SSG** for dynamic routes | Works with `getStaticProps` | + +--- + +# 8. Combining Rules: How to Infer Rendering from Code + +### If you see `getServerSideProps`: + +- The page is always **SSR** +- Component receives props from server +- Component itself is a normal React component rendered server-side then hydrated +- No client data loading unless the component explicitly fetches in browser + +### If you see `getStaticProps`: + +- The page is **SSG** or **ISR** +- Only runs again during revalidation +- Component is static unless you add client-side fetching + +### If you see `getStaticPaths`: + +- The file uses dynamic **SSG** or **ISR** +- Builds static versions of dynamic routes + +### If you see `"use client"`: + +- Entire file is **client-rendered** +- Data in this component does **not** SSR +- Even if the page uses SSG/SSR, this component runs only in browser + +### If you see hooks (`useState`, `useEffect`, etc.): + +- The component must be **client-side** +- It must hydrate +- It cannot participate in server rendering logic +- SSG/SSR/ISR still occurs for the page shell, but the logic inside this component runs only in browser + +### If you see server-side code (DB queries, secrets): + +- Component must be **Server Component** (App Router) or handled inside `getServerSideProps`/`getStaticProps` + +--- + +### How to Think About It When Architecting + +1. **Default to Server Components** whenever no browser interactivity is needed. + Reduces bundle size and avoids unnecessary hydration. + +2. **Use Client Components** only where interaction happens (buttons, forms, animations, local state). + +3. **Choose a rendering model based on data volatility**: + - Rarely changing: SSG + - Somewhat changing and OK with slightly stale: ISR + - Must always be fresh or personalized: SSR + +4. **Remember:** Hydration cost scales with the amount of Client Components. Keep them narrow. + +5. **Consider caching**: + Next.js can automatically cache server component results; knowing what is cached impacts performance heavily. + + +### Backend vs Frontend on Next.js + +| Term | True Meaning | Might Confuse People Because… | +| ------------ | ------------------------------------------------------------------------ | --------------------------------------------------------------------------- | +| **Frontend** | Code that executes in the user’s environment (browser, WebView) | SSR code _belongs to frontend logic_ but executes on server | +| **Backend** | Code that executes on remote infrastructure (server, VM, cloud function) | Some “backend-like” behavior can occur in browser via caching or local APIs | + +### Downtime + +To simulate downtime **you need the error to happen at runtime, not at build time**. That means the page must be **server-rendered**, not statically generated. \ No newline at end of file