gatsby: Programatically created Pages do not trigger onCreatePage

Description

When creating pages programatically in gatsby-node.js they do not trigger the onCreatePage function. See log below

Steps to reproduce

Call the createPage function within the exports.createPages function in gatsby-node.js

Expected result

The exports.onCreatePage handler is called.

Actual result

I put a console log in before the createPage function and another console log in the exports.onCreatePage. Notice how the only calls to onCreatePage logged are for pages within the pages folder and not the programatically created ones.

success createLayouts — 0.015 s
⠁ CREATING PAGE:  blog-post
CREATING PAGE:  blog-post
CREATING PAGE:  blog-post
CREATING PAGE:  press-release
CREATING PAGE:  blog-post
CREATING PAGE:  blog-post
CREATING PAGE:  blog-post
success createPages — 0.053 s
⠁ ON PAGE CREATED /dev-404-page/
ON PAGE CREATED /404/
ON PAGE CREATED /blog/
ON PAGE CREATED /
ON PAGE CREATED /press/
ON PAGE CREATED /404.html

Environment

  • Gatsby version (1.9.253):
  • Node.js version: 8.11.1
  • Operating System: OSX

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 24 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I followed the popular https://auth0.com/blog/securing-gatsby-with-auth0/ to implement auth. It utilizes onCreatePage to create client-only route. Because of this issue it didn’t secure my programmatically created pages.

Sure, there’s not much to it. Here it is with the big warning comment linking this issue and all. 😃

  // Wrap createPage to assure onCreatePage is called since it's currently not for programmatically created pages in
  // gatsby-node.js. It only works for plugin created pages and pages in the `/pages` folder. See this issue for details:
  // https://github.com/gatsbyjs/gatsby/issues/5255
  // NOTE: If that issue is ever fixed we'll want to remove this code else onCreatePages will be called twice.
  const ourCreatePage = ({ ...params }) => {
    createPage(params)
    const { path, component, context } = params
    onCreatePage({
      page: { path, component, context },
      actions: { deletePage, createPage }
    })
  }

NOTE: deletePage and createPage here are from the actions from the createPages callback that you implement in gatsby-node.js to create pages. Our looks like this…

export const createPages = async ({
  graphql,
  actions: { createPage, deletePage }
}) => {
...

And the ourCreatePage definition is the first thing in there.

Just ran into this today as well. Given that it’s 2 years old now I’m assuming this just won’t be fixed. 😛 Guess I’ll use the workaround.

I just ran into this issue today. I have duplicated my function call in both onCreatePage and createPages to handle it for now.

Ohhh yeah. I remember adding that. Yeah, checking if the page has changed before calling onCreateNode is a much better solution. That’s what we do for new nodes as well.

Thanks @Chuloo for reproduction!

So here’s my findings why this is happening: https://github.com/gatsbyjs/gatsby/blob/d213693ef90f07c8a1b4e43db427327499b429ba/packages/gatsby/src/utils/api-runner-node.js#L167-L178

Because only plugin name is being tracked and not what API hook createPage was called in - it will skip calling onCreatePage in the same gatsby-node.js file.

Potential solutions:

  • track both plugin name and originating api hook, or
  • don’t emit CREATE_PAGE action if page didn’t change (which should prevent infinite loop) and remove code I linked above