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.
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:
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.
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!