Mertafor
Mertafor

Reputation: 414

Next JS SSG partial page update best practices

I'm trying to understand how to make a partial update on a SSG page. Next JS is pre-rendering pages on demand if fallback is true or blocking. Revalidate and revalidate on-demand (Next v12) functions provided to re-render the page. But I see examples loading subset of a page instead of full revalidate.

I guess price value would be a perfect example. Changing product price in DB would require immediate effect on entire website. Since it could be displayed on multiple pages / areas on the website, on-demand revalidation on a single path wouldn't work.

Only solution I could think leaving all locations where price is being displayed empty and fetching fresh data with useEffect to update it. However I thought there might be more practical solutions, even a NextJS function to utilize.

Edit : This example is related to dynamic paths require getStaticPaths yet I believe updating certain sections is related to all SSG pages

Here is an example code :

import { GetStaticPaths, GetStaticProps, NextPage } from 'next';
import React from 'react';
import fs from 'fs/promises';
import path from 'path';
import { ParsedUrlQuery } from 'querystring';
import Link from 'next/link';

interface iProduct {
  id: string;
  title: string;
  description: string;
  price:string;
}
interface iProps {
  singleProduct: iProduct;
}

const SingleProduct: NextPage<iProps> = (props) => {
  const { singleProduct } = props;
  
  return (
    <div className="container mx-auto mt-10">
      <h3>{singleProduct && singleProduct.title}</h3>
      <p>{singleProduct && singleProduct.description}</p>
      <p>{singleProduct && singleProduct.price}</p>
    </div>
  );
};


interface iPaths extends ParsedUrlQuery {
  id: string;
}

export const getStaticProps: GetStaticProps = async (context) => {
  const { id } = context.params as iPaths;

  const filePath = path.join(process.cwd(), 'src/data/products_db.json');
  const jsonData = await fs.readFile(filePath, 'utf-8');
  const data = JSON.parse(jsonData);

  const product = data.products.find((item: iProduct) => item.id === id);

  if (!product) {
    return {
      props: {},
      redirect: {
        destination: '/products',
      },
    };
  }

  return {
    props: {
      singleProduct: product,
    },
  };
};

export const getStaticPaths: GetStaticPaths = async () => {
  return {
    paths: [],
    fallback: true,
  };
};

export default SingleProduct;

Upvotes: 0

Views: 2667

Answers (1)

pnxdxt
pnxdxt

Reputation: 160

Your page is either generated at build time (ie. once in a while) or every time user loads your site (SSR). You can control for each page but not for each component right now.

Indeed the first way of solving this is having a useEffect to fetch the price data.

Second way would be asking the site to rebuild certain static pages when you make changes.

This is provided trough Next.js On-demand revalidation.

Read more at: https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration#using-on-demand-revalidation

Upvotes: 0

Related Questions