Gatsby: Is it possible to prevent some page components under src/pages from turning into pages?

Created on 24 Sep 2019  路  10Comments  路  Source: gatsbyjs/gatsby

Summary

Based on GatsbyJS documentation on Creating and Modifying Pages, it says:

Gatsby core automatically turns React components in src/pages into pages

But is it possible to prevent some page components under src/pages from automatically being turned into pages?

For example, suppose I have index.js and about.js under src/pages. Is there any way to prevent about.js from being turned into a page depending on whether I am in "development" or "production" environment?

I was hoping there was a way I could edit gatsby-node.js to prevent building the About page during "production" so it is only available on "development" mode.

question or discussion

Most helpful comment

Hi @kimbaudi. There are two ways to go about doing it.

First, using gatsby's onCreatePage APIs, similar to the documentation page that you linked to.

const pathsToIgnore = ['/about/', ...]
exports.onCreatePage = ({ page, actions: { deletePage }) => {
  if (process.env.NODE_ENV === 'production') return

  if (pathsToIgnore.includes(page.path)) {
    deletePage(page)
  }
}

Or you can override the default gatsby-plugin-page-creator. More info here https://www.gatsbyjs.org/packages/gatsby-plugin-page-creator/?=#ignoring-specific-files

// gatsby-config.js
  plugins: [
    // ...
    ...(process.env.NODE_ENV === 'development' && {
      resolve: 'gatsby-plugin-page-creator',
      options: {
        path: `${__dirname}/src/pages`,
        ignore: ['about.(js|ts)?(x)'],
      },
    }),
    // ...
  ]

Hope it helps.

All 10 comments

But is it possible to prevent some page components under src/pages from automatically being turned into pages?

No, that's not possible.

Is there any way to prevent about.js from being turned into a page depending on whether I am in "development" or "production" environment?

The solution you're trying isn't ideal IMO anyways, you should do it differently (than fiddling with src/pages).

You can place the file somewhere else and use the createPages API to generate that.

// gatsby-node.js
exports.createPages = ({ actions }) => {
  const { createPage } = actions

  if (process.env.NODE_ENV === `production`) {
    createPage({
      path: `/about`,
      component: require.resolve(`./src/templates/about.js`),
    })
  }
}

Hope that helps! Closing the issue as answered, please reply if you need further help. Thanks for using Gatsby!

Hi @kimbaudi. There are two ways to go about doing it.

First, using gatsby's onCreatePage APIs, similar to the documentation page that you linked to.

const pathsToIgnore = ['/about/', ...]
exports.onCreatePage = ({ page, actions: { deletePage }) => {
  if (process.env.NODE_ENV === 'production') return

  if (pathsToIgnore.includes(page.path)) {
    deletePage(page)
  }
}

Or you can override the default gatsby-plugin-page-creator. More info here https://www.gatsbyjs.org/packages/gatsby-plugin-page-creator/?=#ignoring-specific-files

// gatsby-config.js
  plugins: [
    // ...
    ...(process.env.NODE_ENV === 'development' && {
      resolve: 'gatsby-plugin-page-creator',
      options: {
        path: `${__dirname}/src/pages`,
        ignore: ['about.(js|ts)?(x)'],
      },
    }),
    // ...
  ]

Hope it helps.

@LekoArts - I'm not sure your solution will work in my case. It seems to require that I convert all my react components under src/pages into markdown files. I've seen other websites do what you suggested, but its not an ideal solution for me. Thanks for taking the time to provide a solution, though!

@universse - Your solutions are exactly what I was looking for. Thank you! I chose to override gatsby-plugin-page-creator and prevent pages from being created instead of using onCreatePage to delete the page after its already been created.

...(process.env.NODE_ENV === `production`
    ? [
        {
        resolve: `gatsby-plugin-page-creator`,
        options: {
            path: `${__dirname}/src/pages`,
            ignore: [
            'about.js',
            ],
        },
        },
    ]
    : []),

The other solution to use onCreatePage works fine too:

const pathsToIgnore = [
  `/about/`,
]
exports.onCreatePage = ({ page, actions }) => {
  if (process.env.NODE_ENV === 'development') return
  if (pathsToIgnore.includes(page.path)) {
    const { deletePage } = actions
    deletePage(page)
  }
}

There is also a plugin called gatsby-plugin-exclude that deletes pages using onCreatePage method in gatsby-node.js as well.

Oops I made some syntax errors there. Glad it helped.

It seems to require that I convert all my react components under src/pages into markdown files.

No, that鈥檚 not the case. This function takes a component and creates a page.

@LekoArts - I don't think your suggestion to use exports.createPages to conditionally create pages based on the environment (dev/prod) makes sense in my case. If I am to follow your suggestion, I would have to move the javascript files from src/pages somewhere else and convert it to markdown. Something like the following:

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

  // Create blog posts pages.
  createPages(`./src/templates/blog-post.js`, '/blog/')

  // Create notes pages.
  createPages(`./src/templates/note.js`, '/notes/')

  if (process.env.NODE_ENV === `development`) {
    // Create books pages.
    createPages(`./src/templates/note.js`, '/books/')

    // Create code pages.
    createPages(`./src/templates/note.js`, '/code/')

    // Create learn pages.
    createPages(`./src/templates/note.js`, '/learn/')
  }
}

So at least in my case, it seems I would have to move js files out of src/pages and convert it to markdown files and then use export.createPages to conditionally create pages.

I'm sure I'm not understanding what you mean because I feel that I have to move the .js files under /src/pages somewhere else and change it from a page react component to a markdown file for it to work your way.

But either way, @universse solutions are more what I was hoping/looking for.

Hope I could at least explain why I felt your solution wasn't suitable in my case (because I would have to modify files under /src/pages) even though it would work.

If you can explain your suggestion so that I don't have to make any changes to files under /src/pages, then that is what I am looking for. But that doesn't seem to be the case.

If I am to follow your suggestion, I would have to move the javascript files from src/pages somewhere else and convert it to markdown.

No, that's still not the case. Where did you get that impression? I didn't write that 馃

The createPage function takes a path (the URL) and a component a JS/JSX/TSX file to generate the page. You don't have to convert JS files to Markdown.

Yes, you have to move the single file you conditionally want to use (the about.js) out of src/pages but I personally think that @universse solution is bad for the future -- you might come back to this project in 1-2 years (or even another person) and expect the src/pages/about.js file to create a page every time (as you expect).

But if you explicitly put the the file that is used conditionally in a directory like src/conditional-pages/ it will make things so much clearer.

So at least in my case, it seems I would have to move js files out of src/pages and convert it to markdown files and then use export.createPages to conditionally create pages.

You only have to move this one file. You can keep all other files in src/pages.

So I guess for the src/conditional-pages approach, can conditionally include another gatsby-plugin-page-creator that points to src/conditional-pages, depending on process.env.NODE_ENV. So no overriding of default plugin or usage of other APIs is necessary.

@LekoArts - I'm really sorry for not understanding your suggestion earlier. Thank you for clearing up any confusion I had about converting js files into md files 馃槄. I followed your suggestion and moved about.js and any other js files that I want to conditionally build from src/pages to src/hidden-pages. Then in gatsby-node.js, I updated exports.createPages to create the about.js page based on the environment (dev/prod):

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

  if (process.env.NODE_ENV === `development`) {
    createPage({
      path: `/about/`,
      component: path.resolve(`./src/hidden-pages/about.js`),
    })
  }
}

Thanks for this suggestion! It works out well.

@universse - I think your solution to use gatsby-plugin-page-creator plugin with options.path set to src/hidden-pages depending on the environment (dev/prod) is the most ideal solution since I don't need to make any changes to exports.createPages or exports.onCreatePage. Also, it takes into account @LekoArts suggestion to move the javascript files out of src/pages elsewhere. So thanks to both of you!

So here is my solution to only building pages under src/private-pages on "development" environment:

gatsby-config.js:

    ...(process.env.NODE_ENV === `development`
    ? [
        {
          resolve: `gatsby-plugin-page-creator`,
          options: {
            path: `${__dirname}/src/private-pages`,
          },
        },
      ]
    : []),
Was this page helpful?
0 / 5 - 0 ratings