1

I made this restaurant's website and uses Google Spreadsheet to feed content into the menu pages. The choice of such method was based on simplicity and client expertise.

I'm using google-spreadsheet package to fetch all the information I need from this document on Google Drive...

//** ../pages/api/cardapios/index.js
import { GoogleSpreadsheet } from "google-spreadsheet";

export default async function getCardapioFromSlug(indexNumber) {
  try {

    const doc = new GoogleSpreadsheet(<%GOOGLE_SPREADSHEET_ID%>)
    
    await doc.useServiceAccountAuth({
      client_email: process.env.GOOGLE_SHEETS_SERVICE_ACCOUNT_EMAIL,
      private_key: process.env.GOOGLE_SHEETS_PRIVATE_KEY,
    });
    
    await doc.loadInfo()
    
    const cardapio = doc.sheetsByIndex[indexNumber]
    
    const rows = await cardapio.getRows()
    
    if (rows.length) {
      return rows.map(({
        Código,
        Produto,
        Unidade,
        Descrição,
        Valor,
        Procedência,
        Categoria
      }) => {
        return {
          Código,
          Produto,
          Unidade,
          Descrição,
          Valor,
          Procedência,
          Categoria
        }
      })
    }
  } catch (err) {
    console.log(err)
  }

  return [];
}

...then feeding it into the page using getStaticProps() function. It worked like a charm once I've got all things setup properly.

// ../pages/unidades/[slug].js
export async function getStaticProps({ params }) {
  const sanityData = await getCardapio(params.slug)

  const indexNumber = sanityData[0].id
  // console.log("index number", indexNumber)
  const produtos = await getCardapioFromSlug(indexNumber)
  const produtosStringfied = JSON.stringify(produtos)
  const produtosArray = JSON.parse(produtosStringfied)
  return {
    props: {
      cardapio: {
        info: sanityData[0] || null,
        items: produtosArray || null
      }

    },
    revalidate: 1
  }
}

The problem is after we changed values for some cells in the source document, the content wasn't automatically updated in the site.

I've tried redeploying (with both build cache on and off) it so the build process would grab the content from the document one more time and update the site, but it didn't worked. One idea was to make a webhook that would be avaiable for the client to run a simple command on his machine and rebuild the page with the new info, but this approach seems to be useless.

I red some articles (this one for instance) on custom webhooks for Google Spreadsheets but I can't really understand how it would trigger something on my page. Don't really think it would actually work.

Now I'm kind of stuck on where should I go. Perhaps I should rewrite my getStaticProps()?

Eduardo Oliveira
  • 395
  • 2
  • 18
  • 1
    Simple options: 1) Fetch cardapio/menu items client side or 2) use getServerSideProps or 3) Push cardapio/menu ODFs alongside your next.js app to Git and read this file instead of Google Sheet. New pushes cause rebuilds. We do this in a Gatsby app, which shouldn't be very different to next.js – Stefan Jan 06 '22 at 17:44
  • 1
    Another option, to keep using `getStaticProps`, is to look into [Incremental Static Regeneration](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration), as it enables you to update static pages without needing to rebuild the entire app. – juliomalves Jan 07 '22 at 19:18
  • @Stefan the first option would cause a large number of fetching instances on google's API, which would be bad. Second one is not an option, because you can't use getServerSideProps with getStaticPaths, with is crucial for this pages to work. The third idea tho, seems a good try. But the whole idea behind this is to keep the source file up and accessible for the client, which would not want to deal with pushes or different tools. Perhaps he can ping me and I download it everytime, updating the ODF and pushing it to github. Not sure yet. Thanks for your input – Eduardo Oliveira Jan 11 '22 at 21:40
  • 1
    @juliomalves I guess that what I'm trying to achieve here. Maybe am doing it wrong. `revalidate` equals to 1 in this sample I brought but it was set to 10 (sec) so new requests would force updates to data on these pages, but it's not working this way. – Eduardo Oliveira Jan 11 '22 at 21:42

1 Answers1

0

The issue has nothing to due with the code itself, but the misuse of the API. The id from the spreadsheet was wrong, still using a prototype which was used as base to the final one the client has. Changed the env var and everything went fine.

Had to force deploy ignoring build cache via vercel cli. Thanks to anyone that spent time commenting and wondering about this issue.

Eduardo Oliveira
  • 395
  • 2
  • 18