Next JS 应用程序路由器的站点地图文件中无法访问动态路由参数

问题描述 投票:0回答:1

我有一个使用 Next 12 构建的 Next JS 应用程序,我正在将其迁移到 Next 14。我之前在 google 中索引了多个站点地图。现在我正在尝试将它们迁移到应用程序路由器逻辑。在我的项目中,我有一个文件夹路径为

pages/sitemaps/[categoryId]/category.xml.tsx
的站点地图,可以通过路径
https://localhost:3000/sitemaps/124/category.xml
访问。我也想在我的应用程序路由器中维护站点地图的路径。我创建了文件
app/sitemaps/[categoryId]/category/sitemap.ts
以保持完全相同的路径。 这是我的代码:

//app/sitemaps/[categoryId]/category/sitemap.ts

import { MetadataRoute } from 'next';
export default async function sitemap({ params }: { params: { categoryId: string } }) : Promise<MetadataRoute.Sitemap> {
    console.log("Params: ",params);
    const categories:ICategory = await categories(parseInt(params.categoryId));

    return categories.map(category => {
        return( {
            url: `${SiteURL}${getCategoryLink(category)}`,
            lastModified: new Date(),
            changeFrequency: 'daily',
            priority: 1,
          })
    })
}

当我尝试链接

https://localhost:3000/sitemaps/124/category.xml
时,它显示404。 当我尝试链接
http://localhost:3000/sitemaps/124/category/sitemap.xml
时,它显示错误“找不到参数”。我的动态路由路径在文件内不可访问,我的参数值显示
undefined

  1. 为什么动态参数在文件内部无法访问?
  2. 最终路径是否必须始终是
    [...]/sitemap.xml
    ?就不能有别的名字吗
next.js dynamic sitemap next.js14
1个回答
0
投票

以下Nextjs 文档

  • Next.js 似乎希望我们在 app 文件夹下使用单个 sitemap.(ts|xml) 文件。那么你需要调整你的站点地图生成器。相反,您可以通过从 id 获取它来生成它。你必须获取所有数据(获取全部),然后映射并返回它

您可以在下面看到一个示例

const STORE_ID = process.env.NEXT_PUBLIC_STORE_ID ?? '';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  let url = process.env.NEXT_PUBLIC_BASE_WEB_URL ?? 'http:localhost:3000';
  if (url.includes("'")) {
    url = url.substring(1, url.length - 1);
  }
  const store = await getStore(STORE_ID, 'EN');

  const modelList: any = [];
  const brandsSitemap = store.brands.map(product => {
    modelList.push({ brandCode: product.code, data: [...product.models] });
    return {
      url: `${process.env.NEXT_PUBLIC_BASE_WEB_URL}/store/brand/${product.code}`,
      lastModified: new Date(),
      alternates: {
        languages: {
          th: `${process.env.NEXT_PUBLIC_BASE_WEB_URL}/th/store/${product.code}`,
          en: `${process.env.NEXT_PUBLIC_BASE_WEB_URL}/en/store/${product.code}`
        }
      }
    };
  });
  const modelSitemap = modelList.map((model: any) => {
    const brandCode = model.brandCode;
    return model?.data.map((model: ModelDetail) => {
      const modeCode = model.code;
      return model.submodels?.map(subModel => ({
        url: `${process.env.NEXT_PUBLIC_BASE_WEB_URL}/store/brand/${brandCode}/${modeCode}/${subModel.code}`,
        lastModified: new Date(),
        alternates: {
          languages: {
            th: `${process.env.NEXT_PUBLIC_BASE_WEB_URL}/th/store/brand/${brandCode}/${modeCode}/${subModel.code}`,
            en: `${process.env.NEXT_PUBLIC_BASE_WEB_URL}/en/store/brand/${brandCode}/${modeCode}/${subModel.code}`
          }
        }
      }));
    });
  });
  return [...brandsSitemap, ...modelSitemap.flat(2)];
}


© www.soinside.com 2019 - 2024. All rights reserved.