There's not a page yet at /second%20post

Viewed 1469

I have an issue regarding my gatsby site. I am fetching content from contentful and according to the code in my gatsby-node.js it has to generate two pages and it does but only one of them is working when I click on it for the second one it show that

There's not a page yet at /second%20post

I am so confused cause most of the issues asked here telling that they are not able to generate the pages and I don't know if the page is created or not and if it is created then why it shows me the error message and also when got to the error page the

second post

link is given but it is non clickable. all the other code is in my git repository here at Github code

Pleas refer to image for clear understanding at Image here

here is my gatsby-node.js code file

const path = require(`path`)


 exports.createPages = async ({ graphql, actions, reporter }) => {
 const { createPage } = actions;

// Define a template for blog post
 const blogPost = path.resolve(`./src/templates/blog-post-contentful.js`)

// Get all markdown blog posts sorted by date
const result = await graphql(
`
 {
  allContentfulBlockchainlearning{
    edges{
      node{
        slug
        title
        subtitle
        
       
      }
    }
  }
}
`
)

if (result.errors) {
 reporter.panicOnBuild(
  `There was an error loading your blog posts`,
  result.errors
  )
  return
}

 const posts = result.data.allContentfulBlockchainlearning.edges

  // Create blog posts pages
  // But only if there's at least one markdown file found at "content/blog" (defined in gatsby- 
config.js)
  // `context` is available in the template as a prop and as a variable in GraphQL

 if (posts.length > 0) {
  posts.forEach((post, index) => {
  const previousPostSlug = index === 0 ? null : posts[index - 1].id
  const $nextPostSlug = index === posts.length - 1 ? null : posts[index + 1].id

  createPage({
    path: post.node.slug,
    component: blogPost,
    context: {
      slug: post.node.slug,
      previousPostSlug,
      $nextPostSlug,
    },
  })
})
}
}

and here is my blog-post template I want to creat

import React from "react"
import { Link, graphql } from "gatsby"

import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"

const BlogPostTemplate = ({ data, location }) => {
const post = data.contentfulBlockchainlearning
const siteTitle = data.site.siteMetadata?.title || `Title`
const { previous, next } = data

return (
<Layout location={location} title={siteTitle}>
  <SEO
    title={post.title}
    description={post.subtitle}
  />
  <article
    className="blog-post"
    itemScope
    itemType="http://schema.org/Article"
  >
    <header>
      <h1 itemProp="headline">{post.title}</h1>
      <p>{post.date}</p>
    </header>
    <section
      dangerouslySetInnerHTML={{ __html: post.content.raw }}
      itemProp="articleBody"
    />
    <hr />
    <footer>
      <Bio />
    </footer>
  </article>
  <nav className="blog-post-nav">
    <ul
      style={{
        display: `flex`,
        flexWrap: `wrap`,
        justifyContent: `space-between`,
        listStyle: `none`,
        padding: 0,
      }}
    >
      <li>
        {previous && (
          <Link to={previous.slug} rel="prev">Hey There
            ← {previous.title}
          </Link>
        )}
      </li>
      <li>
        {next && (
          <Link to={next.slug} rel="next">
            {next.title} →
          </Link>
        )}
      </li>
    </ul>
    </nav>
  </Layout>
 )
 }

  export default BlogPostTemplate

export const pageQuery = graphql`
query BlogPostBySlug(
$slug: String!
$previousPostSlug: String
$nextPostSlug: String

) {
site {
  siteMetadata {
    title
    
    
  }
}
contentfulBlockchainlearning(slug: {eq: $slug}){
  title
  subtitle
  content{
    raw
  }

}
previous: contentfulBlockchainlearning(slug: { eq: $previousPostSlug}) {
  title 
}

    


next:  contentfulBlockchainlearning(slug: { eq: $nextPostSlug }) {
     title     
    
 
      
  
 }
 }
 `
1 Answers

The issue is simple, you can't create a URL with whitespace like the one you are trying to create. second page should be parsed as second-page since the whitespace between second and page potentially will cause a lot of issues.

Gatsby is creating properly the pages since they appear on the 404 page (under gatsby develop, the 404 page lists all you created pages). However, it doesn't have a valid route because your slugs must be slugified. Ideally, the slug should be fetched with the correct format from the CMS already, however, you can add some controls to avoid this behaviour:

 if (posts) {
  posts.forEach((post, index) => {
  let slugifiedPath= post.node.slug.toLowerCase().replace(/\s/g, '-');
  
  const previousPostSlug = index === 0 ? null : posts[index - 1].id
  const $nextPostSlug = index === posts.length - 1 ? null : posts[index + 1].id

  createPage({
    path: slugifiedPath,
    component: blogPost,
    context: {
      slug: post.node.slug,
      previousPostSlug,
      $nextPostSlug,
    },
  })
})
}

It's quite self-explanatory but, since your paths are being fetched with a wrong format, you need to refactor them by:

  let slugifiedPath= post.node.slug.toLowerCase().replace(/\s/g, '-');

It transforms it to lower case and it replaces all-white spaces globally (/\s/g) using a regular expression for hyphens (-), creating a valid slug.

Related