DEV Community

Daniel Madalitso Phiri
Daniel Madalitso Phiri

Posted on • Originally published at

Event Triggered GraphQL: Making Static Sites Dynamic

I saw this amazing talk by Tanmai Gopal, one of the founders at JAMStack SF, on Making Static React Sites Dynamic .

“I could probably cook up a Vue alternative,” I thought.

My Blog happens to be built with Gridsome, a Vue powered static site generator for building blazing-fast static websites.

I’ve played around with Hasura in the past: it’s a super fast GraphQL server that gives you instant, realtime GraphQL APIs over Postgres. So we’re going to build something with Gridsome, deploy it, and then make a portion of it dynamic (sort of) with GraphQL and Netlify.

I have a list of books I've read in a GraphQL API and I want to use that as a data source for the content on our Gridsome site. We want this site to update dynamically when ever we add a new book to the list or take one out.

I’ll show you how.

TL;DR: Hasura Event Triggers


I left my GraphQL endpoint open for the sake of this tutorial, but it’s not advisable for a production environment.

Have a look at this post on securing your API by adding authorization and managing users.

We’ll start out by installing the Gridsome CLI tool with npm install --global @gridsome/cli .

When that’s done, we create a new Gridsome project with gridsome create <project name>.

After that, we cd <project name> and then run it locally with gridsome develop.

You’ll get a very simple page like this.

Now go to this page and click Deploy to Heroku. You might have to create a new Heroku account.

When that’s sorted, you’ll be prompted to create an app name. Key one in and then click Deploy.

Once it’s deployed, head over to to access your Hasura API Explorer.

It should look this:

On our API Console, we’ll head over to the data section and click add table.

We then create a table called books and go on to create the following columns:

    - `id, Integer (AutoIncrement), Unique`
    - `name, text`
    -`author, text`
Enter fullscreen mode Exit fullscreen mode

Set id as the primary key. Then, click create.

Now that we’ve got a books table, we’ve got to insert data into it.

In the data section, click on the books table and pick the insert data tab. Feel free to add any books and authors you enjoy. Mine looks something like this:

We’re done with the Hasura API console for now.

Next up, we want to be able to query a remote GraphQL source.

First, we need to install the Gridsome source plugin. We’ll enter npm install gridsome-source-graphql to do so. Once that’s done, we need to edit our gridsome.config.js.

We then paste in the following code:

    plugins: [
          use: 'gridsome-source-graphql',
          options: {
            url: '',
            fieldName: 'puppies',
            typeName: 'puppyTypes',

Enter fullscreen mode Exit fullscreen mode

Be sure to change url, fieldName, and typeName (although the latter is optional).

You can get the url from the Hasura API console, i.e

I’ll name fieldType booksList and leave the typeName blank. They’re important, so remember them.

Now let's navigate to the src > pages > About.vue. This is where we want to display the data.

Gridsome uses GraphQL to query data that it displays on pages.

After the closing , we paste the following page query:

    query {
      books {
Enter fullscreen mode Exit fullscreen mode

The query fetches the author, id, and name from the books table. Now we need to display the data we’re querying.

To do so, add the following code below the sole


    <h1>Books Read by Me</h1>
    <div v-for="book in $page.books" v-bind:key="">
       <li>{{ }} - {{ }}</li>
Enter fullscreen mode Exit fullscreen mode

We use $page.books to access the query response and parse through it with the v-for directive, storing each value in the book variable. We then use this to display the book author and book name.

This also happens to be a really nice way of understanding how Gridsome displays data. When we run this locally and click ‘about’, we can see the books and their authors displayed.

If you head back to the Hasura API Console and insert one row into the books table, you’ll notice that the list on the site updates.

This only happens locally because the data source is continuously refreshed.

When you deploy the app, only the data available on deploy is displayed, meaning when we insert a row in the API console it will not show until the site is rebuilt.

To solve this, we’ll leverage Hasura Event Triggers to trigger a Netlify build that will then update the data in your database.

You will need to push your code to GitHub or GitLab and connect your repository to Netlify.

Gridsome put together a great resource to help out if you have any trouble doing so. Check that out here.

Once deployed to Netlify, we need to create a build hook.

I’ll call mine hasura-event-trigger.

When you create one, you get a URL that triggers a build.

Copy this URL and head back to your Hasura API console.

This time, we’ll head over to the events section.

Hasura event triggers capture events on specified tables and invoke webhooks to carry out any custom logic.

Events could be inserts, updates, or deletes on a row. They also give you the flexibility to add manual triggers.

We want to trigger a rebuild whenever we delete or add a book. After clicking ‘create’, we name it ‘author-update’, select the books table, tick ‘insert’, and update as trigger operations.

We’re then asked to add a webhook URL. This is the build hook URL we copied from Netlify.

After pasting that in, click ‘create’.

Now, every time we insert or delete a row (be it manually in the API console or with a mutation using another web app), the event is triggered and a new build will start.

This updates the side content—some would say dynamically.

Add or delete a few rows to trigger builds and your events tab will look like this:

The builds on Netlify also show what triggered them.


Now we have a sort of dynamic static site that leverages Hasura GraphQL Event Triggers.

Check out the full repo on my GitHub and feel free to tweet me any questions.

Top comments (0)