diff --git a/package-lock.json b/package-lock.json index b3f5338..4257256 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "react-photoswipe-gallery": "^3.0.2", "react-toastify": "^10.0.5", "sass": "^1.77.8", + "sitemap": "^8.0.0", "swiper": "^11.1.9", "wowjs": "^1.1.3", "yet-another-react-lightbox": "^3.25.0" @@ -211,6 +212,21 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/animate.css": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", @@ -230,6 +246,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1055,6 +1077,12 @@ "node": ">=14.0.0" } }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -1063,6 +1091,25 @@ "loose-envify": "^1.1.0" } }, + "node_modules/sitemap": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.0.tgz", + "integrity": "sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", diff --git a/package.json b/package.json index bcd5c4c..1b4ea1e 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "generate-sitemap": "node scripts/generate-sitemap.js" }, "dependencies": { "@emailjs/browser": "^4.4.1", @@ -21,6 +22,7 @@ "react-photoswipe-gallery": "^3.0.2", "react-toastify": "^10.0.5", "sass": "^1.77.8", + "sitemap": "^8.0.0", "swiper": "^11.1.9", "wowjs": "^1.1.3", "yet-another-react-lightbox": "^3.25.0" diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..6892a7b --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1,188 @@ + + + + https://cibusindustries.com/about + 2025-08-09T07:53:53.577Z + 0.8 + + + https://cibusindustries.com/blog + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/news + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/news-details/[id] copy + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/news-details/[slug] + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/contact + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/corporate-profile + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/engineering-innovation + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/factory-workflows + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/home-1 + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/home-1 copy + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/home-1-one-page + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/home-2 + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/home-2-one-page + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/404 + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/faq + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/pricing + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/team + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/team-details + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/product + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/product-details/[slug] + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/project + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/project-details + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/service + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/service-details + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/sustainability-impact + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/turnkey-solutions + 2025-08-09T07:53:53.578Z + 0.8 + + + https://cibusindustries.com/ + 2025-08-09T07:53:53.578Z + 1.0 + + + https://cibusindustries.com/product-details/coconut-deshelling-machine + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/product-details/coconut-dryer-hot-air-tray-type + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/product-details/coconut-pulverizer-grinder + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/product-details/coconut-milk-extractor + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/product-details/virgin-coconut-oil-vco-processing-equipment + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/product-details/coconut-water-processing-unit + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/news-details/rise-of-turnkey-coconut-processing-plants + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/news-details/coconut-deshelling-machine-upgrades + 2025-08-09T07:53:53.578Z + 0.6 + + + https://cibusindustries.com/news-details/choosing-the-right-coconut-dryer + 2025-08-09T07:53:53.578Z + 0.6 + + \ No newline at end of file diff --git a/scripts/generate-sitemap.js b/scripts/generate-sitemap.js new file mode 100644 index 0000000..21bca83 --- /dev/null +++ b/scripts/generate-sitemap.js @@ -0,0 +1,84 @@ + +const fs = require("fs"); +const path = require("path"); +const { allBlogs, allProducts } = require(path.resolve(__dirname, "../utlis/constant.utils.js")); + +const BASE_URL = "https://cibusindustries.com"; +const sitemapPath = path.join(__dirname, "../public/sitemap.xml"); +const appDir = path.join(process.cwd(), "app"); + +const getCurrentDate = () => new Date().toISOString(); + +const cleanUrl = (url) => { + let cleaned = url + .replace(/\/\([^)]*\)/g, "") + .replace(/\/$/, ""); + return cleaned === "" ? "/" : cleaned; +}; + +const getStaticPages = (dir = appDir, basePath = "") => { + let urls = []; + const files = fs.readdirSync(dir); + + files.forEach((file) => { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + + if (stat.isDirectory()) { + const nested = getStaticPages(filePath, `${basePath}/${file}`); + urls = urls.concat(nested); + } else if (file.match(/^(page)\.(js|jsx|ts|tsx)$/)) { + urls.push(basePath || "/"); + } + }); + + return urls; +}; + +const buildXml = (urls) => { + const xmlUrls = urls + .map(({ loc, priority }) => { + return ` + + ${BASE_URL}${cleanUrl(loc)} + ${getCurrentDate()} + ${priority} +`; + }) + .join(""); + + return `\n${xmlUrls} +`; +}; + +const generateSitemap = () => { + const staticPages = getStaticPages().map((route) => ({ + loc: route, + priority: route === "/" ? "1.0" : "0.8", + })); + + const productPages = allProducts.map((p) => ({ + loc: `/product-details/${p.slug}`, + priority: "0.6", + })); + + const blogPages = allBlogs.map((b) => ({ + loc: `/news-details/${b.slug}`, + priority: "0.6", + })); + + const seen = new Set(); + const allUrls = [...staticPages, ...productPages, ...blogPages].filter((item) => { + const cleaned = cleanUrl(item.loc); + if (seen.has(cleaned)) return false; + seen.add(cleaned); + return true; + }); + + const sitemapXml = buildXml(allUrls); + fs.writeFileSync(sitemapPath, sitemapXml, "utf8"); + + console.log(`✅ Sitemap generated at: public/sitemap.xml`); +}; + +generateSitemap();