Building With Gatsby and Prismic ~ Filtering Front to Back

Kahilnayton
The Startup
Published in
4 min readJul 23, 2020

--

Often times you’ll have a fairly complicated assortment of resources to filter through on the front end. I’m going to walk you through our approach to filtering through a resource room with Prismic and Gatsby. If you’re new to Prismic or Gatsby be sure to check out their excellent docs to get started.

Templates

Templates to the rescue! If we structure our CMS in a thoughtful way then we can abstract away a lot of the complexity of filtering on the front-end. In Prismic you’ll need to create a repeatable content type of category and assign a category for each blog. Or in traditional back end speak there needs to be a one-to-many relationship between blogs and categories. This way we’re able to assign the data with its own designated end point for each category. Let’s explore how.

Here’s an example of how a blog content type could look. The essential take away here is including a unique uid, which we will use for our routing and dynamic page generation.

In our application we’re going to generate templates with the help of gatsby-source-prismic-graphql

I would recommend this plugin over gatsby-source-prismic because it comes with content previewing right out of the box, which is a pretty essential feature if your client is not tech savvy and are going to be updating the application independently.

gatsby-config.js

resolve: 'gatsby-source-prismic-graphql',options: {  repositoryName: '<your-repo-name>',  path: '/preview',  previews: true,  pages: [   {    type: 'Post',    match: '/post/:uid',    path: '/post-preview',    component: require.resolve('./src/templates/post.js'),},

The pages attribute is what finds all our uid’s and dynamically creates our routes. Here’s what the post.js template could look like:

import React from 'react';import { graphql } from 'gatsby';import SEO from 'components/SEO';import Layout from 'components/Layout';const PostPage = (props) => {   const post = props.data.prismic.postByUID;   if(!post) {   return null;   }return (  <Layout>   ... <render your post data>  </Layout>  );}export default PostPage;
export const query = graphql`query getPost($uid: String!) { prismic { post(uid: $uid, lang: "en-us") { _meta {...

GraphQL

Our qraphql query is set up to take a uid as a parameter and fetch the corresponding data depending on what uid is passed in.

Now that we have all our posts rendered as their own page we can move on to the categories and define a template for those.

gatsby-config-js

{type: 'Category',match: '/post/:uid',path: '/category-preview',component: require.resolve('./src/templates/category.js'),},

Again the important take away is the uid that we’re passing into our graphql query.

const postQuery = graphql`query getCategoryPosts($first: Int = 12, $after: String, $id: String!) {   prismic {   allPosts(first: $first, after: $after, sortBy: publish_date_DESC,      where: {category: $id}) {   edges {node {

The where keyword in graphql defines the condition for the data we are querying so the above code will define an endpoint for each category and fetch all blog posts that are under that category.

Front End Filtering

If you have a second factor to sort by then we’ll need to take this one step further and drill into each section on the front end.

Let’s create a select element and use the handle change to trigger a filterByType() method. There will of course have to be a type associated with each of our blog posts so make sure you have that set up in your CMS.

Here we’re taking the target from the select and beginning the filtering process:

async filterFunction(type) {   if (type === 'all') {   await this.setState({    filteredBlogs: this.state.blogs,    type: null,  });} else {  await this.setState({filteredBlogs: this.state.blogs.filter(blog =>     blog.node.blog_type._meta.uid === type && blog.__typename === 'ResourceConnectionEdge),type,});}await this.setCurrentBlogs();}...

Since the data is going to be a changing variable we need to first set the state with the blogs by category.

The setCurrentBlogs() method is going to asynchronously splice, depending on how many blogs we want to see per page, and set the state with the newBlogs.

async setCurrentBlog() {
...
await this.setState({currentBlogs: this.state.filteredBlogs.slice(this.state.firstBlog, this.state.lastBlog),loaded: true,})}

That’s pretty much it! Now you have the filtered blogs in state that are going to change dynamically in your render method in a clean and concise way. You can check out the finished product here.

Filtering a complicated resource room for a client can take a bit of planning at times, but with the right setup on the backend, graphql, React and a bit of es6 thrown in you can get it together is a pretty readable and maintainable way.

The author of this tutorial is Kahil Nayton, a full stack developer at Ronik, a creative digital agency based out of Brooklyn NYC.

--

--

Kahilnayton
The Startup

Full stack developer based out of Brooklyn, NYC.