SDK
SDK

Reputation: 1518

How to delete src/pages/index.js file and create it dynamically using gatsby-node.js in gatsby?

I want to create the homePage of my gatsby site dynamically w/o using the src/pages/index.js.

I did like this.

const fetchAllComposePages = async ({ graphql, locales }) =>
  /* eslint implicit-arrow-linebreak: ["error", "below"] */
  graphql(`
    {
      allContentfulComposePage(filter: { node_locale: { in: ${locales} } }) {
        nodes {
          contentful_id
          title
          node_locale
          slug
          seo {
            no_follow
            no_index
            description
            name
            keywords
            title
          }
          content {
            __typename
          }
        }
      }
    }
  `);

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

  let locales = '';

  if (process.env.GATSBY_LOCALE === 'qc') {
    locales = '["en", "fr"]';
  } else {
    // Default to ROC locales
    locales = '["en-CA", "fr-CA"]';
  }

  const result = await fetchAllComposePages({ graphql, locales });

  result.data.allContentfulComposePage.nodes.map((node) => {
    const { contentful_id: id, slug, seo } = node;
    const content = node.content || [{}];
    const { __typename: template } = content;

    if (STATIC_DEFINED_PAGES.includes(slug)) {
      // These pages are generated in the `/pages` directory,
      // No need to generate a layout page for them here
      // eslint-disable-next-line no-console
      console.info(`Skipping Page :: ID: ${id} - Slug: ${slug}`);
      return;
    }

    if (!template) {
      // eslint-disable-next-line no-console
      console.info(`No Layout Found :: ID: ${id} - Slug: ${slug}`);
      return;
    }

    let layout = '';

    if (LAYOUT_LOOKUP[template]) {
      layout = LAYOUT_LOOKUP[template];
    } else {
      // eslint-disable-next-line no-console
      console.info(`No Layout Found :: ID: ${id} - Slug: ${slug}`);
      layout = 'base/BaseTemplate.js';
    }

    if (!seo) {
      // eslint-disable-next-line no-console
      console.info(`No SEO Found for: ${slug}`);
    }

    if (node.slug === '/') {
      deletePage({
        path: node.slug,
        component: path.resolve('src/pages/index.js'),
      });

      createPage({
        path: node.slug,
        component: path.resolve(`src/layouts/${layout}`),
        context: {
          pathSlug: slug,
          pageId: id,
          seo: {
            name: seo.name ? seo.name : '',
            description: seo.description ? seo.description : '',
            keywords: seo.keywords ? seo.keywords : '',
            title: seo.title ? seo.title : '',
            no_follow: seo.no_follow ? seo.no_follow : false,
            no_index: seo.no_index ? seo.no_index : false,
          },
        },
      });
    }

    createPage({
      path: node.slug,
      component: path.resolve(`src/layouts/${layout}`),
      context: {
        pathSlug: slug,
        pageId: id,
        seo: {
          name: seo.name ? seo.name : '',
          description: seo.description ? seo.description : '',
          keywords: seo.keywords ? seo.keywords : '',
          title: seo.title ? seo.title : '',
          no_follow: seo.no_follow ? seo.no_follow : false,
          no_index: seo.no_index ? seo.no_index : false,
        },
      },
    });
  });
};

// Adds the locale to pageContext for all pages and templates
exports.onCreatePage = ({ page }) => {
  const lang = page.context.intl.language;
  const locale = `${lang}-CA`;
  page.context.locale = locale;
  return page;
};

And this is the functionality i wrote to delete the index.js file

  if (node.slug === '/') {
      deletePage({
        path: node.slug,
        component: path.resolve('src/pages/index.js'),
      });

      createPage({
        path: node.slug,
        component: path.resolve(`src/layouts/${layout}`),
        context: {
          pathSlug: slug,
          pageId: id,
          seo: {
            name: seo.name ? seo.name : '',
            description: seo.description ? seo.description : '',
            keywords: seo.keywords ? seo.keywords : '',
            title: seo.title ? seo.title : '',
            no_follow: seo.no_follow ? seo.no_follow : false,
            no_index: seo.no_index ? seo.no_index : false,
          },
        },
      });
    }

But it's throwing an error like this enter image description here

Please recommend me a solution to fix this

Upvotes: 0

Views: 450

Answers (1)

Ferran Buireu
Ferran Buireu

Reputation: 29315

deletePage is an action available inside onCreatePage API (which is called every time a page is created), not inside createPages as you are trying to use it, where the page creation callback is not fired yet (that's why it fails).

You'll need to move your logic inside onCreatePage:

const replacePath = path => (path === `/` ? path : path.replace(/\/$/, ``))

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

  // Remove trailing slash unless page is /
  page.path = replacePath(page.path)

  if (page.path !== oldPage.path) {
    deletePage(oldPage)
    createPage(page)
  }

Alternatively, you can always delete the /pages/index.js and create it automatically using gatsby-node.js.

Upvotes: 1

Related Questions