Wednesday, March 22, 2023
HomeReactuse GraphQL in Gatsby

use GraphQL in Gatsby


Gatsby is an open-source framework primarily based on React that helps construct web sites and apps. It means that you can construct your web site and apps utilizing React after which generates HTML, CSS, and JS while you construct for manufacturing.

One of many many benefits of utilizing Gatsby is that it permits accessing information by a question language known as GraphQL. GraphQL is a question language for APIs that gives an entire and comprehensible description of the information in your API, provides shoppers the ability to ask for precisely what they want and nothing extra. Gatsby makes use of GraphQL as a result of it gives the next:

  • Specificity: Request solely the information wanted and never no matter is returned by the API.
  • Static Construct: Carry out information transformations at construct time inside GraphQL queries.
  • Standardized: It is a performant information querying language for the customarily complicated/nested information dependencies.

If you’re , you’ll be able to learn extra about why Gatsby makes use of GraphQL. On this article, I will share some helpful ideas for when utilizing GraphQL in a Gatsby undertaking.

Create Gatsby Pages from GraphQL Question

By default, pages/routes in Gatsby are created by creating a brand new file within the src/pages folder i.e creating an about.js file means making a web page at /about. Nonetheless there’s one other methodology to creating pages, and that is utilizing the createPage motion along with the createPages API to programmatically create pages. This methodology additionally gives you with extra choices when creating these pages equivalent to customizing the web page’s slug.

const path = require('path')

exports.createPages = ({ graphql, actions }) => {

const { createPage } = actions

const ShopPage = path.resolve(`src/parts/shop-page.js`)

createPage({

path: "/retailer",

element: ShopPage,

context: {},

})

}

Within the code snippet above, the createPage motion is used to create a web page at /retailer. The createPage motion accepts a number of arguments however I will give attention to the next arguments:

  • path – That is the relative URL of the web page and will at all times begin with a slash.
  • element – That is the trail to the React element which is used as template for this web page.
  • context – That is an object that may include any information to be handed right down to the React element as .

Basically createPage helps us in every single place the place we have to create pages dynamically. A extra sensible use for the createPage motion could be creating a number of pages for every article in a publication web site. It is the perfect methodology for this use case as a result of it permits creating a number of pages programmatically from an exterior supply. It is also a very good choice as a result of we may use the information gotten from the exterior supply to create permalinks/paths for the pages. Let’s check out an instance:

const path = require('path')

exports.createPages = ({ graphql, actions }) => {

const { createPage } = actions

const ArticlePage = path.resolve(`src/parts/article-page.js`)

return new Promise((resolve, reject) => {

resolve(

graphql(

`{

articles: allArticles {

edges {

node {

id

slug

title

class {

slug

}

}

}

}

}`,

).then(end result => {

end result.information.articles.edges.forEach(edge => {

createPage({

path: `${edge.node.class.slug}/${edge.node.slug}`,

element: ArticlePage,

context: {

slug: edge.node.slug

},

})

})

}),

)

}

Within the code above, we’re querying a (fictional) exterior GraphQL supply to fetch article entries. The question physique comprises the properties that we would need to be returned within the end result which might be helpful in setting up the permalink.

The end result gotten again from the question is then used to create the pages by looping by the end result and utilizing the article’s property to create a path for the web page.

One other helpful tip for when creating pages programmatically is extracting the createPage actions simply in case they’re lots for the gatsby-node.js file. It helps to declutter the file and make the code extra readable.

This often occurs when there are a number of queries and a number of pages to be created. See the code snippet beneath for example:

const path = require('path')

exports.createPages = ({ graphql, actions }) => {

const { createPage } = actions

const ArticlePage = path.resolve(`src/parts/article-page.js`)

const AuthorPage = path.resolve(`src/parts/author-page.js`)

const ProductPage = path.resolve(`src/parts/product-page.js`)

return new Promise((resolve, reject) => {

resolve(

graphql(

`{

articles: allArticles {

edges {

node {

id

slug

title

class {

slug

}

}

}

}

authors: allAuthors {

edges {

node {

id

slug

identify

bio

}

}

}

merchandise: allProducts {

edges {

node {

id

slug

title

}

}

}

}`,

).then(end result => {

end result.information.articles.edges.forEach(edge => {

createPage({

path: `${edge.node.class.slug}/${edge.node.slug}`,

element: ArticlePage,

context: {

slug: edge.node.slug

},

})

})

end result.information.authors.edges.forEach(edge => {

createPage({

path: `${edge.node.slug}`,

element: AuthorPage,

context: {

slug: edge.node.slug

},

})

})

end result.information.merchandise.edges.forEach(edge => {

createPage({

path: `${edge.node.slug}`,

element: ProductPage,

context: {

slug: edge.node.slug

},

})

})

}),

)

}

The code snippet above is just like the primary one we created, with the addition of extra queries to fetch extra information. If we proceed including queries and createPage actions at this fee, the gatsby-node.js would grow to be cluttered and a really lengthy file to scroll by.

A doable repair could be to extract the createPage actions to particular person information for every of the pages that you just’d wish to create within the Gatsby undertaking. This implies creating page-specific helpers to handle every web page, fairly than placing all pages in the identical place. The tip end result needs to be that the file is fairly declarative for every Gatsby hook that it implements:

const path = require('path')

module.exports = (createPage, edge) => {

const ArticlePage = path.resolve(`src/parts/article-page.js`)

createPage({

path: `${edge.node.class.slug}/${edge.node.slug}`,

element: ArticlePage,

context: {

slug: edge.node.slug

},

})

}

const path = require('path')

module.exports = (createPage, edge) => {

const AuthorPage = path.resolve(`src/parts/author-page.js`)

createPage({

path: `${edge.node.class.slug}/${edge.node.slug}`,

element: AuthorPage,

context: {

slug: edge.node.slug

},

})

}

const path = require('path')

module.exports = (createPage, edge) => {

const ProductPage = path.resolve(`src/parts/product-page.js`)

createPage({

path: `${edge.node.class.slug}/${edge.node.slug}`,

element: ProductPage,

context: {

slug: edge.node.slug

},

})

}

The three code snippets above are page-specific helper features; createArticlePages, createAuthorPages, and createProductPages which can assist to create the article pages, writer pages, and product pages respectively. Additionally they settle for an argument of the createPage motion itself and an edge object that comprises the information wanted for creating the trail.

The brand new helper features can then be used within the gatsby-node.js file like this.

import createArticlePages from './createArticlePages'

import createAuthorPages from './createAuthorPages'

import createProductPages from './createProductPages'

exports.createPages = ({ graphql, actions }) => {

const { createPage } = actions

return new Promise((resolve, reject) => {

resolve(

graphql(

`{

articles: allArticles {

edges {

node {

id

slug

title

class {

slug

}

}

}

}

authors: allAuthors {

edges {

node {

id

slug

identify

bio

}

}

}

merchandise: allProducts {

edges {

node {

id

slug

title

}

}

}

}`,

).then(end result => {

end result.information.articles.edges.forEach(edge => {

createArticlePages(createPage, edge)

})

end result.information.authors.edges.forEach(edge => {

createAuthorPages(createPage, edge)

})

end result.information.merchandise.edges.forEach(edge => {

createProductPages(createPage, edge)

})

}),

)

}

This implementation helps to guarantee that the gatsby-node.js file stays decluttered and straightforward to learn.

Web page question vs StaticQuery

Gatsby gives you with two strategies for fetching information utilizing GraphQL – Web page Question and StaticQuery. Web page question is a technique that means that you can use the graphql tag in your React parts to fetch information. The StaticQuery is a technique in which you’ll be able to the useStaticQuery React Hook to carry out queries in your React element:

import { graphql } from 'gatsby'

import React from 'react'

const ArticlePage = ({ information }) => {

return (

{information.edges.map(article, index) => (

<h2>{article.title}</h2>

<p>{article.snippet}</p>

)}

)

}

export default ArticlePage

export const question = graphql`

question Articles($locale: String!) {

articles: allArticles(

filter: { locale: { eq: $locale } }

) {

edges {

node {

id

title

snippet

locale

publishDate

}

}

}

}

`

import { graphql, useStaticQuery } from 'gatsby'

import React from 'react'

const ArticlePage = ({ information }) => {

const information = useStaticQuery(graphql`

question Articles {

edges {

node {

id

title

snippet

locale

publishDate

}

}

}

`)

return (

{information.edges.map(article, index) => (

<h2>{article.title}</h2>

<p>{article.snippet}</p>

)}

)

}

export default ArticlePage

The primary distinction between each strategies is that web page queries have entry to the web page context, which is outlined in the course of the createPage and this basically signifies that web page queries can settle for GraphQL variables. Static queries shouldn’t have this function.

One other distinction between them is that static queries can be utilized anyplace in any element however web page queries can solely be used on pages that are used as element property within the createPage operate.

Utilizing GraphQL fragments in Gatsby

When utilizing GraphQL in Gatsby, it is almost certainly you will be in a state of affairs the place you have used a specific question a few instances throughout a number of parts. Fortunately there is a function in GraphQL known as fragments that assist you to create a set of fields after which embody them in queries the place they’d be used.

Fragments additionally assist to transform complicated queries into a lot smaller and modular queries. In a approach it is just like exporting a operate from a helper file after which reusing that operate in a number of parts:

export const question = graphql`

fragment AuthorInfo on AuthorEntry {

id

identify

slug

twitter

locale

}

`

The code snippet above is an instance of a fraction file in a Gatsby undertaking. The question above fetches particulars about an writer and we’re assuming that this question has been written a few instances all through the codebase.

Fragments will be created in any GraphQL question however I discover it higher to create the question individually in a brand new file. There are 3 key components in a fraction; the fragment’s identify, the GraphQL sort it is going to be used on and the precise physique of the question.

Utilizing the instance above, AuthorInfo is the identify of the fragment and what will probably be used to reference it in different parts. AuthorEntry is the GraphQL sort and the physique is the thing values.

After getting this file created, all it’s essential to do is use the fragment anyplace within the Gatsby undertaking:

import { graphql } from 'gatsby'

import React from 'react'

const ArticlePage = ({information}) => {

}

export const question = graphql`

question FetchArticle {

article {

id

slug

title

publishDate

writer {

...AuthorInfo

}

}

}

`

There is no must import the file or fragment earlier than utilizing it as a result of Gatsby already is aware of to preprocess all GraphQL queries while compiling the location.

GraphQL Fragments in Gatsby with TypeScript

In case you use TypeScript in your Gatsby undertaking, you can too outline varieties when creating your GraphQL fragment. Which means wherever you’ll use your fragment, you need to use its sort to make sure that you are getting what’s anticipated. Utilizing the code snippet beneath for example:

import { graphql } from 'gatsby'

export interface AuthorInfoFragment {

id: string

identify: string

slug: string

twitter: string

locale: string

}

export const question = graphql`

fragment AuthorInfo on AuthorEntry {

id

identify

slug

twitter

locale

}

`

Within the code snippet above, there is a GraphQL fragment known as AuthorInfo and an interface known as AuthorInfoFragment, each of that are exported. These two can then be utilized in one other element to question GraphQL and examine for sort security respectively. Utilizing the code snippet beneath for example, we try to fetch an article entry utilizing the GraphQL question on the backside.

import { graphql } from 'gatsby'

import React from 'react'

import { AuthorInfoFragment } from 'AuthorInfo.fragment.ts'

interface Props {

information: {

article: {

id: string

slug: string

title: string

publishDate: string

writer: AuthorInfoFragment

}

}

}

const ArticlePage = ({information}) => {

}

export const question = graphql`

question FetchArticle {

article {

id

slug

title

publishDate

writer {

...AuthorInfo

}

}

}

`

Included within the question is the writer property which makes use of the AuthorInfo fragment, and we’re additionally type-checking the content material of writer within the Prop TypeScript interface.

GraphQL Playground for Gatsby

Everytime you run your Gatsby web site in improvement mode, it additionally launches GraphiQL, an in-browser IDE, to discover your web site’s information and schema at localhost:8000/___graphql:



Prisma GraphQL

Nonetheless, there’s an alternative choice to GraphiQL, and that is the GraphQL Playground by Prisma. It means that you can work together with all the information, schemas added by extra Gatsby plugins. GraphQL Playground makes use of parts of GraphiQL beneath the hood however is actually a extra highly effective GraphQL IDE that permits higher improvement workflows. The GraphQL Playground additionally provides extra options like:

  • Interactive, multi-column schema documentation.
  • A number of Tabs identical to you’d have in an IDE.
  • Customizable HTTP headers.
  • Question historical past.

To make use of the GraphQL Playground in your Gatsby undertaking, edit the develop script within the package deal.json file:

"develop": "GATSBY_GRAPHQL_IDE=playground gatsby develop",

In case you’re on Home windows then the script ought to seem like this and likewise set up the cross-env package deal:

"develop": "cross-env GATSBY_GRAPHQL_IDE=playground gatsby develop"

As soon as you have modified the script, you’ll be able to then run yarn develop to run the location in improvement mode and likewise launch the brand new GraphQL Playground.



GraphQL Playground


These are a number of the issues I’ve learnt while working with Gatsby and GraphQL and you may learn extra about each applied sciences right here. If in case you have any helpful Gatsby + GraphQL ideas, please share them beneath within the feedback!

RELATED ARTICLES

Most Popular

Recent Comments