NextJS Notes

 

Reactjs is a Library and Nextjs is a Framework which is build on top of Reactjs, so before understanding what exactly is Nextjs, firstly we need to understand what is the difference between a library and a framework.

Aspect

JavaScript Library

JavaScript Framework

DefinitionA collection of functions and utilities for specific tasksA complete structure to build and manage an application
Control FlowYou call the library (you’re in control)Framework calls your code (framework is in control)
Inversion of Control❌ No inversion — you’re in charge✅ Yes — framework dictates structure and flow
Scope of UseNarrow, specific — often for a particular featureBroad — full application architecture
DependencyOptional — can use as neededMandatory — dictates how components interact
Learning CurveUsually low — easier to integrateHigher — requires understanding framework’s patterns and structure
FlexibilityHigh — you choose when and how to useLow — must follow framework rules and lifecycle
ModularityCan use standalone functionsRequires app to be built within its ecosystem
ExamplesLodash (utils), Axios (HTTP), jQuery (DOM)Angular, Vue, Next.js, Svelte, Ember
Code IntegrationPlug-and-play with any projectProject must conform to the framework's structure
OpinionatednessLow — lets you decide how to structure your appHigh — enforces certain architecture and practices
TestingEasier to test in isolationMore integrated testing approach needed
Real-World AnalogyToolset you carry and use when neededPre-built home structure where you fill in the rooms
Use Case

Ideal for adding features to existing apps

Ideal for building full-fledged apps from scratch

-----------------------------------------------------------------------------------------

🔍 Example Analogy

  • Library = Like ordering parts to build your own bike however you want.

  • Framework = Like assembling a bike from IKEA with strict instructions.




-----------------------------------------   IMPORTANT   --------------------------------------------

1. In nextjs, if we are in production mode( for starting production mode use command -> npm run build | then after that a .next folder is created in directory then, use command -> npm start ) then if we send a request from any specific page from the browser to server then, it will send a static HTML file which have same name as that page and have HTML content in it, which is directly coming from the server, but it also send few more files ie. rsc and meta files of that pages and other pages which are not loaded at that time, rsc and meta files have rendering data for pages, which makes the rendering very faster.

2. Note: The static HTML file will only be generated for the pages from where we are sending request to the browser, not for all the pages, but rsc and meta files will be generated for all the pages.

3. By Default Nextjs only call the data of the pages( html, rsc and metadata ) for which the links are present on the current page( page from where we are sending the request ), and it will later on, nextjs calls the data of other pages, once we move from one page to another and more links are visible.

4. If you mark parent component as use client, so all the child component inside that parent component also become client component, try to avoid making a parent component as client component as much as possible.

5. 







------------------------------------------------------------------------------------------------------------

Static and Dynamic Rendering
Both static and dynamic rendering are the type of Server side rendering.

Static Rendering (Default)

  • Pages are pre-rendered at build time
  • HTML is generated once during next build and reused for each request
  • Faster performance since content is served from CDN
  • Better for SEO as content is immediately available
  • Data is fetched at build time using generateStaticParams or during the build process
  • Content remains the same until the next build

Dynamic Rendering

  • Pages are rendered on each request at runtime
  • HTML is generated fresh for every user request
  • Automatically happens when Next.js detects dynamic functions like:
    • cookies(), headers(), searchParams
    • Uncached data fetches
    • Dynamic segments without generateStaticParams
  • Slower than static but allows for personalized, real-time content
  • Better for user-specific data or frequently changing content

When to use each:

  • Static: Marketing pages, blogs, documentation, product catalogs
  • Dynamic: User dashboards, personalized content, real-time data, authenticated pages

Lets understand with the help of an example -> Let suppose, u build a nextjs app after using build command( for starting production mode use command -> npm run build | then after that a .next folder is created in directory then, use command -> npm start ) now u have console.log(blogID) in a dynamic page then everytime we click on that page then the console.log will also run, but if there is a console.log in static page then it wont run in productions mode.



------------------------------------------------------------------------------------------------------------

Rendering Paradigm( paradigm -> example or pattern of something )


1. SSR (Server-Side-Rendring)

SSR is the technique in which code executes on server and then server send the entire html to client( go to page source in any website in browser then u will see the SSR app have entire html but CSR only have HTML boiler plate with only root div ) then it gets rendered at once this technique is used by Nextjs( even if we disable the javascript from the browser then also the page will be visible).

  • NOTE: SSR dont provide the reactivity for the browser like if we use onClick or onChange or something like that then it will give us the error that these things are only present in client side...

  • Because the HTML is directly coming from servers, then its easy for crawler( bots in browser ) to read those pages and give the SEO better for those web-apps which is Server side rendered.


  
              |-----> SSG( Static-Site-Generation)
              |
SSR ----|
              |
              |-----> ISR( Incremental-Static-Regeneration)

                                
                                        ISR and SSG, both are the type of SSR. 




2. CSR (Client-Side-Rendring)

CSR is the technique in which Javascript in inject the html in the root div then it present the full website, this techinque is used by Reactjs( if we disable the javascript from the browser then the page will be not be visible because the javascript is doing the work here ).

  • NOTE: SSR is really fast as compare the CSR because the html takes less time to render, on the other hand the CSR sends javascript to the client which takes more time to get render...

  • NOTE: SSR components only renders(displayed) on the server( in your terminal ) while doing a console.log(), where as CSR components renders on both terminal and console on the browser... (u might see the SSR components presenting on the console on browser but they will have this "SERVER" tag along with them)

  • NOTE: By default Nextjs have only server side components but if you want to create a component as a client side component then go to the top of the file and write this -> 'use client' this is how u can create a component as client side.

  • React.js provides a static server, meaning it only starts on a port and serves pre-built static files like HTML, CSS, and JavaScript. There's no backend logic or server-side processing — everything runs in the browser after the files are loaded.

  • Next.js provides a dynamic server, meaning it can serve static files and render pages dynamically on the server using Server-Side Rendering (SSR) or API routes. It supports features like data fetching at request time, dynamic routing, and backend logic, making it a hybrid framework for both frontend and backend.




3. SSG( Static-Site-Generation)

Static site generation (SSG) is a method of building page where HTML are pre-built at build time rather than generated dynamically on each request. This approach creates fast, secure, and easily deployable websites.
Basically we are creating some static pages which is actually a dynamic page, like if we have a blog website and we know that our 2-3 tech blogs( these blogs are dynamically rendered when user request it ) are getting visited more than other blogs, so we can simply make those dynamic blogs pages into the static pages using static site generation. 

How Static Site Generation Works

Instead of a server processing requests and generating HTML on-the-fly, SSG tools take your content (often written in Markdown), templates, and data sources, then compile everything into static HTML, CSS, and JavaScript files during a build process. These files can then be served from any web server or CDN.

  • Performance: Static files load extremely fast since there's no server-side processing required. CDNs can cache and serve these files from locations closest to users.

  • Security: With no database or server-side code execution, there are fewer attack vectors. You're essentially serving read-only files.

  • Scalability: Static files can handle massive traffic spikes without performance degradation. CDNs make global distribution seamless.

  • Developer Experience: Modern SSG tools offer features like hot reloading, automatic optimization, and easy deployment workflows.

Common Use Cases

Static site generation works particularly well for blogs, documentation sites, marketing websites, portfolios, and e-commerce sites with relatively stable product catalogs. It's ideal when your content doesn't change frequently and you don't need complex user interactions that require server-side processing.



Code :-
just create this exporting function right after all the imports

export function generateStaticParams() {     // name of the function should be generateStaticParams
    return [                                                    // you can write any code in this function but at the end  
        {blogID: "1"},                                  // it should return an array, which have objects like this
        {blogID: "2"},                                // and these objects should have key as dynamic page name
        {blogID: "3"},                              // and value as new page which is getting generated.
        {blogID: "4"},
        {blogID: "5"}
    ]
}


another example => this code can build static pages for all the blogIDs which are present in the fetching route.

export async function generateStaticParams() {     
    const response = await fetch('https://jsonplaceholder.typicode.com/todos');
    const data = response.json();
    return data.map(({ id }) => ({blogID: `${id}`}));
}


dynamicParams in SSG

Well dynamicParams is the type of SSG where the page are automatically statically generated whenever the user visits the page. This automatically create a static page in .next folder where user is visiting and that page is not listed in the array of SSG generateStaticParams() function, this static page will be used later on, when a new user will visit it.
This feature is by default true for dynamic pages where SSG is enabled. If you want to shut it down then paste this code just below the imports.

Code :- 
export const dynamicParams = false;          // name of the constant should be dynamicParams 



4. ISR( Incremental-Site-Regeneration)

ISR (Incremental Static Regeneration) is one of Next.js's most powerful rendering strategies that combines the benefits of static generation with the flexibility of server-side rendering. Here's a comprehensive overview...
Basically it recreate the static page of a page where user is visiting and store that static page in the server for the next user, without again and again building the website, or we can say that we give some time in seconds to the revalidate constant and that page will recreate again and again after that given time in revalidate constant.  

What is ISR?

ISR allows you to create or update static pages after you've built your site. It enables you to use static generation on a per-page basis without needing to rebuild the entire site, solving the scalability issues of traditional static generation.

NOTE => we need to do the static site generation in that page to performe incremental site regeneration. 

How ISR Works

ISR operates on a "stale-while-revalidate" strategy:

  1. Initial Request: Serves the statically generated page (even if stale)
  2. Background Revalidation: Triggers regeneration of the page in the background
  3. Cache Update: Updates the cached version once regeneration completes
  4. Subsequent Requests: Serve the updated static page

Code

Example for reloading the entire page => paste this code just below the imports 

export const revalidate = 5;       // name of the constant is revalidate and 5 is the time in seconds


Example for reloading the API  => paste this code just below the imports 

// app/posts/[id]/page.js
async function getPost(id) {
  const res = await fetch(`https://api.example.com/posts/${id}`, {
    next: { revalidate: 60 } // Revalidate every 60 seconds
  });
  return res.json();
}

export default async function Post({ params }) {
  const post = await getPost(params.id);
  return <div>{post.title}</div>;
}



5. Streaming

The App Router has built-in streaming support through React's Suspense boundaries. Pages automatically stream by default, sending the shell first and then streaming in components as they 
resolve.
Basically render the output whenever the data comes from the server, until that point the components won't render and show the loading.
In general, if any of the component takes 9 seconds time to load then that entire page will take 9 seconds time to load but if the component is suspended then the entire page will load fast but just that component take 9 seconds to load, till that point we can simply shows loading component.

Structure:-

app/
├── (dashboard)/
│   ├── loading.js          # Shared loading for all dashboard routes
│   ├── analytics/
│   │   └── page.js
│   └── settings/
│       └── page.js

Code :-

Firstly create a basic streaming component with loading.js:

// app/dashboard/loading.js

export default function Loading() {

  return <div>Loading dashboard...</div>

}


Streaming specific components by using the suspense, everything that comes under suspense component will load until the response will come from the server:

// app/dashboard/page.js

import { Suspense } from 'react'
import { UserProfile, RecentActivity } from './components'

export default function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Suspense fallback={<div>Loading profile...</div>}>       // we can also give loading component here instead og passing a <div> </div>
        <UserProfile />
      </Suspense>
      <Suspense fallback={<div>Loading activity...</div>}>
        <RecentActivity />
      </Suspense>
    </div>
  )
}


------------------------------------------------------------------------------------------------------------

Topics

1. Hydration
Hydration in Next.js is a critical process where the client-side JavaScript takes over server-rendered HTML, making it interactive. When a Next.js page loads, the server sends static HTML first, then JavaScript "hydrates" it to make it fully interactive.
Basically we can say that if we make changes in the static HTML which is coming from the server then this process is know as Hydration. And this process also produces the hydration error because in nextjs the HTML will get matched from the HTML which is coming from the server and HTML which is getting rendered on client side.

How Hydration Works

  1. Server renders the initial HTML with all content
  2. Client receives the static HTML and displays it immediately
  3. JavaScript bundle downloads and executes
  4. React hydrates the DOM, attaching event handlers and state
  5. Page becomes fully interactive

Hydration Error
This error only occurs when the HTML from the server is getting changed on client side... might be possible that HTML is getting changed because of any browser extension (u can avoid this situation by uninstalling the extension or using incognito mode) or we have written the code which is getting rendered differently on server and differently on client, and from this statement we can clearly understand that this error only occours because of client side components because only client side components gets rendered on both client and server.

This error can simply be produced with math.random() or date.now() functions because when the HTML will render on browser, on that time its value is different but when it gets rendered on browser on that time its value is different from the server. this cause hydration error. 

Because of this error user might see the changing values while the page is loading, like if we have 3G net then these value will be visible for upto 3 seconds then it will change on client side, which will cause bad user experience. 

Code:-
This code will cause hydration error
export default function Dashboard() {
  return (
    <div>
      date function in js {Date.now()}  // or Math.random()
    </div>
  )
}



2. Fetching

Client Components
Its same as we do it in reactjs

Code :-

'use client'
import { useState, useEffect } from 'react'

export default function PostsClient() {
  const [posts, setPosts] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch('/api/posts')
      .then(res => res.json())
      .then(data => {
        setPosts(data)
        setLoading(false)
      })
  }, [])

  if (loading) return <div>Loading...</div>
  
  return (
    <div>
      {posts.map(post => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  )
}


Server Components (default)

Code :-

// app/posts/page.js
async function getPosts() {
  const res = await fetch('https://api.example.com/posts')
  if (!res.ok) throw new Error('Failed to fetch')
  return res.json()
}

export default async function PostsPage() {
  const posts = await getPosts()
  
  return (
    <div>
      {posts.map(post => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  )
}





------------------------------------------------------------------------------------------------------------

Questions

1. Is reactjs only uses client side rendering, or can we perform server site rendering in my reactjs vite, if yes then how?

Ans.
React itself is just a library for building user interfaces and doesn't dictate rendering strategy. By default, React apps (including those built with Vite) use client-side rendering (CSR), but you can implement server-side rendering with some setup.

Default Vite + React = Client-Side Rendering

  • JavaScript bundle loads in browser
  • React hydrates and renders components client-side
  • Initial HTML is mostly empty with a root div

Server-Side Rendering with Vite + React

Yes, you can add SSR to a Vite + React app, but it requires manual configuration:


1. BASIC SSR Setup :-

// in server.js
import express from 'express'
import React from 'react'
import { renderToString } from 'react-dom/server'
import { createServer as createViteServer } from 'vite'
import App from './src/App.jsx'

async function createServer() {
  const app = express()
  
  // Create Vite server in middleware mode
  const vite = await createViteServer({
    server: { middlewareMode: true }
  })
  
  app.use(vite.ssrLoadModule)
  
  app.use('*', async (req, res) => {
    const { App } = await vite.ssrLoadModule('/src/App.jsx')
    const appHtml = renderToString(React.createElement(App))
    
    const html = `
      <!DOCTYPE html>
      <html>
        <head><title>SSR App</title></head>
        <body>
          <div id="root">${appHtml}</div>
          <script type="module" src="/src/main.jsx"></script>
        </body>
      </html>
    `
    res.send(html)
  })
  
  app.listen(3000)
}

createServer()



2. Client-side hydration:

// in src/main.jsx
import { hydrateRoot } from 'react-dom/client'
import App from './App'

hydrateRoot(document.getElementById('root'), <App />)


Easier Alternatives:

Instead of manual SSR setup, consider these frameworks that provide SSR out-of-the-box:

  • Next.js - React framework with built-in SSR/SSG
  • Remix - Full-stack React framework
  • Gatsby - Static site generator with SSR capabilities


2. Is it possible to Dynamically Rendering Static Pages in Next.js? If yes then tell all the ways to perform this rendering.

Ans.
Yes, we can easily dynamically render the a static page by either using Dynamic APIs or forcefully changing the value of dynamic constant to something else like force-dynamic  

Code :-

Example in which we are changing the value of  dynamic constant.
just below the imports, paste this code.

export const dynamic = "force-dynamic";     // it will forcefully rander the page dynamically

export const dynamic = "auto";          // check weather any dynamic API is present in the page, if yes
                                                          // then it will rander it dynamically otherwise statically.

export const dynamic = "error";                // it won't let the website build and give error while building,
                                                                 //  in case of static page is getting rendered daynamically

export const dynamic = "force-static";       // it will forcefully rander the page statically


Example in which we are using Dynamic API
like fetching cookies or using searchParams in page function component.

const serverPage = async ({ searchParams }) => {
    const search = await searchParams;
    console.log(search);
    
    return (
        <>
            <div>
                    Hi
            <div/>
        </>
    )
}

// OR

const serverPage = async () => {
    const myCookies = await cookies();
    console.log(myCookies);
    
    return (
        <>
            <div>
                    Hi
            <div/>
        </>
    )
}






Comments

Popular posts from this blog

ReactJs Notes

HTML NOTES