错误:从查询返回的数据中`siteMetAdata'上不存在`siteUrl`。如何解决?

发布于 2025-01-28 21:45:32 字数 5854 浏览 3 评论 0原文

构建盖茨比网站时,我会收到以下错误。 我试图删除并重新安装NPM,更新插件,删除(gatsby)缓存,在gatsby配置中使用SiteUrl和各种设置。但是我似乎无法摆脱错误。开发环境正常。

github: https://github.com/github.com/bartfluitsma/gatsby-bart-bart-bart-bart-fluitsma

**Error console log**

ERROR #11321  PLUGIN

"gatsby-plugin-sitemap" threw an error while running the onPostBuild lifecycle:

`siteUrl` does not exist on `siteMetadata` in the data returned from the query.
Add this to your `siteMetadata` object inside gatsby-config.js or add this to your custom query or provide a custom `resolveSiteUrl` function.
https://www.gatsbyjs.com/plugins/gatsby-plugin-sitemap/#api-reference


  47 |             errors = _yield$graphql.errors;
  48 |             _context.next = 9;
> 49 |             return Promise.resolve(resolveSiteUrl(queryRecords)).catch(function (err) {
     |                                    ^
  50 |               return reporter.panic(_internals.REPORTER_PREFIX + " Error resolving Site URL", err);
  51 |             });
  52 |

File: node_modules\gatsby-plugin-sitemap\gatsby-node.js:49:36



  Error: `siteUrl` does not exist on `siteMetadata` in the data returned from the query.
  Add this to your `siteMetadata` object inside gatsby-config.js or add this to your custom query or provide a custom `resolveSiteUrl` function.
  https://www.gatsbyjs.com/plugins/gatsby-plugin-sitemap/#api-reference

  - internals.js:62 resolveSiteUrl
    [gatsby-bart-fluitsma]/[gatsby-plugin-sitemap]/internals.js:62:11

  - gatsby-node.js:49 _callee$
    [gatsby-bart-fluitsma]/[gatsby-plugin-sitemap]/gatsby-node.js:49:36


not finished onPostBuild - 0.480s

strong> gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Bart Fluitsma`,
    description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
    author: `@gatsbyjs`,
    siteUrl: `http://bartfluitsma.com`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-image`,
    'gatsby-plugin-postcss',
    {
      resolve: `gatsby-plugin-google-fonts-with-attributes`,
      options: {
        fonts: [
          `montserrat\:300,400,400i,600,900`,
        ],
        display: 'swap',
        attributes: {
          rel: "stylesheet preload prefetch",
        },
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    }, {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/src/locales`,
        name: `locale`
      }
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `Web development | Bart Fluitsma`,
        short_name: `Bart develops`,
        start_url: `/`,
        background_color: `#663399`,
        // This will impact how browsers show your PWA/website
        // https://css-tricks.com/meta-theme-color-and-trickery/
        // theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/logo-bart-fluitsma-web-design.svg`, // This path is relative to the root of the site.
      },
    },
    {
      resolve: `gatsby-plugin-react-i18next`,
      options: {
        localeJsonSourceName: `locale`, // name given to `gatsby-source-filesystem` plugin.
        languages: [`en`, `nl`],
        defaultLanguage: `en`,
        // if you are using Helmet, you must include siteUrl, and make sure you add http:https
        siteUrl: `https://bartfluitsma.com`,
        // you can pass any i18next options
        i18nextOptions: {
          interpolation: {
            escapeValue: false // not needed for react as it escapes by default
          },
          keySeparator: false,
          nsSeparator: false
        },
        pages: [
          {
            matchPath: '/:lang?/blog/:uid',
            getLanguageFromPath: true
          },
        ]
      }
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.dev/offline
    // `gatsby-plugin-offline`,
    {
      resolve: 'gatsby-plugin-sitemap',
      options: {
        excludes: ['/**/404', '/**/404.html'],
        query: `
            {
              site {
                siteMetadata {
                  siteUrl
                }
              }
              allSitePage(filter: {context: {i18n: {routed: {eq: false}}}}) {
                edges {
                  node {
                    context {
                      i18n {
                        defaultLanguage
                        languages
                        originalPath
                      }
                    }
                    path
                  }
                }
              }
            }
          `,
        serialize: ({ site, allSitePage }) => {
          return allSitePage.edges.map((edge) => {
            const { languages, originalPath, defaultLanguage } = edge.node.context.i18n;
            const { siteUrl } = site.siteMetadata;
            const url = siteUrl + originalPath;
            const links = [
              { lang: defaultLanguage, url },
              { lang: 'x-default', url }
            ];
            languages.forEach((lang) => {
              if (lang === defaultLanguage) return;
              links.push({ lang, url: `${siteUrl}/${lang}${originalPath}` });
            });
            return {
              url,
              changefreq: 'daily',
              priority: originalPath === '/' ? 1.0 : 0.7,
              links
            };
          });
        }
      }
    },
  ],
}

When building my Gatsby website I get the below error.
I've tried to delete and reinstall npm, update the plugins, deleting (Gatsby) cache, playing around with the siteUrl and all kinds of settings in the Gatsby config. But I can't seem to get rid of the error. The development environment works fine.

github: https://github.com/bartfluitsma/gatsby-bart-fluitsma

**Error console log**

ERROR #11321  PLUGIN

"gatsby-plugin-sitemap" threw an error while running the onPostBuild lifecycle:

`siteUrl` does not exist on `siteMetadata` in the data returned from the query.
Add this to your `siteMetadata` object inside gatsby-config.js or add this to your custom query or provide a custom `resolveSiteUrl` function.
https://www.gatsbyjs.com/plugins/gatsby-plugin-sitemap/#api-reference


  47 |             errors = _yield$graphql.errors;
  48 |             _context.next = 9;
> 49 |             return Promise.resolve(resolveSiteUrl(queryRecords)).catch(function (err) {
     |                                    ^
  50 |               return reporter.panic(_internals.REPORTER_PREFIX + " Error resolving Site URL", err);
  51 |             });
  52 |

File: node_modules\gatsby-plugin-sitemap\gatsby-node.js:49:36



  Error: `siteUrl` does not exist on `siteMetadata` in the data returned from the query.
  Add this to your `siteMetadata` object inside gatsby-config.js or add this to your custom query or provide a custom `resolveSiteUrl` function.
  https://www.gatsbyjs.com/plugins/gatsby-plugin-sitemap/#api-reference

  - internals.js:62 resolveSiteUrl
    [gatsby-bart-fluitsma]/[gatsby-plugin-sitemap]/internals.js:62:11

  - gatsby-node.js:49 _callee$
    [gatsby-bart-fluitsma]/[gatsby-plugin-sitemap]/gatsby-node.js:49:36


not finished onPostBuild - 0.480s

Gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Bart Fluitsma`,
    description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
    author: `@gatsbyjs`,
    siteUrl: `http://bartfluitsma.com`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-image`,
    'gatsby-plugin-postcss',
    {
      resolve: `gatsby-plugin-google-fonts-with-attributes`,
      options: {
        fonts: [
          `montserrat\:300,400,400i,600,900`,
        ],
        display: 'swap',
        attributes: {
          rel: "stylesheet preload prefetch",
        },
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    }, {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/src/locales`,
        name: `locale`
      }
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `Web development | Bart Fluitsma`,
        short_name: `Bart develops`,
        start_url: `/`,
        background_color: `#663399`,
        // This will impact how browsers show your PWA/website
        // https://css-tricks.com/meta-theme-color-and-trickery/
        // theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/logo-bart-fluitsma-web-design.svg`, // This path is relative to the root of the site.
      },
    },
    {
      resolve: `gatsby-plugin-react-i18next`,
      options: {
        localeJsonSourceName: `locale`, // name given to `gatsby-source-filesystem` plugin.
        languages: [`en`, `nl`],
        defaultLanguage: `en`,
        // if you are using Helmet, you must include siteUrl, and make sure you add http:https
        siteUrl: `https://bartfluitsma.com`,
        // you can pass any i18next options
        i18nextOptions: {
          interpolation: {
            escapeValue: false // not needed for react as it escapes by default
          },
          keySeparator: false,
          nsSeparator: false
        },
        pages: [
          {
            matchPath: '/:lang?/blog/:uid',
            getLanguageFromPath: true
          },
        ]
      }
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.dev/offline
    // `gatsby-plugin-offline`,
    {
      resolve: 'gatsby-plugin-sitemap',
      options: {
        excludes: ['/**/404', '/**/404.html'],
        query: `
            {
              site {
                siteMetadata {
                  siteUrl
                }
              }
              allSitePage(filter: {context: {i18n: {routed: {eq: false}}}}) {
                edges {
                  node {
                    context {
                      i18n {
                        defaultLanguage
                        languages
                        originalPath
                      }
                    }
                    path
                  }
                }
              }
            }
          `,
        serialize: ({ site, allSitePage }) => {
          return allSitePage.edges.map((edge) => {
            const { languages, originalPath, defaultLanguage } = edge.node.context.i18n;
            const { siteUrl } = site.siteMetadata;
            const url = siteUrl + originalPath;
            const links = [
              { lang: defaultLanguage, url },
              { lang: 'x-default', url }
            ];
            languages.forEach((lang) => {
              if (lang === defaultLanguage) return;
              links.push({ lang, url: `${siteUrl}/${lang}${originalPath}` });
            });
            return {
              url,
              changefreq: 'daily',
              priority: originalPath === '/' ? 1.0 : 0.7,
              links
            };
          });
        }
      }
    },
  ],
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你不是我要的菜∠ 2025-02-04 21:45:32

该错误是通过gatsby-plugin-sitemap抛出的。尝试在配置中添加esolvesiteUrl方法,例如:

const siteUrl = process.env.URL || `https://fallback.net`

resolveSiteUrl: () => siteUrl,

应用于代码:

const siteUrl = process.env.URL || `https://fallback.net`

module.exports = {
  plugins: [
    {
      resolve: "gatsby-plugin-sitemap",
      options: {
        excludes: ["/**/404", "/**/404.html"],
        query: `
            {
              site {
                siteMetadata {
                  siteUrl
                }
              }
              allSitePage(filter: {context: {i18n: {routed: {eq: false}}}}) {
                edges {
                  node {
                    context {
                      i18n {
                        defaultLanguage
                        languages
                        originalPath
                      }
                    }
                    path
                  }
                }
              }
            }
          `,
        resolveSiteUrl: () => siteUrl,
        serialize: ({ site, allSitePage }) => {
          return allSitePage.edges.map((edge) => {
            const { languages, originalPath, defaultLanguage } =
              edge.node.context.i18n;
            const { siteUrl } = site.siteMetadata;
            const url = siteUrl + originalPath;
            const links = [
              { lang: defaultLanguage, url },
              { lang: "x-default", url },
            ];
            languages.forEach((lang) => {
              if (lang === defaultLanguage) return;
              links.push({ lang, url: `${siteUrl}/${lang}${originalPath}` });
            });
            return {
              url,
              changefreq: "daily",
              priority: originalPath === "/" ? 1.0 : 0.7,
              links,
            };
          });
        },
      },
    },
  ],
};

如果您不在环境文件中,则相应地更改siteurl和后备网址

The error is thrown by gatsby-plugin-sitemap. Try adding the resolveSiteUrl method in your configuration like:

const siteUrl = process.env.URL || `https://fallback.net`

resolveSiteUrl: () => siteUrl,

Applied to your code:

const siteUrl = process.env.URL || `https://fallback.net`

module.exports = {
  plugins: [
    {
      resolve: "gatsby-plugin-sitemap",
      options: {
        excludes: ["/**/404", "/**/404.html"],
        query: `
            {
              site {
                siteMetadata {
                  siteUrl
                }
              }
              allSitePage(filter: {context: {i18n: {routed: {eq: false}}}}) {
                edges {
                  node {
                    context {
                      i18n {
                        defaultLanguage
                        languages
                        originalPath
                      }
                    }
                    path
                  }
                }
              }
            }
          `,
        resolveSiteUrl: () => siteUrl,
        serialize: ({ site, allSitePage }) => {
          return allSitePage.edges.map((edge) => {
            const { languages, originalPath, defaultLanguage } =
              edge.node.context.i18n;
            const { siteUrl } = site.siteMetadata;
            const url = siteUrl + originalPath;
            const links = [
              { lang: defaultLanguage, url },
              { lang: "x-default", url },
            ];
            languages.forEach((lang) => {
              if (lang === defaultLanguage) return;
              links.push({ lang, url: `${siteUrl}/${lang}${originalPath}` });
            });
            return {
              url,
              changefreq: "daily",
              priority: originalPath === "/" ? 1.0 : 0.7,
              links,
            };
          });
        },
      },
    },
  ],
};

Change the siteUrl and the fallback URL accordingly if you are not setting it in your environment file

撩人痒 2025-02-04 21:45:32

Ferran Buireu的答案最终不是OP的解决方案。我遇到了同样的问题,如果他没有放弃它,该解决方案本来可以解决他的问题。检查此 github thread

您的siteUrl问题只是掩盖了查询无效的问题,因为上下文在gatsby> = 4中不可用,因为您在修复siteUrl后发现了

您可能已经从文档支持站点地图。

为了使它起作用,我发现您必须要1。自己创建上下文,然后进行2。调整查询

  1. 通过gatsby-node.js创建上下文(Creade wilsonvolker> wilsonvolker
/**
 * Workaround for missing sitePage.context:
 * Used for generating sitemap with `gatsby-plugin-react-i18next` and `gatsby-plugin-sitemap` plugins
 * https://www.gatsbyjs.com/docs/reference/release-notes/migrating-from-v3-to-v4/#field-sitepagecontext-is-no-longer-available-in-graphql-queries
 */
exports.createSchemaCustomization = ({ actions }) => {
    const { createTypes } = actions
    createTypes(`
    type SitePage implements Node {
      context: SitePageContext
    }
    type SitePageContext {
      i18n: i18nContext
    }
    type i18nContext {
        language: String,
        languages: [String],
        defaultLanguage: String,
        originalPath: String
        routed: Boolean
    }
  `)
}
  1. //github.com/microapps/gatsby-plugin-react-i18next/issues/143#issuecomment-1183523819“ rel = “ 在I18Next中提出的不再起作用,因为它显然会收到一个节点,而不是完整的GraphQL响应。因此,gatsby-config.js中的一些更改以使其再次起作用(假设您有一个全局siteUrl可用):
query: `
  {
    site {
      siteMetadata {
        siteUrl
      }
    }
    allSitePage(filter: {context: {i18n: {routed: {eq: false}}}}) {
      nodes {
        context {
          i18n {
            defaultLanguage
            languages
            originalPath
          }
        }
        path
      }
    }
  }
`,
serialize: (node) => {
  const { languages, originalPath, defaultLanguage } = node.context.i18n
  const url = siteUrl + originalPath
  const links = [
    { lang: defaultLanguage, url },
    { lang: 'x-default', url },
  ]
  languages.forEach((lang) => {
    if (lang === defaultLanguage) return
    links.push({ lang, url: `${siteUrl}/${lang}${originalPath}` })
  })
  return {
    url,
    changefreq: 'daily',
    priority: originalPath === '/' ? 1.0 : 0.7,
    links,
  }
},

The answer by Ferran Buireu ultimately was not the solution for OP. I had experienced the same issue and this solution would have solved his issue hadn't he abandoned it. Check this GitHub thread.

Your siteUrl issue just masks that the query was invalid, as the context is not available in gatsby >= 4 anymore, as you found out after fixing the siteUrl.

You may have used this query from the gatsby-plugin-react-i18next docs to support a sitemap.

In order to make it work, I found you have to 1. create the context yourself, and 2. adjust the queries

  1. Create your context through gatsby-node.js (credit wilsonvolker)
/**
 * Workaround for missing sitePage.context:
 * Used for generating sitemap with `gatsby-plugin-react-i18next` and `gatsby-plugin-sitemap` plugins
 * https://www.gatsbyjs.com/docs/reference/release-notes/migrating-from-v3-to-v4/#field-sitepagecontext-is-no-longer-available-in-graphql-queries
 */
exports.createSchemaCustomization = ({ actions }) => {
    const { createTypes } = actions
    createTypes(`
    type SitePage implements Node {
      context: SitePageContext
    }
    type SitePageContext {
      i18n: i18nContext
    }
    type i18nContext {
        language: String,
        languages: [String],
        defaultLanguage: String,
        originalPath: String
        routed: Boolean
    }
  `)
}
  1. It looks like the serialize function proposed in the i18next doesn't work as-is anymore since it apparently receives a single node, not the full graphql response. So, a few changes in gatsby-config.js to make it work again (this assumes you have a global siteUrl variable available):
query: `
  {
    site {
      siteMetadata {
        siteUrl
      }
    }
    allSitePage(filter: {context: {i18n: {routed: {eq: false}}}}) {
      nodes {
        context {
          i18n {
            defaultLanguage
            languages
            originalPath
          }
        }
        path
      }
    }
  }
`,
serialize: (node) => {
  const { languages, originalPath, defaultLanguage } = node.context.i18n
  const url = siteUrl + originalPath
  const links = [
    { lang: defaultLanguage, url },
    { lang: 'x-default', url },
  ]
  languages.forEach((lang) => {
    if (lang === defaultLanguage) return
    links.push({ lang, url: `${siteUrl}/${lang}${originalPath}` })
  })
  return {
    url,
    changefreq: 'daily',
    priority: originalPath === '/' ? 1.0 : 0.7,
    links,
  }
},
生生漫 2025-02-04 21:45:32

这对我有用,而无需创建新类型:

{
  resolve: "gatsby-plugin-sitemap",
  options: {
    excludes: ["/**/404", "/**/404.html"],
    resolveSiteUrl: () => siteUrl,
    query: `
      {
        allSitePage {
          edges {
            node {
              pageContext
            }
          }
        }
      }
    `,
    resolvePages: ({ allSitePage: { edges } }) => {
      return edges
        .filter(
          ({ node }) => !["/404/", "/404.html"].includes(node.pageContext.i18n.originalPath)
        )
        .map(({ node: { pageContext } }) => {
          const { languages, originalPath, path, defaultLanguage } = pageContext.i18n;
          const baseUrl = siteUrl + originalPath;
          const links = [{ lang: "x-default", url: baseUrl }];

          languages.forEach((lang) => {
            const isDefaultLang = lang === defaultLanguage;
            const isDefaultPath = path === originalPath;
            const isLangSubDir = path.includes(`${lang}/`);

            if (isDefaultLang && isDefaultPath) return;
            if (!isDefaultLang && isLangSubDir) return;

            links.push({
              lang,
              url: isDefaultLang ? baseUrl : `${siteUrl}/${lang}${originalPath}`,
            });
          });

          return {
            path,
            url: path === "/" ? siteUrl : `${siteUrl}/${path}`,
            changefreq: "daily",
            priority: originalPath === "/" ? 1.0 : 0.7,
            links,
          };
        });
    },
    serialize: (page) => page,
  },
}

版本:
节点:18.13.0

"gatsby": "^5.3.3",
"gatsby-plugin-react-i18next": "^3.0.1",
"gatsby-plugin-sitemap": "^6.5.0",

This worked for me without the need to create new types:

{
  resolve: "gatsby-plugin-sitemap",
  options: {
    excludes: ["/**/404", "/**/404.html"],
    resolveSiteUrl: () => siteUrl,
    query: `
      {
        allSitePage {
          edges {
            node {
              pageContext
            }
          }
        }
      }
    `,
    resolvePages: ({ allSitePage: { edges } }) => {
      return edges
        .filter(
          ({ node }) => !["/404/", "/404.html"].includes(node.pageContext.i18n.originalPath)
        )
        .map(({ node: { pageContext } }) => {
          const { languages, originalPath, path, defaultLanguage } = pageContext.i18n;
          const baseUrl = siteUrl + originalPath;
          const links = [{ lang: "x-default", url: baseUrl }];

          languages.forEach((lang) => {
            const isDefaultLang = lang === defaultLanguage;
            const isDefaultPath = path === originalPath;
            const isLangSubDir = path.includes(`${lang}/`);

            if (isDefaultLang && isDefaultPath) return;
            if (!isDefaultLang && isLangSubDir) return;

            links.push({
              lang,
              url: isDefaultLang ? baseUrl : `${siteUrl}/${lang}${originalPath}`,
            });
          });

          return {
            path,
            url: path === "/" ? siteUrl : `${siteUrl}/${path}`,
            changefreq: "daily",
            priority: originalPath === "/" ? 1.0 : 0.7,
            links,
          };
        });
    },
    serialize: (page) => page,
  },
}

Versions:
Node: 18.13.0

"gatsby": "^5.3.3",
"gatsby-plugin-react-i18next": "^3.0.1",
"gatsby-plugin-sitemap": "^6.5.0",
青春有你 2025-02-04 21:45:32

我正在自定义用于生成多语言站点地图的代码,如下所示。
在实际的生产代码中,从I18N配置设置中检索了“语言”变量中的每种语言。

import type { GatsbyConfig } from 'gatsby'

const languages = ['en', 'fr', 'ja']

const config: GatsbyConfig = {
  plugins: [
    'gatsby-plugin-pnpm',
    'gatsby-plugin-postcss',
    {
      resolve: `gatsby-plugin-sitemap`,
      options: {
        excludes: ['/**/404', '/**/404.html'],
        serialize: ({ path }) => {
          // Get the page path without the language code.
          const pagepath = path.replace(/\/.*?\//, '/')
          // Generate XML links for each language.
          const xmlLinks = languages.map((lang: string) => ({
            rel: 'alternate',
            hreflang: lang,
            url: `/${lang}${pagepath}`
          }))
          xmlLinks.push({
            rel: 'alternate',
            hreflang: 'x-default',
            url: `${pagepath}`
          })

          let entry = {
            url: path,
            changefreq: 'daily',
            links: xmlLinks
          }

          return entry
        }
      }
    }
  ]
}

生成的XML看起来如下。

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
  <url>
    <loc>https://sample.com/</loc>
    <changefreq>daily</changefreq>
    <xhtml:link rel="alternate" hreflang="en" href="https://sample.com/en/" />
    <xhtml:link rel="alternate" hreflang="ja" href="https://sample.com/ja/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://sample.com/" />
  </url>
  <url>
    <loc>https://sample.com/en/</loc>
    <changefreq>daily</changefreq>
    <xhtml:link rel="alternate" hreflang="en" href="https://sample.com/en/" />
    <xhtml:link rel="alternate" hreflang="ja" href="https://sample.com/ja/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://sample.com/" />
  </url>
  <url>
    <loc>https://sample.com/ja/</loc>
    <changefreq>daily</changefreq>
    <xhtml:link rel="alternate" hreflang="en" href="https://sample.com/en/" />
    <xhtml:link rel="alternate" hreflang="ja" href="https://sample.com/ja/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://sample.com/" />
  </url>
</urlset>

版本:节点:V19.4.0

"gatsby": "v19.4.0",
"gatsby-plugin-sitemap": "6.11.0"

I'm customizing the code for generating a multilingual sitemap as follows.
In the actual production code, each language in the 'languages' variable is retrieved from the i18n configuration settings.

import type { GatsbyConfig } from 'gatsby'

const languages = ['en', 'fr', 'ja']

const config: GatsbyConfig = {
  plugins: [
    'gatsby-plugin-pnpm',
    'gatsby-plugin-postcss',
    {
      resolve: `gatsby-plugin-sitemap`,
      options: {
        excludes: ['/**/404', '/**/404.html'],
        serialize: ({ path }) => {
          // Get the page path without the language code.
          const pagepath = path.replace(/\/.*?\//, '/')
          // Generate XML links for each language.
          const xmlLinks = languages.map((lang: string) => ({
            rel: 'alternate',
            hreflang: lang,
            url: `/${lang}${pagepath}`
          }))
          xmlLinks.push({
            rel: 'alternate',
            hreflang: 'x-default',
            url: `${pagepath}`
          })

          let entry = {
            url: path,
            changefreq: 'daily',
            links: xmlLinks
          }

          return entry
        }
      }
    }
  ]
}

The generated XML looks as below.

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
  <url>
    <loc>https://sample.com/</loc>
    <changefreq>daily</changefreq>
    <xhtml:link rel="alternate" hreflang="en" href="https://sample.com/en/" />
    <xhtml:link rel="alternate" hreflang="ja" href="https://sample.com/ja/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://sample.com/" />
  </url>
  <url>
    <loc>https://sample.com/en/</loc>
    <changefreq>daily</changefreq>
    <xhtml:link rel="alternate" hreflang="en" href="https://sample.com/en/" />
    <xhtml:link rel="alternate" hreflang="ja" href="https://sample.com/ja/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://sample.com/" />
  </url>
  <url>
    <loc>https://sample.com/ja/</loc>
    <changefreq>daily</changefreq>
    <xhtml:link rel="alternate" hreflang="en" href="https://sample.com/en/" />
    <xhtml:link rel="alternate" hreflang="ja" href="https://sample.com/ja/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://sample.com/" />
  </url>
</urlset>

Versions: Node: v19.4.0

"gatsby": "v19.4.0",
"gatsby-plugin-sitemap": "6.11.0"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文