Day 5

Key learnings:

  • React hooks like useRouter cant be used in GSP (getStaticProps) - it can only be used in React function component.

    • So can’t use useRouter to get the slug (like ID of note/post). But we dont need it - we have context param in GSP.
  • In GSP the context will not hold req and res - it has params:

    • the params object has
      • key = the thing between [] in the filename. (e.g. pages\[noteId]\index.js)
      • value = gets it from actual current URL
  • getStaticPaths (GSPa) is needed when working with GSP - it can be used to load the key/slugs/ids of each post form DB, so that next knows about them and is able make the info available in GSP.


Going to use getStaticProps for our Notes page. Why? because page wont be frequently changing.

In pages\[noteId]\index.js

  • use GSP
  • return fake data for now - at props key

The ID (slug or id) to identify the note / post is embedded in URL

Cant use useRouter - in GSP - to get URL embedded in URL - have alternative: use the context.params of GSP

export async function getStaticProps(context) {
  //TODO fetch data for a single note.

  const noteId = context.params.noteId;
  console.log(noteId);  //This will show on development server log, not in browser because (dev server reruns for every code change to assist in development, because it is dev env). GSP Actually runs on Build time only. So this log is NOT in browser but in env. of whoever did the build - the Dev env!

  return {
    props: {
      noteData: {
        id: noteId,
        title: "Selfie from Mars",
        details: "This is Curiosity's selfie from Mars",
        image:
          "https://www.nasa.gov/sites/default/files/thumbnails/image/pia23378-16.jpg",
      },
    },
  };
}

preparing paths with getStaticPaths

GSPa is another reserved fn that nextjs understands

Use GSPa if

  • if its a dynamic page like pages\[noteId]\index.js

  • AND if using GSP, (not needed if using GSSP)

  • Its async

With GSP a page is rendered during build. NextJS has to

  1. render all the versions of the dynamic page - for all supported IDs (jinka jinka data hai existing available - uss har data ke liye)

GSPa has job of returning an object where we describe all the dynamic segment values - so all the note IDs in this case, for whom the page should be generated.

  • paths is reserved
  • params is reserved
export async function getStaticPaths(){
    return {
        paths: [
                {
                    params: {
                        noteId: 'n1',
                    },
                    params: {
                        noteId: 'n2',
                    }
                }
        ]
    };
}

The array at paths is in real world - fatched from a database.

On reaching so till here, we get error:

Server Error
Error: The `fallback` key must be returned from getStaticPaths in /[noteId].
Expected: { paths: [], fallback: boolean }

fallback

If using GSP, need to include fallback key in GSPa

  • fallback : false // If set this, user sees 404 error if any URL is not supported (means the dynamic page for i was never rendered)

  • fallback : true is good in the sense that - while some of the (supported) keywords will cause page to generate on build time, the unsupported keywords wont show 404 but a page will be generated for them at the instance when request comes with a xyz URL.

If your usecase is - if you are sure you have defined all the supported paths for which req will be coming in, then set the fallback to false. We will do this.

Generated the most visited / most popular pages by returning their ID from the GSPa

Wasted 30mins - /n1 /n2 were always showing as 404. Problem was with my GSPa return object structure - be careful! Used this: wrong

Wrong

export async function getStaticPaths() {
  return {
    fallback: false,
    paths: [
      {
        params: {
          notesId: "n1",
        },
        params: {
          notesId: "n2",
        },
      },
    ],
  };
}

Correct:

export async function getStaticPaths() {
  return {
    fallback: false,
    paths: [
      {
        params: {
          noteId: "n1",
        },
      },
      {
        params: {
          noteId: "n2",
        },
      },
    ],
  };
}