Querying Sanity page data by slug in Gatsby without gatsby-node

13 replies
Last updated: Nov 16, 2020
Hi guys how are you, I have a doubt concerning sanity + Gatsby. I have created a "Page" schema in Sanity, and added a slug field, so let's say I have a Product page with a "product" slug

Now in gatsby, I have some pages which I am not generating via templates, as they are quite different from each other.
In this page, I am using the following query

`export const query = graphql``

query {

pageData: sanityPage(slug: { current: { eq: "product" } }) {

id

seoTitle

intro {

title

logo

}

}

}
```

With which I am able to filter through Sanity page data, hardcoding the "product" slug in graphql filter.

But I don't really know how can I do this query getting each page slug from gatsby, as I am currently not generating them via gatsby-node


Any tips?
AI Update

Based on your question, it sounds like you're working with Gatsby pages that aren't generated through gatsby-node.js templates, and you want to dynamically query Sanity data based on each page's slug without hardcoding it.

The challenge you're facing is that Gatsby's page queries (queries using export const query) are designed to work with page context variables that are typically passed during page creation in gatsby-node.js. Since you're using Gatsby's file system routing instead of programmatic page creation, you don't have access to those context variables.

Here are your options:

Option 1: Create Pages Programmatically (Even with Different Layouts)

Even though your pages have different layouts, you can still use gatsby-node.js to create them programmatically and pass the slug as context. You can use different templates for different page types:

// gatsby-node.js
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  
  const result = await graphql(`
    query {
      allSanityPage {
        nodes {
          slug {
            current
          }
          _id
        }
      }
    }
  `)

  result.data.allSanityPage.nodes.forEach(page => {
    createPage({
      path: `/${page.slug.current}`,
      component: require.resolve(`./src/templates/${page.slug.current}-template.js`),
      context: {
        slug: page.slug.current,
      },
    })
  })
}

Then in your template file, you can use the context variable:

export const query = graphql`
  query($slug: String!) {
    pageData: sanityPage(slug: { current: { eq: $slug } }) {
      id
      seoTitle
      intro {
        title
        logo
      }
    }
  }
`

If you're on Gatsby 4+, you can use the File System Route API with collection routes. Create a file like src/pages/{SanityPage.slug__current}.js:

import React from 'react'
import { graphql } from 'gatsby'

export const query = graphql`
  query($id: String!) {
    sanityPage(id: { eq: $id }) {
      id
      seoTitle
      intro {
        title
        logo
      }
    }
  }
`

const PageTemplate = ({ data }) => {
  return // your component
}

export default PageTemplate

This automatically creates pages for all your Sanity pages and provides the correct query variables. If you need different layouts, you can conditionally render components based on the slug or add a page type field in your Sanity schema.

Option 3: Use useStaticQuery and Filter

If you have a small number of pages, you could query all pages and filter in your component:

import { useStaticQuery, graphql } from 'gatsby'

const ProductPage = () => {
  const data = useStaticQuery(graphql`
    query {
      allSanityPage {
        nodes {
          slug {
            current
          }
          id
          seoTitle
          intro {
            title
            logo
          }
        }
      }
    }
  `)
  
  const pageData = data.allSanityPage.nodes.find(
    page => page.slug.current === 'product'
  )
  
  return // your component
}

This works but isn't ideal for performance since you're querying all pages on every page.

For your specific use case, I'd recommend Option 2 (File System Route API) if you're on Gatsby 4+, as it gives you the dynamic querying you need while keeping your pages file-based. If you need completely different layouts, you can either use conditional rendering within the template or stick with Option 1 and create pages programmatically with different template files.

Show original thread
13 replies
I’m not sure I understand what you’re trying to do. Are you trying to dynamically generate a page in Gatsby for every “Page” document you have in Sanity?
No, quite the contrary, I am not generating them dynamically in gatsby
In my "Page" document in Sanity, let's say i have a "product" and a" pricing" document, and they have a title field and a slug field.

So, in Gatsby, in /pages, i have a "product" file, I want to bring my title field only concerning to my "product" page, filtering out the rest

In order to do this, I reckoned I could do it filtering by slug. So I did that graphql query and it works

My question, more related to gatsby I think, would be, how can I dinamically get every page slug, in order to work out that filter
I hope I am a bit clearer now
Does something like this not work?
{
  allSanityPage(
    filter: {
      slug: {current: {eq: "product"}}
    }
  ) {
    edges {
      node {
        id
        seoTitle
        intro
      }
    }
  }
}
Hello Patrick, thank you for your response, yes, that does work
But my problem is that I would like not to hardcode that "eq: product", so my doubt is how do I get my current page slug in gatsby, so I can use it in that query dynamically instead of hardcode it
do I make sense?
Something like..
`export const query = graphql``

query($slug: String!) {

pageData: sanityPage(slug: { current: { eq: $slug } }) {

id

seoTitle

intro {

title

logo

}

}

}
```

I don't know how would I do to get this $slug on each of my pages
You could use the path variable that created on the contex object for the Gatsby pages
Do I have access to this context even if I didn't dynamically created the pages via gatby-node?
I just created each page on gatsby /pages folder
Yeah you should be able to access the $path variable inside of the page query for each of those pages
Alright, I will check it out
thanks!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?