skip to Main Content

I read the documentation and tried several tutorials, but I am stuck on fetching custom post types with GatsbyJS.

I tried several approaches, but none of them are working as expected. I always receive a 404.

This is a part of the snippet I am using, which works fine with pages and posts, but not with a custom post type.
The projects pages should be created under a project subfolder/path. Like: example.com/project/my-first-project

The part of the gatsby-node.js looks like that:

const createSinglePages = async ({ posts, gatsbyUtilities }) =>
  Promise.all(
    posts.map(({ previous, post, next }) =>
      // createPage is an action passed to createPages
      // See https://www.gatsbyjs.com/docs/actions#createPage for more info
      gatsbyUtilities.actions.createPage({
        // Use the WordPress uri as the Gatsby page path
        // This is a good idea so that internal links and menus work 👍
        path: post.uri,

        // use the blog post template as the page component
        component: path.resolve(
          `./src/templates/${post.__typename.replace(`Wp`, ``)}.js`
        ),

        // `context` is available in the template as a prop and
        // as a variable in GraphQL.
        context: {
          // we need to add the post id here
          // so our blog post template knows which blog post
          // the current page is (when you open it in a browser)
          id: post.id,

          // We also use the next and previous id's to query them and add links!
          previousPostId: previous ? previous.id : null,
          nextPostId: next ? next.id : null,
        },
      })
    )
  );

The src/template/project.js file looks like this:

import React from "react";
import { Link, graphql } from "gatsby";
import Image from "gatsby-image";
import parse from "html-react-parser";

import Layout from "../components/Layout";
import Seo from "../components/Seo";

const ProjectTemplate = ({ data: { post } }) => {
  const featuredImage = {
    fluid: post.featuredImage?.node?.localFile?.childImageSharp?.fluid,
    alt: post.featuredImage?.node?.alt || ``,
  };

  return (
    <Layout>
      <Seo title={post.title} description={post.excerpt} />

      <article
        className="blog-post"
        itemScope
        itemType="http://schema.org/Article"
      >
        <header>
          <h1 itemProp="headline">{parse(post.title)}</h1>
          <p>{post.date}</p>

          {/* if we have a featured image for this post let's display it */}
          {featuredImage?.fluid && (
            <Image
              fluid={featuredImage.fluid}
              alt={featuredImage.alt}
              style={{ marginBottom: 50 }}
            />
          )}
        </header>

        {!!post.content && (
          <section itemProp="articleBody">{parse(post.content)}</section>
        )}
      </article>
    </Layout>
  );
};

export default ProjectTemplate;

export const pageQuery = graphql`
  query ProjectById(
    # these variables are passed in via createPage.pageContext in gatsby-node.js
    $id: String!
  ) {
    # selecting the current post by id
    post: wpProject(id: { eq: $id }) {
      id
      content
      title
      date(formatString: "MMMM DD, YYYY")
      featuredImage {
        node {
          altText
          localFile {
            childImageSharp {
              fluid(maxWidth: 1000, quality: 100) {
                ...GatsbyImageSharpFluid_tracedSVG
              }
            }
          }
        }
      }
    }
  }
`;

Is the Gatsby API creating a subfolder automatically, or do I need to define that somewhere for each post type?

Any help appreciated!

2

Answers


  1. You define the "subfolder" under the path field in:

      gatsbyUtilities.actions.createPage({
            path: post.uri,
                component: path.resolve(
              `./src/templates/${post.__typename.replace(`Wp`, ``)}.js`
            ),
    
            context: {
              id: post.id,
              previousPostId: previous ? previous.id : null,
              nextPostId: next ? next.id : null,
            },
          })
    

    You just need to do something like:

    path: `projects/${post.id}`
    

    Check the slashes and trailing slashes here.

    You cna replace projects for your dynamic project type if you fetch that information for a more automatic approach (assuming it’s post.__typename).

    Login or Signup to reply.
  2. In order to use Custom Post Types with WPGraphQL, you must configure the Post Type to show_in_graphql using the following field:

    show_in_graphql : true

    While Registering a new Custom Post Type
    This is an example of registering a new "docs" post_type and enabling GraphQL Support.

    add_action( 'init', function() {
       register_post_type( 'docs', [
          'show_ui' => true,
          'labels'  => [
            //@see https://developer.wordpress.org/themes/functionality/internationalization/
            'menu_name' => __( 'Docs', 'your-textdomain' ),
          ],
          'show_in_graphql' => true,
          'hierarchical' => true,
          'graphql_single_name' => 'document',
          'graphql_plural_name' => 'documents',
       ] );
    } );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search