Working with Gridsome
Gridsome is a static site generator for users who want to integrate content pulled from a GraphQL API into their static site's build process.
In this doc, we'll show you how to integrate a GraphQL API with Gridsome.
The first step will be creating a project; you need a API Endpoint and API Key to connect your GraphQL API to your Gridsome project. Follow our guide to learn how to create a project. Already have one? Continue below to connect it to your Gridsome project.
Getting your project information
To connect to your project, you need your API Endpoint and an API key.
If you haven't created a project yet, follow this guide to do so.
If you already have a project, your API Endpoint will be in the admin UI. In the home tab, look for the "Useful Snippets" section.
Copy the API Endpoint and save it somewhere secure.
To get an API Key, you'll have to create one. Read our docs on creating an API Key here.
Connecting your project
Once you have your API Endpoint, and have access to an API Key with dev
permissions (see our API Key docs for more information), then you're ready to start.
Gridsome has a <page-query>
component that allows you to add GraphQL queries directly into your page components. You can then display whatever data you pull from the API, and this can all be done at build time.
Let's get started.
Protecting your project information
To keep your API Endpoint and API key safe, it's best to use environment variables.
Install the dotenv node package to use environment variables in the build script you'll be making. Go to the terminal in your project directory and enter npm i dotenv
.
Now in the root of your project directory, create a file called .env.
Inside, you will define your API Key and API Endpoint as variables:
API_ENDPOINT=YourEndpointHere
API_KEY=YourApiKeyHere
Now you can use this data in your Gridsome build process without risk of exposing it to the public.
Creating a Gridsome Project
Follow along with this guide by checking out our starter project repo. Our starters let you instantly deploy a pre-configured project.
To get started, install gridsome with the below command in your terminal:
npm install --global @gridsome/cli
Now navigate to a folder where you'd like to store your project directory, and enter the following command:
gridsome create my-gridsome-project
Open your project directory in your favorite IDE, or change directories into it.
Creating your Gridsome Server file
To get started, you'll need to add a file called gridsome.server.js
to the root of your project.
This file exports a function that fetches data from your GraphQL API. Your project data will then be added to the build process for your site. For now, we'll just export an empty function:
module.exports = function(api) {
//Our query code will go here
}
At the top of the module, we'll add the code required to configure dotenv, so we have access to environment variables. We'll also add the node-fetch library, which we'll need to request data from our project.
If you don't already have node-fetch installed, enter npm i node-fetch
into your terminal. The code for requiring both of these packages is below
require('dotenv').config()
const fetch = require('node-fetch')
module.exports = function(api) {
//Our query code will go here
}
To add the data fetched from GraphQL API to your project, we need to use the api.loadSource()
hook from Gridsome's Server API.
Within that hook, you'll create a 'collection', which is just a Gridsome data structure that represents the data you'll be querying from the GraphQL API. In this example, we want a list of products from an ecommerce API.
So let's create a collection called ProductList
, and keep it in an object called products
.
module.exports = function(api) {
api.loadSource(async actions => {
const products = actions.addCollection('ProductList')
})
}
Once you have a variable to hold your collection, it's time to do a fetch request to your project's GraphQL API. Your API endpoint will be of this format: api.takeshape.io/project/PROJECT-ID/graphql
You'll use your API Key as a Bearer Token for authorization. See the code below for a detailed example:
module.exports = function(api) {
api.loadSource(async actions => {
const products = actions.addCollection('ProductList')
const result = await fetch(process.env.API_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.API_KEY}`,
accept: "application/json",
},
body: JSON.stringify({
query: `query {
getProductList {
items {
_id
name
price
}
}
}`,
}),
});
const resultJSON = await result.json();
})
}
In the above code, you may have noticed that in the body of the fetch request, the main property is query
. This is the property used to read your GraphQL query.
Your query must already be defined in your schema. Read our Schema docs for more information. In this example, we just want the name and price of every item in our product list.
After converting the query's result to JSON as shown above, add a for ... of
loop that cycles through and converts the items returned from the GraphQL API into nodes in your ProductList
collection.
After converting your fetch result to json as shown above, add the below code to your api.loadSource()
hook:
const resultJSON = await result.json();
for (const item of resultJSON.data.getProductList.items){
products.addNode({
_id: item._id,
name: item.name,
description: item.price,
})
}
And you're all connected. You can access your data with Gridsome's Page API. Read on to learn more about how to pull that data into your Gridsome components. Below you'll find the full gridsome.server.js
script for this example:
require('dotenv').config()
const fetch = require('node-fetch')
module.exports = function(api) {
api.loadSource(async actions => {
const products = actions.addCollection('ProductList')
const result = await fetch(process.env.API_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.API_KEY}`,
accept: "application/json",
},
body: JSON.stringify({
query: `query {
getProductList {
items {
_id
name
price
}
}
}`,
}),
});
const resultJSON = await result.json();
for (const item of resultJSON.data.getProductList.items){
products.addNode({
_id: item._id,
name: item.name,
price: item.price,
})
}
})
}
Adding your data to your Gridsome components
Gridsome allows you to make GraphQL queries from within your page components using the <page-query>
tags. Below is an example of how you could query your data from within a component using <page-query>
:
<page-query>
query {
products: allProductList {
edges {
node {
_id
name
price
}
}
}
}
</page-query>
The above code executes the allProductList
query, then assigns what it returns to products
. The edges
and node
properties give us access to the data we specified in our query to the GraphQL API back in the gridsome.server.js
file.
The method is called allProductList
because that's the query name Gridsome automatically generates. If your collection is called ProductList
, then to query all items within it, you must call allProductList
. If you collections was called ExampleQuery
, you would call allExampleQuery
. To learn more, check out the gridsome docs.
Finally, to access your data, you'll find it in Gridsome's $page
object. Here's how you would render divs for every item you received from the GraphQL API, filling them out with your product information.
<template>
<div>
<h1>Products</h1>
<div v-for="edge in $page.products.edges" :key="edge.node._id">
<p>
<b>{{ edge.node.name }}</b>
<span>{{ edge.node.price }}</span>
</p>
</div>
</div>
</template>
In the above code, each item pulled from the GraphQL API is represented as an edge
. The node
property gives us access to that edge's data, and we can reference the properties we defined in our gridsome.server.js
script.
For more information, read about Gridsome GraphQL queries in their docs.
Here's the final index.vue
file.
<template>
<div>
<h1>Products</h1>
<div v-for="edge in $page.products.edges" :key="edge.node._id">
<p>
<b>{{ edge.node.name }}</b>
<span>{{ edge.node.price }}</span>
</p>
</div>
</div>
</template>
<page-query>
query {
products: allProductList {
edges {
node {
name
_id
price
}
}
}
}
</page-query>
<script>
import { Pager } from 'gridsome';
import PostSummary from '~/components/PostSummary.vue'
export default {
components: {
Pager,
PostSummary
}
}
</script>
Just enter npm run develop
to start your project.
And here's what the page should look like after you run it:
And that's it. You're ready to incorporate data from your GraphQL API into your Gridsome site.
Still need help? Get in touch with us.