Next.js SSR, SSG and ISG

Photo by Andrew Neel on Unsplash

Next.js SSR, SSG and ISG

First, let's start with SSG (static site generation) what does it mean? well, we all know what static is, so what does it mean for site generation?

Here in Next.js, it does this site generation magic at the build time of the app. Then the props are sent to render on the page. These props are generated by the getStaticProps async function. So all the data must be available at the build time for this page to generate, which does make sense.

const Home = ({data}) => {
    const [pokemons, setPokemons] = useState(data)    
    return (
        <div>
            {pokemons && pokemons.map((pokemon, index))=> (
                <h1 key={index}> {pokemon.name} </h1>
            )}
        </div>
    )
}
export default Home

export const getStaticProps : GetStaticProps = async () => {
    //get 20 pokemons API call
    const { pokemons } = await getPokemons(20)
    return {
        props: {
          data: pokemons,
        }
     }
}

Here in the above code, in the getStaticProps function API request is made for getting the data (Pokemon) and send as props to the Home component, Next.js will pre-render this page when the app is built. To verify if the page has been generated one can see it in the .next/server/pages folder after the npm run build command.

Now let's look at SSR (Server Side Rendering), for this Next.js has getServerSideProps returns the props which pre-render the page each time whenever the request is made for it. Also, this function always runs on the server side, so even if you put some keys here it would not be an issue as it never shows up on the client side.

const Home = ({ pokemon }) => {
  // Render data...
}
export default Home

// This gets called on every request
export const getServerSideProps : GetServerSideProps (context) {
  //get single pokemon by id API call
  const pokemon = await getSinglePokemon(context.params?.id)

  // Pass the pokemon to the page via props
  return { props: { pokemon } }
}

Here in the above code in the getServerSideProps function we a requesting single Pokemon by passing in the id which is received by the context object and sending it as props to the Home component. This function needs to be a standalone function that always pre-renders on requests made via client-side page transition through next/link or next/router. So one needs to use it when data must be fetched at request time.

Finally, we have ISG (Incremental Static Regeneration), which allows the static-generated page to update or create without the need of rebuilding the entire app which would have been a lot of pain for the developers. Worry not ISG allows us to overcome this issue, one just needs to add the revalidate prop to the getStaticProps, here's the same example from the previous.

const Home = ({data}) => {
    // data render
}
export default Home

export const getStaticProps : GetStaticProps = async () => {
    //get 20 random pokemons API call
    const { pokemons } = await getRandomPokemon(20)
    return {
        props: {
          data: pokemons,
        },
        revalidate: 5, //** in 5 sec
    }
}

Notice the additional prop, the revalidate prop is set to 5 seconds, so any request made to the page will show the cached page. Then any request to the page after the initial and before the 5 seconds will show the same cached page, after the 5 seconds it will still show the same cached page but Next.js will trigger a regeneration of the page in the background. Finally, it will validate the cached page with the new one and render the page accordingly. In case the regeneration does fail it will show the same cached page.

In conclusion, having a solid understanding of the various page generation techniques offered by Next.js, along with their respective advantages and use cases, can be crucial in optimizing website performance, improving user experience, and ultimately, setting your project up for success.