nextjs 15 - next js 15, app, sitemap - Cannot convert argument to a ByteString - Stack Overflow

sitemap generation, in dev mode it displays normally. In production when opening the page sitemap.xml

sitemap generation, in dev mode it displays normally. In production when opening the page /sitemap.xml - error 500

server console " 0|front | ⨯ [TypeError: Cannot convert argument to a ByteString because the character at index 131 has a value of 1082 which is greater than 255.] " during assembly in the console "sitemap length 606 "

\src\app\sitemap.ts

import { MetadataRoute } from 'next';

import { getCities } from '@/utils/api/request/cities';
import { getAppConfig } from '@/utils/api/config';
import { getAllPoints } from '@/utils/api/request/points';
import { getAllProducts, filterProductsByMenuIds } from '@/utils/api/request/products';
import { getAllShowcases } from '@/utils/api/request/showcases';
import { createPointsByCityMap } from '@/utils/createPointsByCityMap';
import { BASE_SITEMAP_URL, INCLUDED_LINK_KEYS, LINKS } from '@/app/constants';

function createSitemapEntry(
  url: string,
  changeFrequency: MetadataRoute.Sitemap[0]['changeFrequency'],
  priority: number,
): MetadataRoute.Sitemap[0] {
  const encodedUrl = encodeURIComponent(url);

  return {
    url: encodedUrl,
    lastModified: new Date(),
    changeFrequency,
    priority,
  };
}

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  try {
    const [configData, citiesData] = await Promise.all([getAppConfig(), getCities()]);

    if (
      !configData?.data?.CombinationOfParameters ||
      !citiesData?.data ||
      !configData.data?.TypeMenu?.Object
    ) {
      throw new Error('Missing required data');
    }

    const points = await getAllPoints(citiesData);
    const cities = citiesData.data;
    const menu = configData.data.TypeMenu;

    const pointsByCityMap = createPointsByCityMap(cities, points);
    const allProducts = await getAllProducts(
      cities,
      pointsByCityMap,
      configData.data.CombinationOfParameters,
    );

    const sitemapEntries: MetadataRoute.Sitemap = [
      createSitemapEntry(BASE_SITEMAP_URL, 'daily', 1),
    ];

    for (const city of cities) {
      const cityUrl = `${BASE_SITEMAP_URL}/${city.Url}`;
      sitemapEntries.push(createSitemapEntry(cityUrl, 'weekly', 1));

      INCLUDED_LINK_KEYS.forEach((key) => {
        const link = LINKS[key];

        if (typeof link === 'function') {
          sitemapEntries.push(
            createSitemapEntry(`${BASE_SITEMAP_URL}${link(city.Url)}`, 'weekly', 0.5),
          );
        } else if (typeof link === 'string') {
          sitemapEntries.push(createSitemapEntry(`${BASE_SITEMAP_URL}${link}`, 'weekly', 0.5));
        } else if (typeof link === 'object') {
          Object.entries(link).forEach(([, childLink]) => {
            if (typeof childLink === 'function') {
              sitemapEntries.push(
                createSitemapEntry(`${BASE_SITEMAP_URL}${childLink(city.Url)}`, 'weekly', 0.5),
              );
            }
          });
        }
      });

      for (const category of menu.Object) {
        const categoryUrl = `${BASE_SITEMAP_URL}/${city.Url}/${category.URL}`;
        sitemapEntries.push(createSitemapEntry(categoryUrl, 'weekly', 0.8));

        const menuIds = category.TypeIDs?.map((typeID) => typeID.ID) || [];
        const isShowcase = category.Showcase;

        const products = isShowcase
          ? await getAllShowcases([city], pointsByCityMap, allProducts)
          : filterProductsByMenuIds(allProducts, menuIds);

        Object.entries(products).forEach(([cityUrl, pointsData]) => {
          Object.values(pointsData).forEach((productArrays) => {
            productArrays?.flat().forEach((product) => {
              sitemapEntries.push(
                createSitemapEntry(
                  `${BASE_SITEMAP_URL}/${cityUrl}/${category.URL}/${product.NameTranslit}`,
                  'weekly',
                  0.9,
                ),
              );
            });
          });
        });
      }
    }

    const uniqueSitemapEntries = Array.from(
      new Map(sitemapEntries.map((entry) => [entry.url, entry])).values(),
    );

    console.log('sitemap length', uniqueSitemapEntries?.length);

    return uniqueSitemapEntries;
  } catch (error) {
    console.error('Error generating sitemap:', error);
    return [createSitemapEntry(BASE_SITEMAP_URL, 'daily', 1)];
  }
}

{
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "npm run clean && cross-env AUTOPREFIXER_GRID=autoplace NODE_EXTRA_CA_CERTS=certs/CAROOT.crt next dev --turbo",
    "prebuild": "npm run clear-tags && npm run clean",
    "build": "cross-env AUTOPREFIXER_GRID=autoplace NODE_EXTRA_CA_CERTS=certs/CAROOT.crt next build",
    "postbuild": "npm run clean-tags",
    "start": "cross-env AUTOPREFIXER_GRID=autoplace NODE_EXTRA_CA_CERTS=certs/CAROOT.crt next start",
    "lint": "next lint",
    "clean": "npx rimraf .next out",
    "clear-tags": "node ./src/utils/revalidate/clearTags.mjs",
    "clean-tags": "node ./src/utils/revalidate/cleanTags.mjs"
  },
  "dependencies": {
    "@emotion/react": "^11.11.4",
    "@emotion/styled": "^11.11.5",
    "@pbe/react-yandex-maps": "^1.2.5",
    "@reduxjs/toolkit": "^2.3.0",
    "@types/react": "19.0.0",
    "@types/react-dom": "19.0.0",
    "caniuse-lite": "^1.0.30001699",
    "date-fns": "^4.1.0",
    "date-fns-tz": "^3.2.0",
    "eslint-plugin-compat": "^5.0.0",
    "eslint-plugin-prettier": "^5.1.3",
    "iron-session": "^8.0.4",
    "moment": "^2.30.1",
    "moment-timezone": "^0.5.45",
    "next": "^15.2.3",
    "nextjs-toploader": "^3.7.15",
    "postcss-flexbugs-fixes": "^5.0.2",
    "postcss-preset-env": "^9.6.0",
    "react": "^19.0.0",
    "react-datepicker": "^7.5.0",
    "react-dom": "^19.0.0",
    "react-google-recaptcha": "^3.1.0",
    "react-insta-stories": "^2.7.0",
    "react-masonry-css": "^1.0.16",
    "react-perfect-scrollbar": "^1.5.8",
    "react-phone-input-2": "^2.15.1",
    "react-photo-view": "^1.2.6",
    "react-range": "^1.10.0",
    "react-redux": "^9.1.2",
    "react-select": "^5.8.3",
    "swiper": "^11.1.4",
    "transliteration": "^2.3.5",
    "use-media": "^1.5.0"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react-google-recaptcha": "^2.1.9",
    "@types/yandex-maps": "^2.1.36",
    "@typescript-eslint/eslint-plugin": "^8.24.0",
    "@typescript-eslint/parser": "^8.24.0",
    "autoprefixer": "^10.4.19",
    "cross-env": "^7.0.3",
    "eslint": "^8",
    "eslint-config-next": "^15.0.3",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-css-modules": "^2.12.0",
    "prettier": "^3.5.0",
    "typescript": "^5.4.5",
    "typescript-plugin-css-modules": "^5.1.0"
  }
}

node v20.15.1

I expect a list of sitemaps with the ability to revalidate by time or tag or path

I tried to do it through the route, like here .js/discussions/50419

\src\app\api\ppp.xml\route.ts

import { getCities } from '@/utils/api/request/cities';
import { getAppConfig } from '@/utils/api/config';
import { getAllPoints } from '@/utils/api/request/points';
import { getAllProducts, filterProductsByMenuIds } from '@/utils/api/request/products';
import { getAllShowcases } from '@/utils/api/request/showcases';
import { createPointsByCityMap } from '@/utils/createPointsByCityMap';
import { BASE_SITEMAP_URL, LINKS } from '@/app/constants';

const INCLUDED_LINK_KEYS: (keyof typeof LINKS)[] = [
  'cashback',
  'contacts',
  'stock',
  'law',
  'lawChilds',
  'b2b',
  'help',
];

function createSitemapEntry(url: string, changefreq: string, priority: number): string {
  const encodedUrl = encodeURIComponent(url); // Кодируем URL
  return `
    <url>
      <loc>${encodedUrl}</loc>
      <lastmod>${new Date().toISOString()}</lastmod>
      <changefreq>${changefreq}</changefreq>
      <priority>${priority}</priority>
    </url>
  `;
}

export async function GET(): Promise<Response> {
  try {
    const [configData, citiesData] = await Promise.all([getAppConfig(), getCities()]);

    if (
      !configData?.data?.CombinationOfParameters ||
      !citiesData?.data ||
      !configData.data?.TypeMenu?.Object
    ) {
      throw new Error('Missing required data');
    }

    const points = await getAllPoints(citiesData);
    const cities = citiesData.data;
    const menu = configData.data.TypeMenu;

    const pointsByCityMap = createPointsByCityMap(cities, points);
    const allProducts = await getAllProducts(
      cities,
      pointsByCityMap,
      configData.data.CombinationOfParameters,
    );

    let sitemapEntries = createSitemapEntry(BASE_SITEMAP_URL, 'daily', 1.0);

    for (const city of cities) {
      const cityUrl = `${BASE_SITEMAP_URL}/${city.Url}`;
      sitemapEntries += createSitemapEntry(cityUrl, 'weekly', 1.0);

      INCLUDED_LINK_KEYS.forEach((key) => {
        const link = LINKS[key];

        if (typeof link === 'function') {
          sitemapEntries += createSitemapEntry(
            `${BASE_SITEMAP_URL}${link(city.Url)}`,
            'weekly',
            0.5,
          );
        } else if (typeof link === 'string') {
          sitemapEntries += createSitemapEntry(`${BASE_SITEMAP_URL}${link}`, 'weekly', 0.5);
        } else if (typeof link === 'object') {
          Object.entries(link).forEach(([, childLink]) => {
            if (typeof childLink === 'function') {
              sitemapEntries += createSitemapEntry(
                `${BASE_SITEMAP_URL}${childLink(city.Url)}`,
                'weekly',
                0.5,
              );
            }
          });
        }
      });

      for (const category of menu.Object) {
        const categoryUrl = `${cityUrl}/${category.URL}`;
        sitemapEntries += createSitemapEntry(categoryUrl, 'weekly', 0.8);

        const menuIds = category.TypeIDs?.map((typeID) => typeID.ID) || [];
        const isShowcase = category.Showcase;

        const products = isShowcase
          ? await getAllShowcases([city], pointsByCityMap, allProducts)
          : filterProductsByMenuIds(allProducts, menuIds);

        Object.entries(products).forEach(([cityUrl, pointsData]) => {
          Object.values(pointsData).forEach((productArrays) => {
            productArrays?.flat().forEach((product) => {
              sitemapEntries += createSitemapEntry(
                `${BASE_SITEMAP_URL}/${cityUrl}/${category.URL}/${product.NameTranslit}`,
                'weekly',
                0.9,
              );
            });
          });
        });
      }
    }

    const xml = `<?xml version="1.0" encoding="UTF-8"?>
      <urlset xmlns=".9">
        ${sitemapEntries}
      </urlset>`;

    const xmlBuffer = Buffer.from(xml, 'utf-8'); // Преобразуем строку в Buffer с кодировкой UTF-8

    const headers = new Headers();
    headers.set('Content-Type', 'application/xml; charset=UTF-8'); // Устанавливаем кодировку в заголовках

    return new Response(xmlBuffer, { headers });
  } catch (error) {
    console.error('Error generating sitemap:', error);
    return new Response('<?xml version="1.0" encoding="UTF-8"?><urlset></urlset>', {
      headers: { 'Content-Type': 'application/xml; charset=UTF-8' },
    });
  }
}

works, but if I add cache - export const revalidate = 4000; then the same error "[TypeError: Cannot convert argument to a ByteString because the character at index 131 has a value of 1082 which is greater than 255.] "

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744080116a4555129.html

相关推荐

  • 如何增加 Elasticsearch 中的主分片数量

    要增加现有索引的主分片数量,直接修改是不可能的。因此,如果你想增加主分片的数量,必须重新创建索引。通常有两种方法:_reindex API 和 _split API。在这两种方法中,_split API 通常比 _reindex API 更

    1小时前
    20
  • 怎么用html写出哆啦A梦?

    用HTML和CSS来画哆啦A梦(Doraemon)是一项有趣且具有挑战性的任务。虽然HTML和CSS主要用于网页布局和样式,但通过巧妙的组合和定位,可以创建出相对简单的图形和图案。下面是一个简单的示例,展示了如何用HTML和CSS绘制哆啦A

    1小时前
    00
  • MySQL8.4 Enterprise安装Firewall及测试

    参考:.4enfirewall.html1.首先执行安装SQL,路径在baseshare目录下代码语言:javascript代码运行次数:0运行复制cd u01mysql3308baseshare[root@mysql8_3

    1小时前
    00
  • 用安信可Ai

    以下作品由安信可社区用户业余菜狗制作前言自从接触智能家居之后,笔者就变得很依赖智能家居(绝对不是懒!)比如卧室灯,就在进门的地方,进门开灯很方便,但是晚上睡觉关灯就很不方便。之前是买了一款Wi-Fi灯,是用手机APP操作,刚开始用的时候感觉

    1小时前
    00
  • Claude 不是只能聊天:我用这5个 MCP 工具,让它像程序员一样工作

    最近在折腾 Claude,原本只是拿来写点文案、回答技术问题。但渐渐地我有点不满足了——AI 不能只会说话,它得“动”起来。于是,我遇见了 MCP Server,彻底打开了新世界大门。

    1小时前
    00
  • Go项目实战

    上节课我给大家介绍了怎么给Go项目做单元测试的规划,当然这里仅限于跟咱们课程里的实战项目一样分层架构设计做的还可以的项目哦,要是所有逻辑都耦合在Controller里,那这个规划就不适用了。。。,所有逻辑都耦合在Controller里还做个

    1小时前
    00
  • UMIT:统一多模态多任务视觉

    随着深度学习的迅速发展,尤其是在医学影像分析领域的应用,越来越多的视觉-语言模型(VLMs)被广泛应用于解决复杂的健康和生物医学挑战。然而,现有研究主要集中在特定任务或单一模态上,这限制了它们在多种医学场景中的适用性和泛化能力。为了解决这

    1小时前
    00
  • 2025年最受欢迎的10款免费CRM软件大对比

    在数字化转型浪潮下,越来越多的企业开始重视客户关系管理(CRM)系统。一个高效的CRM不仅能帮助企业理清客户脉络,还能提升销售效率、优化服务体验。2025年,市场上涌现了众多优秀的免费CRM软件,本文将为大家对比10款最受欢迎的产品,助您选

    1小时前
    00
  • 万字图解 Java 并发框架:ForkJoin、CountDownLatch、Semaphore、CyclicBarrier

    本文图多,内容硬核,建议收藏。在第一章节《1.6w 字图解 Java 并发:多线程挑战、线程状态和通信、死锁;AQS、ReentrantLock、Condition 使用和原理》,我们开启了 Java 高并发系列的学习,透彻理解 Java

    56分钟前
    00
  • 电脑密码在哪里设置win11,win11电脑开机密码怎么设置

    Win11系统由于许多设置和以前系统不一样了&#xff0c;所以很多用户们操作非常不习惯&#xff0c;有很多的小伙伴不知道win11系统怎么设置开机密码。给电脑设置密码&#xff0c;只有自己能打开进入系统桌面&a

    53分钟前
    00
  • HLS最全知识库

    HLS最全知识库副标题-FPGA高层次综合HLS(二)-Vitis HLS知识库高层次综合(High-level Synthesis)简称HLS,指的是将高层次语言描述的逻辑结构,自动转换成低抽象级语言描述的电路模型的过程。对于AMD Xi

    50分钟前
    00
  • 面试官:从三万英尺角度谈一下Ceph架构设计(1)

    把面试官当陪练,在找工作中才会越战越勇大家好我是小义同学,这是大厂面试拆解——项目实战系列的第3篇文章,如果有误,请指正。本文主要解决的一个问题,Ceph为例子 如何描述项目的架构。一句话描述:主要矛盾发生变化10年前的技术和方案,放到10

    45分钟前
    00
  • 电脑开机会默认一件GHOST

    关于电脑开机会自己重装系统 前段时间电脑一开机就遇到会自己ghost的问题&#xff0c;而且一直再重复同样的操作&#xff0c;我点击restart的时候到开启页面又会自动ghost&#xff0c;而且此页面停留

    38分钟前
    00
  • ascend pytorch 踩坑.

    在910b上安装pytorch 和 pytorch_npu, 因为后续准备装vllm, 所以torch_npu是特殊的版本.代码语言:shell复制pip install torch==2.5.1 --extra-index pip in

    28分钟前
    00
  • 3、win10重装系统后Mysql环境和数据的恢复

    因为电脑是机哥的原因&#xff0c;重装了好几次电脑&#xff0c;因为我习惯把软件都装在D盘。所以很多东西都还比较好恢复&#xff0c;在网上学会了怎么不卸载重装数据库&#xff0c;自己记录以备后面自己查

    21分钟前
    00
  • MongoDB “升级项目” 大型连续剧(2)

    上期写的是非必要不升级,想到这个事情,有一些事情的仔细琢磨琢磨,为什么数据库升级的事情在很多公司都是一个困扰,从一个技术人的观点,升级是一件好事,功能提升了,性能提升了,开发效率和一些数据库使用的痛点也被解决了,为什么就不愿意升级呢?如果只

    20分钟前
    00
  • 深度学习在DOM解析中的应用:自动识别页面关键内容区块

    爬虫代理摘要本文介绍了如何在爬取东方财富吧()财经新闻时,利用深度学习模型对 DOM 树中的内容区块进行自动识别和过滤,并将新闻标题、时间、正文等关键信息分类存储。文章聚焦爬虫整体性能瓶颈,通过指标对比、优化策略、压测数据及改进结果,展示了

    17分钟前
    10
  • 什么是docker?它是如何工作的?

    想象一个场景,你要部署一个服务,然后它对环境有很多依赖,不同的操作系统又是不同的需求,而且还可能遇到有些源不能使用,又得一番折腾,折腾完上线后,假设要在新的环境再来一套,又得再来一遍。那么有没有什么办法可以解决呢?有办法,docker就是干

    15分钟前
    00
  • 推荐一个轻量级的监控平台并且支持移动端

    简介XUGOU 是基于Cloudflare构建的轻量化监控平台,专精于系统资源监控与可视化状态页面服务。该平台提供英文简体中文双语支持,满足全球化部署需求。面向开发者及中小团队,项目致力于提供高可用性的监控解决方案。核心功能与实现平台功能

    12分钟前
    00
  • 【Docker项目实战】使用Docker部署IT工具箱Team·IDE

    一、Team·IDE介绍1.1 Team·IDE简介Team IDE 是一款集成多种数据库(如 MySQL、Oracle、金仓、达梦、神通等)与分布式系统组件(如 Redis、Zookeeper、Kafka、Elasticsearch)管理

    9分钟前
    00

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信