Gatsby: createPages seems to be using the wrong template

Created on 8 Jul 2020  路  4Comments  路  Source: gatsbyjs/gatsby

I'm developing a blog about astrology and I'm trying to create pages for blog articles, and for monthly horoscope articles,
this is my gatsby-node.js :

const path = require("path")
const { graphql } = require("gatsby")

exports.createPages = async ({ actions: { createPage }, graphql }) => {
  const allArticles = await graphql(`
    query articleInfo {
      allStrapiArticle {
        nodes {
                    title
          slug
          content
          id
          author {
            name
            avatar {
              publicURL
            }
          }
          categories {
            name
          }
          cover {
            publicURL
          }
          created_at(formatString: "dddd, MMMM Do YYYY")
          title
          content
          id
        }
      }
    }
  `).then(result => result.data.allStrapiArticle.nodes)

  allArticles.forEach(
    ({
      id,
      title,
      slug,
      content,
      cover,
      author,
      categories,
      created_at,
    }) => {
      createPage({
        path: `/articles/${slug}`,
        component: require.resolve("./src/templates/article"),
        context: {
          id,
          title,
          content,
          cover,
          author,
          categories,
          created_at,
        },
      })
    }
  )

  const allHoroscopes = await graphql(`
    query horoscopeArticles {
      allStrapiArticle(
        filter: { categories: { elemMatch: { name: { eq: "Horoscopes" } } } }
      ) {
        nodes {
          horoscope
          title
          slug
          content
          id
          author {
            name
            avatar {
              publicURL
            }
          }
          categories {
            name
          }
          cover {
            publicURL
          }
          created_at(formatString: "dddd, MMMM Do YYYY")
          title
          content
          id
        }
      }
    }
  `).then(result => result.data.allStrapiArticle.nodes)

  allHoroscopes.forEach(
    ({
      id,
      title,
      slug,
      content,
      horoscope,
      cover,
      author,
      categories,
      created_at,
    }) => {
      createPage({
        path: `/horoscopes/${slug}`,
        component: require.resolve("./src/templates/horoscopes"),
        context: {
          id,
          title,
          content,
          horoscope,
          cover,
          author,
          categories,
          created_at,
        },
      })
    }
  )
}

the first createPage instance uses the articles templates and it works just fine, but the second instance is supposed to use the horoscopes template but it's apparently still using the articles template, because of the way the pages are rendered and their HTML. Any idea why is this happening?

My article template

import React from "react"
import Article from "../components/article"

export default props => {
  return (
    <Article
      title={props.pageContext.title}
      content={props.pageContext.content}
      author={props.pageContext.author.name}
      category={props.pageContext.categories
        .map(category => category.name)
        .toString()
        .replace(/,/g, ", ")}
      date={props.pageContext.created_at}
      cover={props.pageContext.cover.publicURL}
    />
  )
}

it uses an Article component

import React from "react"
import Layout from "./layout"
import { Link } from "gatsby"

import ReactMarkdown from "react-markdown"
import "./styles/article.css"

const Article = ({
  title,
  content,
  author,
  category,
  date,
  cover,
  authorPath,
  categoryPath,
}) => (
  <Layout>
    <div className="header">
      <img src={cover} />
    </div>
    <h2 className="title shadow">
      {title} Generated with the Article template
    </h2>
    <div className="article-container">
      <p className="content">
        <ReactMarkdown source={content} />
      </p>
      <h6 className="author-date">
        Posted by <Link to={authorPath}>{author}</Link> on {date} in{" "}
        <Link to={categoryPath}>{category}</Link>
      </h6>
    </div>
  </Layout>
)

export default Article

I`ve added a "Generated with the Article template" next to the title to confirm my suspicions that the horoscopes pages were being generated with the wrong template

Horoscopes template

import React from "react"
import Horoscopes from "../components/article"

export default props => {
  return (
    <Horoscopes
      title={props.pageContext.title}
      foreword={props.pageContext.content}
      aries_horoscope={props.pageContext.horoscope.aries_horoscope}
      taurus_horoscope={props.pageContext.horoscope.taurus_horoscope}
      gemini_horoscope={props.pageContext.horoscope.gemini_horoscope}
      cancer_horoscope={props.pageContext.horoscope.cancer_horoscope}
      leo_horoscope={props.pageContext.horoscope.leo_horoscope}
      virgo_horoscope={props.pageContext.horoscope.virgo_horoscope}
      libra_horoscope={props.pageContext.horoscope.libra_horoscope}
      scorpio_horoscope={props.pageContext.horoscope.scorpio_horoscope}
      sagittarius_horoscope={props.pageContext.horoscope.sagittarius_horoscope}
      capricorn_horoscope={props.pageContext.horoscope.capricorn_horoscope}
      aquarius_horoscope={props.pageContext.horoscope.aquarius_horoscope}
      pisces_horoscope={props.pageContext.horoscope.pisces_horoscope}
      author={props.pageContext.author.name}
      category={props.pageContext.categories
        .map(category => category.name)
        .toString()
        .replace(/,/g, ", ")}
      date={props.pageContext.created_at}
      cover={props.pageContext.cover.publicURL}
    />
  )
}

Horoscopes component

import React from "react"
import { Link } from "gatsby"
import Layout from "./layout"

import ReactMarkdown from "react-markdown"
import "./styles/article.css"

const Horoscopes = ({
  title,
  foreword,
  aries_horoscope,
  taurus_horoscope,
  gemini_horoscope,
  cancer_horoscope,
  leo_horoscope,
  virgo_horoscope,
  libra_horoscope,
  scorpio_horoscope,
  sagittarius_horoscope,
  capricorn_horoscope,
  aquarius_horoscope,
  pisces_horoscope,
  author,
  category,
  date,
  cover,
  authorPath,
  categoryPath,
}) => {
  return (
    <Layout>
      <div className="header">
        <img src={cover} />
      </div>
      <h2 className="title shadow">{title} Hey</h2>
      <div className="article-container">
        <p>{foreword}</p>
        <h3>Aries</h3>
        <p>
          <ReactMarkdown source={aries_horoscope} />
        </p>
        <h3>Taurus</h3>
        <p>
          <ReactMarkdown source={taurus_horoscope} />
        </p>
        <h3>Gemini</h3>
        <p>
          <ReactMarkdown source={gemini_horoscope} />
        </p>
        <h3>Cancer</h3>
        <p>
          <ReactMarkdown source={cancer_horoscope} />
        </p>
        <h3>Leo</h3>
        <p>
          <ReactMarkdown source={leo_horoscope} />
        </p>
        <h3>Virgo</h3>
        <p>
          <ReactMarkdown source={virgo_horoscope} />
        </p>
        <h3>Libra</h3>
        <p>
          <ReactMarkdown source={libra_horoscope} />
        </p>
        <h3>Scorpio</h3>
        <p>
          <ReactMarkdown source={scorpio_horoscope} />
        </p>
        <h3>Sagittarius</h3>
        <p>
          <ReactMarkdown source={sagittarius_horoscope} />
        </p>
        <h3>Capricorn</h3>
        <p>
          <ReactMarkdown source={capricorn_horoscope} />
        </p>
        <h3>Aquarius</h3>
        <p>
          <ReactMarkdown source={aquarius_horoscope} />
        </p>
        <h3>Pisces</h3>
        <p>
          <ReactMarkdown source={pisces_horoscope} />
        </p>
      </div>
      <h6 className="author-date">
        Posted by <Link to={authorPath}>{author}</Link> on {date} in{" "}
        <Link to={categoryPath}>{category}</Link>
      </h6>
    </Layout>
  )
}

export default Horoscopes

thank you

awaiting author response needs reproduction question or discussion

All 4 comments

Hi @joaopedrocoelho do you have a link to a reproducible test case showing this issue?

At a glance though, maybe these lines:
component: require.resolve("./src/templates/horoscopes")
should be: (using path)
component: path.resolve("./src/templates/horoscopes")

If I change require to path I get the following error :

ERROR #11325 

Your site's "gatsby-node.js" created a page with a component that doesn't exist.

The path to the missing component is "D:\Coding\astrobeats\frontend\src\templates\article"

The page object passed to createPage:
{
    "path": "/articles/this-is-my-second-article",
    "component": "D:\\Coding\\astrobeats\\frontend\\src\\templates\\article",_

Sorry I meant to also add the file suffix there as well:
component: require.resolve("./src/templates/horoscopes")
should be: (using path and .js on file)
component: path.resolve("./src/templates/horoscopes.js")

I don't know if Gatsby needs that to resolve the component.

I found the error, I was referencing the wrong path for the horoscope component. Sorry, I'm a newbie.

Thanks for your attention!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jimfilippou picture jimfilippou  路  3Comments

dustinhorton picture dustinhorton  路  3Comments

benstr picture benstr  路  3Comments

andykais picture andykais  路  3Comments

rossPatton picture rossPatton  路  3Comments