2

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 Answers1

2

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.

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • Thank you very much and solves the problem but by doing so when I the title of the blog on the main page , it goes to 404 page first and from there by clicking the link I can access the blog page . for instance when i click learn solidity title , the 404 page and then I have to click second-post to access the learn solidity page. – Inaam Ullah Jan 09 '21 at 12:47
  • 1
    This is because all references to the `slug` must be slugified (`toLowerCase().replace(/\s/g, '-')`) since it's not a valid URL. If you point to `` it will thrive to the same issue (the `Second Page` URL is not valid). You should fix the slug in the CMS to avoid that kind of invalid URLs, or using the `slugifiedPath` function everywhere. – Ferran Buireu Jan 09 '21 at 12:56
  • Well I tried both of the ways, updated the slug and did the slgfiedPath everywhere and it is working now perfectly , Thank you – Inaam Ullah Jan 09 '21 at 13:51
  • If the issue has been solved please consider accepting/upvote the answer in order to close the issue. – Ferran Buireu Jan 09 '21 at 14:03