0

I'm using Gatsby and I want build a single page site, so without create pages. For achieve this I edited gatsby-node.js with the following code:

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

  if (page.path === "/") {
    page.matchPath = "/*"
    createPage(page)
  }
}

in that case, each request is re-routed to the index.js page, which is the only one. Then, in the index.js page I have:

const IndexPage = () => {
  const intl = useIntl()
  const locale = intl.locale

  return (
    <BGTState>
      <BlogState>
        <Layout>
          <Router>
            <Home path={`${locale}/`} />
            <Section path={`${locale}/:sectionSlug`} />
            <Collection path={`${locale}/:sectionSlug/:collectionSlug`} />
            <Season
              path={`${locale}/:categorySlug/:collectionSlug/:seasonSlug`}
            />
            <Product
              path={`${locale}/:categorySlug/:collectionSlug/:seasonSlug/:prodSlug`}
            />
            <Blog path={`${locale}/blog`} />
            <Article path={`${locale}/blog/:articleSlug`} />
            <NotFound default />
          </Router>
        </Layout>
      </BlogState>
    </BGTState>
  )
}

as you can see, I have different routers that load a specific component based on the url. I have prefixed each path with the current locale to match the correct path. This mechanism is working fine for the home page only, but for the other links doesn't work. Infact, if I visit something like:

http://localhost:3001/en/category-home/prod-foo

which must load the Collection component, the site simply redirect to:

http://localhost:3001/en

and display the Home component again.

What I did wrong?

UPDATE

Page Structure:

enter image description here

As you can see I have just the index.js which handle all requests as I configured in the gatby-node.js. If I remove the localization plugin, at least using this configuration:

 {
      resolve: `gatsby-plugin-intl`,
      options: {
        // Directory with the strings JSON
        path: `${__dirname}/src/languages`,
        // Supported languages
        languages: ["it", "en", "ci", "fr"],
        // Default site language
        defaultLanguage: `it`,
        // Redirects to `it` in the route `/`
        //redirect: true,
        // Redirect SEO component
        redirectComponent: require.resolve(
          `${__dirname}/src/components/redirect.js`
        ),
      },
    },

and I don't prefix the url with intl.locale, everything is working fine. But adding redirect: true in the plugin configuration, and prefixing the link with the locale, the site redirect me to the home component.

sfarzoso
  • 1,356
  • 2
  • 24
  • 65

1 Answers1

0

If you are creating a SPA (Single Page Application, notice the single) you won't have any created pages but index. You are trying yo access to a /category page that's not created because of:

  if (page.path === "/") {
    page.matchPath = "/*"
    createPage(page)
  }

That's why your routes don't work (or in other words, only the home page works).

Adapt the previous condition to your needs to allow creating more pages based on your requirements.

I'm using Gatsby and I want build a single page site, so without create pages. For achieve this I edited gatsby-node.js with the following code:

It's a non-sense trying to build a SPA application with Gatsby (without creating pages) but then complaining because there's not collection page created.

Make sure that you understand what you are doing, it seems clearly that you need to create dynamically pages for each collection, season, and product so your approach to create SPA won't work for your use-case.

It's possible to keep just index.js without overcomplicating thing? I just want to understand why my code isn't working 'cause I've passed the correct url... Removing the localization Gatsby works, so I suspect there is a localization problem

The only way that http://localhost:3001/category-home/prod-foo (removing the localization) could be resolved is by creating a folder structure such /pages/category-home/prod-foo.js (since Gatsby extrapolates the folder structure as URLs), so, if you want to use localization using your approach, add a structure such en/pages/category-home/prod-foo.js and es/pages/category-home/prod-foo.js (or the whatever locale), and so on. In my opinion, this is overcomplexitying stuff since, for every category, you'll need to create 2 (even more depending on the locales) files.

Gatsby allows you to create dynamic pages and interpolate the locale automatically using built-in plugins on the process, creating each file for the specifically defined locales.

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • how can I create dynamic page? – sfarzoso Dec 21 '20 at 15:13
  • It's possible to keep just `index.js` without overcomplicating thing? I just want to understand why my code isn't working 'cause I've passed the correct url... Removing the localization Gatsby works, so I suspect there is a localization problem – sfarzoso Dec 21 '20 at 15:37
  • I've updated the answer. The only way that `http://localhost:3001/category-home/prod-foo` (removing the localization) could be resolved is by creating a folder structure such `/pages/category-home/prod-foo.js`. If you want to use localization using your approach, add a structure such as `en/pages/category-home/prod-foo.js` but this the definition of overcomplexing stuff. – Ferran Buireu Dec 21 '20 at 15:46
  • That sounds a little weird to me, because I have this url: `http://localhost:3001/:category-slug/:product-slug`. Without the localization plugin this works.. but if I use the `redirect: true` in the plugin configuration, the url doesn't work anymore. I also tried to prefix the url as: `http://localhost:3001/${locale}/:category-slug/:product-slug` but the problem is here, that redirect to home. – sfarzoso Dec 22 '20 at 09:29
  • What's your project page structure? – Ferran Buireu Dec 22 '20 at 09:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/226281/discussion-between-sfarzoso-and-ferran-buireu). – sfarzoso Dec 22 '20 at 10:00