Search code examples
reactjsgraphqlgatsbyslugcontentful

why is my Gatsby dynamic slug not working


I am going to show the code first and link an article I am following. Essentially I keep getting this error code "There's not a page or function yet at /episode-one". Can somebody tell me what is wrong with my file path ? I've tried playing around with the folder structure to match the article but nothing has changed.

This is the code for index.js

folder structure - gatsby-contentful-site\src\episodes/src\episodes\podsode.js src\pages\EpisodeDetails

index page {data.allContentfulPodcast.edges.map(slug => <Link to={${slug.node.slug}}>{slug.node.title} )}

gatsby node.js

const path = require("path")

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const response = await graphql(
      `
      query MyQuery {
        contentfulPodcast {
          slug
          title
        }
      }
      
  `)
   response.data.allContentfulPodcast.edges.forEach(edge => {
createPage({
  path: `/EpisodeDetails/${edge.node.slug}`,
  component: path.resolve("./src/episodes/podsode.js"),
  context: {
    slug: edge.node.slug,
  },
})

}) }

Episode details

function EpisodeDetails ({props}) {
  const data = useStaticQuery 
  (
  graphql `
  query  {
  allContentfulPodcast(sort: {fields: publishedDate, order: DESC}) {
    edges {
      node {
        title
        slug
      }
    }
  }
}

  `)
  
    return (
        <div>
     {data.allContentfulPodcast.edges.map(edge => 
     <h2>
                <Link to={`/EpisodeDetails/${edge.node.slug}/`}>{edge.node.title}</Link>
              </h2>
              )}
        </div>
    )
}

export default EpisodeDetails

podsode.js

export const query = graphql`
  query($slug: String!) {
    contentfulPodcast(slug: { eq: $slug }) {
      title
     
      
    }
  }
`

const podsode = props => {
    return (
        <div>
            <h1>{props.data.contentfulPodcast.title}</h1>
        </div>
    )
}


export default podsode

Solution

  • You are using in the template the query that is supposed to query for all data (episodes) and loop through them to create the dynamic pages and the single query to filter in the gatsby-config.js.

    const path = require("path")
    
    exports.createPages = async ({ graphql, actions }) => {
      const { createPage } = actions
      const response = await graphql(
          `
          query MyQuery {
            contentfulPodcast {
              slug
              title
            }
          }
          
      `)
       response.data.allContentfulPodcast.edges.forEach(edge => {
    createPage({
      path: `/EpisodeDetails/${edge.node.slug}`,
      component: path.resolve("./src/episodes/podsode.js"),
      context: {
        slug: edge.node.slug,
      },
    })
    

    In the snippet above you don't have allContentfulPodcast.edges to loop through, your node is called contentfulPodcast. Test them all in the localhost:8000/___graphql but you should do something like:

    const path = require("path")
    
    exports.createPages = async ({ graphql, actions }) => {
      const { createPage } = actions
      const response = await   (
       graphql `
         query  {
          allContentfulPodcast(sort: {fields: publishedDate, order: DESC}) {
            edges {
              node {
               title
               slug
             }
           }
         }
       }
    `)
    response.data.allContentfulPodcast.edges.forEach(edge => {
      createPage({
        path: `/EpisodeDetails/${edge.node.slug}`,
        component: path.resolve("./src/episodes/podsode.js"),
        context: {
          slug: edge.node.slug,
        },
      })
    

    This should create your episodes based on the queried slug (extracted from all episodes and iterated through them) at localhost:8000//EpisodeDetails/episode-one

    The slug is passed into the template, where you should query the contentfulPodcast.