Search code examples
javascriptgraphqlgatsbynetlifygatsby-plugin

Only one page generated to sitemap with gatsby-plugin-sitemap


I am not able to create a sitemap for my Gatsy site.

The default setting of the plugin creates only one page even there is several pages:

<sitemap>
<loc>https://www.thesite.nl/sitemap/sitemap-0.xml</loc>
</sitemap>

If I try to override the default setting with:

query: `{
          site {
            siteMetadata {
              siteUrl
            }
          }
          allSitePage {
            nodes {
              path
            }
          }
        }`,
        serialize: ({ site, allSitePage }) =>
          allSitePage.nodes
            .filter(node => {
              const path = node.path
              console.log({ path })
              // Filter out 404 pages
              if (path.includes("404")) {
                return false
              }
              // Filter out base pages that don't have a language directory
              return supportedLanguages.includes(path.split("/")[1])
            })
            .map(node => {
              return {
                url: `${site.siteMetadata.siteUrl}${node.path}`,
                changefreq: `weekly`,
                priority: 0.7,
              }
            }),

I get TypeError: Cannot read property 'nodes' of undefined Problem is that with gatsby develop I can query the nodes like this and get the paths even it says undefined here.

I have Gatsby v3 and the only plugin I can think might affect could be "gatsby-plugin-intl": "^0.3.3",.

{
      resolve: `gatsby-plugin-intl`,
      options: {
        // language JSON resource path
        path: `${__dirname}/src/intl`,
        // supported language
        languages: [`nl`, `en`],
        language: `nl`,
        // language file path
        defaultLanguage: `nl`,
        // option to redirect to `/nl` when connecting `/`
        redirect: false,
      },
    },

Any ideas?

Got it to build via custom options with gatsby build && gatsby serve after @FerranBuireu suggestion to change the query and now it looks like this but sitemap is still empty:

const siteUrl = process.env.URL || `https://www.thesite.nl`
 {
      resolve: "gatsby-plugin-sitemap",
      options: {
        query: `
        {
          allSitePage {
            nodes {
              path
            }
          }
        }
      `,
        resolveSiteUrl: () => siteUrl,
        resolvePages: ({ allSitePage: { nodes: allPages } }) => {
          return allPages.map(page => {
            return { ...page }
          })
        },
        serialize: ({ path }) => {
          return {
            url: path,
          }
        },
      },
    },

Solution

  • I think your issue comes because you are not setting the resolveSiteUrl and, in this scenario, the siteUrl needs to be present. According to the docs:

    siteMetadata: {
      // If you didn't use the resolveSiteUrl option this needs to be set
      siteUrl: `https://www.example.com`,
    },
    

    An ideal full configuration should be:

    const siteUrl = process.env.URL || `https://fallback.net`
    
    // In your gatsby-config.js
    module.exports = {
      plugins: [
        {
          resolve: "gatsby-plugin-sitemap",
          options: {
            query: `
            {
              allSitePage {
                nodes {
                  path
                }
              }
              allWpContentNode(filter: {nodeType: {in: ["Post", "Page"]}}) {
                nodes {
                  ... on WpPost {
                    uri
                    modifiedGmt
                  }
                  ... on WpPage {
                    uri
                    modifiedGmt
                  }
                }
              }
            }
          `,
            resolveSiteUrl: () => siteUrl,
            resolvePages: ({
              allSitePage: { nodes: allPages },
              allWpContentNode: { nodes: allWpNodes },
            }) => {
              const wpNodeMap = allWpNodes.reduce((acc, node) => {
                const { uri } = node
                acc[uri] = node
    
                return acc
              }, {})
    
              return allPages.map(page => {
                return { ...page, ...wpNodeMap[page.path] }
              })
            },
            serialize: ({ path, modifiedGmt }) => {
              return {
                url: path,
                lastmod: modifiedGmt,
              }
            },
          },
        },
      ],
    }
    

    Tweak it and adapt it to fit your query.

    I would do something like:

        resolveSiteUrl: () => siteUrl,
        resolvePages: ({
          allSitePage: { nodes: allPages },
        }) => {
          const sitePageNodeMap = allSitePage.reduce((acc, node) => {
            const { uri } = node
            acc[uri] = node
    
            return acc
          }, {})
    
          return allPages.map(page => {
            return { ...page, ...sitePageNodeMap[page.path] }
          })
        },
        serialize: ({ path, modifiedGmt }) => {
          return {
            url: path,
            lastmod: modifiedGmt,
          }
        },