0

I have a Next JS application which was built using Next 12 and I am migrating it to Next 14. I have multiple sitemaps indexed in google earlier. Now I am trying to migrate them to App router logic. In my project I have a sitemap with folder path as pages/sitemaps/[categoryId]/category.xml.tsx which was accessible in the path https://localhost:3000/sitemaps/124/category.xml. I want to maintain the path of the sitemap in my app router as well. I created file app/sitemaps/[categoryId]/category/sitemap.ts to keep the exact same path. Here is my code:

//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,
          })
    })
}

When I tried the link https://localhost:3000/sitemaps/124/category.xml, it shows 404. When I try the link http://localhost:3000/sitemaps/124/category/sitemap.xml, it is showing error that "Params not found". My dynamic route path is not accessible inside the files, my params value shows undefined.

  1. Why does the dynamic param is not accessible inside the file?
  2. Does the end path have to be [...]/sitemap.xml always? Can't it be any other name ?

1 Answer 1

0

following Nextjs document

  • seems Next.js wants us to use a single sitemap.(ts|xml) file under the app folder. then you need to adjust your sitemap generator. instead, you generate it by getting it from the id. you have to fetch all data (get all) and then map and return it

you can see an example below

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)];
}


Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.