119 lines
4.6 KiB
JavaScript
119 lines
4.6 KiB
JavaScript
const fs = require('fs');
|
|
const { SitemapStream, streamToPromise } = require('sitemap');
|
|
const path = require('path');
|
|
|
|
const hostname = 'https://metatroncube.in';
|
|
const addTrailingSlash = true; // ✅ Set this true if your Next.js uses trailingSlash: true
|
|
|
|
// // 🔧 Utility to format URLs based on config
|
|
// const formatUrl = (url) => {
|
|
// if (addTrailingSlash && !url.endsWith('/')) return url + '/';
|
|
// if (!addTrailingSlash && url.endsWith('/') && url !== '/') return url.slice(0, -1);
|
|
// return url;
|
|
// };
|
|
// Add a trailing slash only for “directory-like” URLs
|
|
const shouldAddSlash = (url) => {
|
|
// keep "/" as is
|
|
if (url === '/') return false;
|
|
// don't touch file-like URLs (has extension)
|
|
if (/\.[a-z0-9]{2,6}(\?.*)?$/i.test(url)) return false;
|
|
return true;
|
|
};
|
|
|
|
const formatUrl = (url) => {
|
|
// normalize to leading slash
|
|
if (!url.startsWith('/')) url = '/' + url;
|
|
|
|
if (addTrailingSlash && shouldAddSlash(url) && !url.endsWith('/')) {
|
|
return url + '/';
|
|
}
|
|
if (!addTrailingSlash && url.endsWith('/') && url !== '/') {
|
|
return url.slice(0, -1);
|
|
}
|
|
return url;
|
|
};
|
|
|
|
// ✅ Static pages
|
|
const staticLinks = [
|
|
{ url: '/', changefreq: 'daily', priority: 1.0 },
|
|
{ url: '/services-digital-solutions/', changefreq: 'daily', priority: 0.7 },
|
|
{ url: '/about/', changefreq: 'weekly', priority: 0.7 },
|
|
{ url: '/careers/', changefreq: 'weekly', priority: 0.7 },
|
|
{ url: '/portfolio/', changefreq: 'weekly', priority: 0.7 },
|
|
{ url: '/blog/', changefreq: 'weekly', priority: 0.7 },
|
|
{ url: '/contact/', changefreq: 'monthly', priority: 0.5 },
|
|
{ url: '/faq/', changefreq: 'monthly', priority: 0.5 },
|
|
{ url: '/accessibility-statement-for-metatroncube-software-solutions/', changefreq: 'weekly', priority: 0.6 },
|
|
{ url: '/privacy-policy/', changefreq: 'weekly', priority: 0.6 },
|
|
{ url: '/service/website-development-company/', changefreq: 'weekly', priority: 0.6 },
|
|
{ url: '/service/mobile-application-development/', changefreq: 'weekly', priority: 0.6 },
|
|
{ url: '/service/graphic-designing-company/', changefreq: 'weekly', priority: 0.6 },
|
|
{ url: '/service/ui-ux-designing/', changefreq: 'weekly', priority: 0.6 },
|
|
{ url: '/service/search-engine-optimization-seo-content-writing/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/digital-solutions/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/app-development-waterloo/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/kitchener-waterloo-website-design-services/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/professional-website-designers-in-waterloo/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/waterloo-seo-services/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/web-design-toronto-custom-website-creation-by-metatroncube-software-solutions/', changefreq: 'weekly', priority: 0.6 },
|
|
// { url: '/service/web-page-design-in-waterloo/', changefreq: 'weekly', priority: 0.6 },
|
|
|
|
];
|
|
|
|
// ✅ Dynamic blog posts
|
|
const blogPosts = [
|
|
{ slug: 'top-web-development-trends-to-watch-in-2025/' },
|
|
{ slug: 'why-every-startup-needs-a-mobile-app-in-2025/' },
|
|
{ slug: 'how-seo-content-writing-boost-online-sales/' },
|
|
{ slug: 'top-digital-marketing-strategies-for-2025-that-actually-work/' },
|
|
{ slug: 'why-ui-ux-design-can-make-or-break-your-app-in-2025/' },
|
|
{ slug: 'how-metatroncube-transforms-businesses-through-digital-marketing-excellence/' },
|
|
{ slug: 'effective-on-page-seo-tips-for-small-businesses-in-2025/' },
|
|
{ slug: 'how-does-metatroncube-approach-mobile-app-development-from-idea-to-launch/' },
|
|
];
|
|
|
|
// Convert blog slugs to sitemap entries
|
|
const blogLinks = blogPosts.map(post => ({
|
|
url: `/${post.slug}`,
|
|
changefreq: 'weekly',
|
|
priority: 0.6,
|
|
}));
|
|
|
|
const seen = new Set();
|
|
const allLinks = [...staticLinks, ...blogLinks]
|
|
.map(link => ({ ...link, url: formatUrl(link.url) }))
|
|
.filter(link => {
|
|
if (seen.has(link.url)) return false;
|
|
seen.add(link.url);
|
|
return true;
|
|
});
|
|
|
|
async function generateSitemap() {
|
|
try {
|
|
const sitemap = new SitemapStream({ hostname });
|
|
const filePath = path.resolve(__dirname, '../public/sitemap.xml');
|
|
const writeStream = fs.createWriteStream(filePath);
|
|
|
|
sitemap.pipe(writeStream);
|
|
|
|
console.log('📦 Writing URLs to sitemap:');
|
|
allLinks.forEach(link => {
|
|
console.log(' -', hostname + link.url);
|
|
sitemap.write(link);
|
|
});
|
|
|
|
sitemap.end();
|
|
|
|
await Promise.all([
|
|
streamToPromise(sitemap),
|
|
new Promise(resolve => writeStream.on('finish', resolve)),
|
|
]);
|
|
|
|
console.log(`✅ Sitemap.xml created successfully! at: ${filePath}`);
|
|
} catch (error) {
|
|
console.error('❌ Error creating sitemap.xml:', error);
|
|
}
|
|
}
|
|
|
|
generateSitemap();
|