Gatsby: [v2] Folder named "index" under /pages creates path "/index" instead of "/"

Created on 16 Aug 2018  路  9Comments  路  Source: gatsbyjs/gatsby

Description

When putting /pages files in folders, like this:

pages
    index
        index.js
        style.css
    page-2
        index.js
        style.css

Gatsby v2 doesn't recognize the index folder as the base path, instead creates a path to index/index.html. This leads to the build failing because there's no base index.html file.

Error: ENOENT: no such file or directory, open '.../gatsby-site/public/index.html'

Steps to reproduce

Create a new Gatsby v2 project.

gatsby new gatsby-site https://github.com/gatsbyjs/gatsby-starter-default#v2

Put the index page under a folder named indexand change the layout import to another level deeper (../../ instead of ../).

Attempt to build with gatsby build.

Expected result

Index folder should be recognized as base path, like in Gatsby v1.

Actual result

Path /index/index.html is created instead of /index.html.

Environment

System:
OS: Windows 10
CPU: x64 Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
Binaries:
Yarn: 1.7.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.1.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: 42.17134.1.0
npmPackages:
gatsby: next => 2.0.0-beta.105
gatsby-plugin-manifest: next => 2.0.2-beta.6
gatsby-plugin-offline: next => 2.0.0-beta.9
gatsby-plugin-react-helmet: next => 3.0.0-beta.4

File contents (if changed)

gatsby-config.js: N/A
package.json: N/A
gatsby-node.js: N/A
gatsby-browser.js: N/A
gatsby-ssr.js: N/A

good first issue help wanted needs reproduction

Most helpful comment

Stumbled across this as well and it's actually really simple to solve with a few lines in your gatsby-node.js file. Figured future issue readers might find this useful!

// gatsby-node.js

exports.onCreatePage = ({ page, actions }) => {
  const { deletePage, createPage } = actions

  return new Promise(resolve => {
    // if the page component is the index page component
    if (page.componentPath === `${__dirname}/src/pages/index/index.js`) {
      deletePage(page)

      // create a new page but with '/' as path
      createPage({
        ...page,
        path: '/',
      })
    }

    resolve()
  })
}

All 9 comments

Need more information on how the expected result should be! Please provide a more specific as not all of us use gatsby v1.

The algorithm for creating pages is in here: https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-create-client-paths/src/gatsby-node.js

Happy to take a PR updating it w/ some new tests to account for this.

Hmm... on second thought, I don't know that we should. / is different than /index/.

Yeah, it'd be nice if you could keep your folder structure the same but the index page of a website is unique so you'll need to put its js/css file at the top-level.

Stumbled across this as well and it's actually really simple to solve with a few lines in your gatsby-node.js file. Figured future issue readers might find this useful!

// gatsby-node.js

exports.onCreatePage = ({ page, actions }) => {
  const { deletePage, createPage } = actions

  return new Promise(resolve => {
    // if the page component is the index page component
    if (page.componentPath === `${__dirname}/src/pages/index/index.js`) {
      deletePage(page)

      // create a new page but with '/' as path
      createPage({
        ...page,
        path: '/',
      })
    }

    resolve()
  })
}

You can also make an index.js with this:

import index from './index/index';
export default index;

You can also make an index.js with this:

import index from './index/index';
export default index;

this seems to be most simple way to approach folder/index.js as folder/
but what is the most general and recommanded way?

in pages/
folder/index.js -> folder/ . /// to do this we have to create /folder.js
folder/about.js -> folder/about

You can also make an index.js with this:

import index from './index/index';
export default index;

So I did this and it kidna bit me in the ass. Turns out a page's graphql queries need to be in the _top level component_. So once I figured out I had to put the queries on the index then pass down to your 'folder' home page - problem solved right?

Well no, turns out that works for develop but not build. Save yourself some time, don't be all fancy about it - just have an index.js in the root - then have a landing folder with all the assets you need in there .

You can also make an index.js with this:

import index from './index/index';
export default index;

So I did this and it kidna bit me in the ass. Turns out a page's graphql queries need to be in the _top level component_. So once I figured out I had to put the queries on the index then pass down to your 'folder' home page - problem solved right?

Well no, turns out that works for develop but not build. Save yourself some time, don't be all fancy about it - just have an index.js in the root - then have a landing folder with all the assets you need in there .

Could you please edit your post to include the proposed file structure for those of us which are still wondering?

@AngelinCalu Sure thing!

My structure looks like this

Pages
- index.js
- Landing
- - landing.module.css
- - img
- - .. any other needed assets for landing page
- AnotherPage
- - index.js
- - another-page.module.css

And in the index.js it just looks like this

import { Link, graphql } from "gatsby"
import React from "react"

import styles from "./landing/landing.module.css"

function LandingPage({ data }) {
  return (
    <Main>
       // render things
    </Main>
  )
}

export const query = graphql`
  query LandingQuery {
    // query things
  }

So essentially, for all pages they get a folder, which has an index.js inside it. I like having each page organised as a folder like that.

But for the index page, I leave the .js file where gatsby expect it to be, so all the page queries work. But I keep all the assets in a /landing folder so they're not just randomly lying around my /pages directory, and just reference them like normal.

Working great for me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Oppenheimer1 picture Oppenheimer1  路  3Comments

theduke picture theduke  路  3Comments

benstr picture benstr  路  3Comments

kalinchernev picture kalinchernev  路  3Comments

ghost picture ghost  路  3Comments