最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I set the index page of my Gatsby site to be one of the dynamically generated pages? - Stack Overflow

programmeradmin1浏览0评论

I have a Gatsby site that queries information from a Wordpress REST API with GraphQL to dynamically create the site pages. I'd like to set my index page to be the homepage that is being created dynamically i.e home.html

I saw this post that was similar On Gatsby CMS how can i set the about page as a index page

However, they have an about.js file that corresponds to their about page, meaning they can export it as a component and use it in index or they can even just copy the contents of that file over to index.js. The homepage that I want to set as my index is being generated dynamically and using a GraphQL query that can't be used outside of the page.js template. So I don't see an easy way to copy that over to another file.

I guess my last option would be to set my server to point to the static file in public/home.html and serve that as the site root, but the person in that posting tries to deter people from doing that.

Any ideas?

Here is page.js template that generates the pages of the site:

const PageTemplate = ({ data }) => (
    <Layout>
        {<h1 dangerouslySetInnerHTML={{ __html: data.currentPage.title }} />}
        {
           renderBlocks(gatherBlocks(data.currentPage.acf.page_blocks, data))
        }
    </Layout>
);

export default PageTemplate;

export const pageQuery = graphql`
    query ($id: String!) {
        currentPage: wordpressPage(id: {eq: $id}) {
            title
            id
            parent {
                id
            }
            template
            acf {
                page_blocks {
                block_type {
                    acf_fc_layout
                    cs_title
                    cs_text
                }
                wordpress_id
                }
            }
        }
    }
`;

And here is my index page:

import React from "react"

import Layout from "../components/global/Layout"

const IndexPage = () => (
  <Layout>
    <h1>Hi people</h1>
    <p>Welcome to the Tank Gatsby site.</p>
    <p>Now go build something great.</p>
  </Layout>
)

export default IndexPage

I have a Gatsby site that queries information from a Wordpress REST API with GraphQL to dynamically create the site pages. I'd like to set my index page to be the homepage that is being created dynamically i.e home.html

I saw this post that was similar On Gatsby CMS how can i set the about page as a index page

However, they have an about.js file that corresponds to their about page, meaning they can export it as a component and use it in index or they can even just copy the contents of that file over to index.js. The homepage that I want to set as my index is being generated dynamically and using a GraphQL query that can't be used outside of the page.js template. So I don't see an easy way to copy that over to another file.

I guess my last option would be to set my server to point to the static file in public/home.html and serve that as the site root, but the person in that posting tries to deter people from doing that.

Any ideas?

Here is page.js template that generates the pages of the site:

const PageTemplate = ({ data }) => (
    <Layout>
        {<h1 dangerouslySetInnerHTML={{ __html: data.currentPage.title }} />}
        {
           renderBlocks(gatherBlocks(data.currentPage.acf.page_blocks, data))
        }
    </Layout>
);

export default PageTemplate;

export const pageQuery = graphql`
    query ($id: String!) {
        currentPage: wordpressPage(id: {eq: $id}) {
            title
            id
            parent {
                id
            }
            template
            acf {
                page_blocks {
                block_type {
                    acf_fc_layout
                    cs_title
                    cs_text
                }
                wordpress_id
                }
            }
        }
    }
`;

And here is my index page:

import React from "react"

import Layout from "../components/global/Layout"

const IndexPage = () => (
  <Layout>
    <h1>Hi people</h1>
    <p>Welcome to the Tank Gatsby site.</p>
    <p>Now go build something great.</p>
  </Layout>
)

export default IndexPage
Share Improve this question edited May 26, 2021 at 17:22 benomatis 5,6337 gold badges39 silver badges60 bronze badges asked Jan 22, 2020 at 21:46 user2030942user2030942 2456 silver badges26 bronze badges 1
  • How are you currently fetching the data for the page you want as the homepage from Wordpress in gatsby-node.js? – coreyward Commented Jan 23, 2020 at 22:28
Add a comment  | 

4 Answers 4

Reset to default 8

I experienced the same situation today. I used the following approach to use my dynamically created page with uri '/home'(fetched from wordpress using GraphQL query) as the home page of my Gatsby site:

  1. Delete the default index.js file in your pages directory.
  2. In gatsby-node.js file, change the uri of page from '/home' to '/' just before using the CreatePage API. Here is the sample code to achieve the desired result:
// loop through WordPress pages and create a Gatsby page for each one
  pages.forEach(page => {
    if(page.uri==='/home/')
      page.uri = '/'
    actions.createPage({
      path: page.uri,
      component: require.resolve(`./src/templates/${page.template.templateName}.js`),
      context: {
        id: page.id,
      },
    })
  })

In the above code, pages refer to the pages fetched from WordPress using GraphQL.

I could not find an easy way to create index page programmatically. Made it work nonetheless, details below.

  • createRedirect is valid approach but might affect SEO and definitely affects E2E tests cause actual page content gets rendered with a small delay.

  • Another thing to consider is that having pages/index.js file is required in order to get index.html file generated on production build. This gets in the way of using createPage({ path: '/', ... cause in my case programmatically created index page was overwritten by the static one (made of pages/index.js). This looks like a bug to me (or rather not supported feature). Corresponding github issue.

  • looks like deletePage and createPage gatsby-node APIs work asynchronously, hence we have to delete index page created from static file and create the one we want in the same callback. Not 100% sure about this one, but that's my observation.

  • onCreatePage API is a good candidate since it gets called upon original index page creation and we can take that one out and replace it with the custom one, programmatically created.

  • There is a catch however - CreatePageArgs interface (unlike CreatePagesArgs) doesn't provide reference to graphql, hence fetching data might be tricky.

Final solution:

export function onCreatePage(args: CreatePageArgs): void {
  const { page } = args;

  if (page.path === '/') {
    const { deletePage, createPage } = args.actions;

    const indexPageComponentPath = path.resolve(
      './src/pages/index.tsx',
    );

    deletePage({
      path: '/',
      component: indexPageComponentPath,
    });

    createPage({
      path: '/',
      component: yourComponentPath,
    });
  }
}

There is a solution: use createRedirect in gatsby-node.js. E.g.:

index.tsx

import React from 'react'
export default () => <></>

gatsby-node.js

...

exports.createPages = async ({ actions }) => {
  const { createRedirect } = actions

  createRedirect({
    fromPath: '/',
    toPath: '/home',
    isPermanent: true,
    redirectInBrowser: true,
 })
}

...

I was able to address this by copying the contents of the page.js template into index.js , but instead of using a regular GraphQL query, which cannot be used outside of the page template, I used useStaticQuery instead and hardcoded the id of the index page I was retrieving data from.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论