Hydrate your Gridsome app: A Vendure example

Unfortunatly shoes are sold out!

For the Pinelab webshops I use Gridsome as static site generator for SEO and speed purposes. The backend used, is the headless GraphQL e-commerce platform Vendure.

TL;DR: Statically generated product overview, client side stock-level hydration: https://github.com/martijnvdbrug/gridsome-vendure-example

What we will do in this blog post:

  • Generate a static page with an overview of products
  • Hydrate the overview on the client with ‘sold-out’ tags for products that are sold out. We do this, so we only have to rebuild the static product overview when products are added, updated or deleted, but not when stock level changes.

Gridsome setup

Create a fresh Gridsome project and add the plugin @gridsome/source-graphql with the following code in gridsome.config.js:

This will merge an existing GraphqQL schema into the Gridsome GraphQL layer under the specified fieldName.

Static product overview page

Now that the Vendure GraphQL schema is available in the Gridsome data layer, we can query this data to show in a page:

Create the file src/pages/Index.vue and add the following query to the page:

Gridsome will execute this query when generating the static HTML pages and make the products available under $page.Vendure.products.items in Vue templates, or under this.$page.Vendure.products.items in javascript.

We can display the data in the Vue template in Index.vue:

Notice the product.soldOut variable, which will always be falsy when generating the static HTML, because we don’t query stock-levels. We are going to solve this by setting the variable soldOut once the page is loaded on the client.

Client side hydration

We only generate static HTML pages when a product is added, updated or deleted, so it could be that a product on the static HTML page is sold out.

To notify our customer that a product is sold out, we are going to query the stock levels of all products when the page is mounted.

The mounted() function is only called when the page is loaded on the client.

Add the following script to Index.vue:

This script queries the Vendure API again, but this time also retrieves productVariant.available to determine if a product is sold out. In the map() function we loop all products, set soldOut to true or false, and set the updated products in this.$page again. Vue will detect the changes and re-render the template, resulting in some products having the label SOLD OUT.

Some products are sold out, some aren’t

Now you have the speed and SEO benefits of static sites and the flexibility of dynamic content!

The complete Index.vue looks like this:

The complete source can be found here: https://github.com/martijnvdbrug/gridsome-vendure-example

And don’t forget to check out the current status of the Pinelab webshops!

Fullstack developing for the web, check out Pinelab.studio for more!