2025-11-19 17:26:31 +05:30
import fs from "fs" ;
import path from "path" ;
import { fileURLToPath } from "url" ;
const _ _filename = fileURLToPath ( import . meta . url ) ;
const _ _dirname = path . dirname ( _ _filename ) ;
const mainDirectory = 'https://www.pozo.app' ;
const routes = [
{ path : "index.html" , pageId : 1 , url : ` ${ mainDirectory } / ` } ,
{ path : "signin/index.html" , pageId : 2 , url : ` ${ mainDirectory } /signin ` } ,
2025-11-26 11:53:58 +05:30
{ path : "home/pricing-pozoapp/index.html" , pageId : 3 , url : ` ${ mainDirectory } /pricing ` } ,
2025-11-19 17:26:31 +05:30
{ path : "contact-us/index.html" , pageId : 4 , url : ` ${ mainDirectory } /contact-us ` } ,
{ path : "blog/index.html" , pageId : 5 , url : ` ${ mainDirectory } /blog ` } ,
{ path : "about-us/index.html" , pageId : 6 , url : ` ${ mainDirectory } /about-us ` } ,
{ path : "solutions/index.html" , pageId : 9 , url : ` ${ mainDirectory } /solutions ` } ,
] ;
const seoData = {
1 : {
title : "Retail ERP & POS for Indian MSMEs | POZO" ,
description : "Fast billing, smart inventory, GST-ready POS. POZO helps kirana, mini-supermarkets & retail chains speed checkout, connect weighing scales, and manage multi-store ops." ,
keywords : "retail ERP, POS software, billing software, inventory management, GST billing, kirana store, mini supermarket, weighing scale POS, multi-store ERP, Indian retail software" ,
image : ` ${ mainDirectory } /og/home.jpg ` ,
} ,
2 : {
title : "Sign In to PozoApp | Retail ERP & POS Login" ,
description : "Access your business dashboard. Sign in to POZO retail ERP & POS system for billing, inventory management, and business analytics." ,
keywords : "POZO login, retail ERP login, POS software login, business dashboard, billing software access, inventory management login" ,
image : ` ${ mainDirectory } /og/Signin-og.jpg ` ,
} ,
3 : {
title : "Pricing - Retail ERP & POS Plans | POZO" ,
description : "Simple plans for MSMEs. Fast billing, inventory, GST e-invoice, weighing-scale integration, WhatsApp e-bills & multi-store controls. Book a demo." ,
keywords : "POZO pricing, retail ERP pricing, POS software cost, billing software price, inventory management pricing, GST software cost, MSME software pricing" ,
image : ` ${ mainDirectory } /og/pricing-og.jpg ` ,
} ,
4 : {
title : "Contact POZO | Retail ERP & POS Support" ,
description : "Get support and sales information for POZO retail ERP & POS solutions. Contact us for billing software, inventory management, and business automation." ,
keywords : "POZO contact, retail ERP support, POS software support, billing software help, inventory management support, customer service, technical support" ,
image : ` ${ mainDirectory } /og/contact-og.jpg ` ,
} ,
5 : {
title : "POZO Blog — Retail ERP, POS & Grocery Billing Guides" ,
description : "Practical guides on POS billing, weighing-scale integration, GST e-invoices, multi-store ERP & inventory control for Indian retailers." ,
keywords : "retail blog, POS guides, billing tutorials, inventory tips, GST billing guide, weighing scale integration, multi-store management, retail technology" ,
image : ` ${ mainDirectory } /og/blog-og.jpg ` ,
} ,
6 : {
title : "About POZO | Retail ERP & POS Solutions for MSMEs" ,
description : "Learn about POZO's mission to digitize Indian retail businesses with affordable ERP & POS solutions, billing software, and inventory management." ,
keywords : "about POZO, retail digitization, MSME solutions, Indian retail software, ERP for small business, POS for kirana stores, retail technology company" ,
image : ` ${ mainDirectory } /og/about-og.jpg ` ,
} ,
9 : {
title : "Retail Solutions | ERP & POS Software for Every Business" ,
description : "Comprehensive retail solutions: billing software, inventory management, GST compliance, weighing scale integration, and multi-store ERP for Indian businesses." ,
keywords : "retail solutions, comprehensive ERP, POS solutions, billing solutions, inventory solutions, GST compliance software, weighing scale POS, multi-store solutions" ,
image : ` ${ mainDirectory } /og/solutions-og.jpg ` ,
} ,
} ;
async function generateSEOFiles ( ) {
for ( const route of routes ) {
const pageSeo = seoData [ route . pageId ] ;
const filePath = path . join ( _ _dirname , "../dist" , route . path ) ;
fs . mkdirSync ( path . dirname ( filePath ) , { recursive : true } ) ;
let html ;
if ( fs . existsSync ( filePath ) ) {
html = fs . readFileSync ( filePath , "utf8" ) ;
} else {
html = fs . readFileSync ( path . join ( _ _dirname , "../dist/index.html" ) , "utf8" ) ;
}
2025-11-26 11:53:58 +05:30
// Remove ONLY SEO-specific tags, preserve verification and analytics
2025-11-19 17:26:31 +05:30
html = html
. replace ( /<meta name="description"[^>]*>/g , '' )
2025-11-26 11:53:58 +05:30
. replace ( /<meta name="keywords"[^>]*>/g , '' )
. replace ( /<meta property="og:type"[^>]*>/g , '' )
2025-11-19 17:26:31 +05:30
. replace ( /<meta property="og:title"[^>]*>/g , '' )
. replace ( /<meta property="og:description"[^>]*>/g , '' )
. replace ( /<meta property="og:image"[^>]*>/g , '' )
. replace ( /<meta property="og:url"[^>]*>/g , '' )
2025-11-26 11:53:58 +05:30
. replace ( /<meta property="twitter:card"[^>]*>/g , '' )
2025-11-19 17:26:31 +05:30
. replace ( /<meta property="twitter:title"[^>]*>/g , '' )
. replace ( /<meta property="twitter:description"[^>]*>/g , '' )
. replace ( /<meta property="twitter:image"[^>]*>/g , '' )
. replace ( /<meta property="twitter:url"[^>]*>/g , '' )
2025-11-26 11:53:58 +05:30
. replace ( /<meta name="twitter:card"[^>]*>/g , '' )
. replace ( /<meta name="twitter:title"[^>]*>/g , '' )
. replace ( /<meta name="twitter:description"[^>]*>/g , '' )
. replace ( /<meta name="twitter:image"[^>]*>/g , '' )
. replace ( /<meta name="twitter:url"[^>]*>/g , '' )
2025-11-19 17:26:31 +05:30
. replace ( /<link rel="canonical"[^>]*>/g , '' ) ;
// Replace title
html = html . replace ( /<title>[^<]*<\/title>/g , ` <title> ${ pageSeo . title } </title> ` ) ;
2025-11-26 11:53:58 +05:30
// Add verification tags and analytics if not present
const verificationTags = `
< meta name = "msvalidate.01" content = "bdb9a09f08f78048c94cb684979cf786" / >
<!-- Microsoft Clarity -- >
< script type = "text/javascript" >
( function ( c , l , a , r , i , t , y ) {
c [ a ] = c [ a ] || function ( ) { ( c [ a ] . q = c [ a ] . q || [ ] ) . push ( arguments ) } ;
t = l . createElement ( r ) ; t . async = 1 ; t . src = "https://www.clarity.ms/tag/" + i ;
y = l . getElementsByTagName ( r ) [ 0 ] ; y . parentNode . insertBefore ( t , y ) ;
} ) ( window , document , "clarity" , "script" , "u49bg68ikk" ) ;
< / s c r i p t >
<!-- Global site tag ( gtag . js ) - Google Analytics -- >
< script async src = "https://www.googletagmanager.com/gtag/js?id=G-2QV0HX3QD6" > < / s c r i p t >
< script >
window . dataLayer = window . dataLayer || [ ] ;
function gtag ( ) { dataLayer . push ( arguments ) ; }
gtag ( 'js' , new Date ( ) ) ;
gtag ( 'config' , 'G-2QV0HX3QD6' ) ;
< / s c r i p t >
<!-- Google Tag Manager -- >
< script > ( function ( w , d , s , l , i ) {
w [ l ] = w [ l ] || [ ] ; w [ l ] . push ( {
'gtm.start' :
new Date ( ) . getTime ( ) , event : 'gtm.js'
} ) ; var f = d . getElementsByTagName ( s ) [ 0 ] ,
j = d . createElement ( s ) , dl = l != 'dataLayer' ? '&l=' + l : '' ; j . async = true ; j . src =
'https://www.googletagmanager.com/gtm.js?id=' + i + dl ; f . parentNode . insertBefore ( j , f ) ;
} ) ( window , document , 'script' , 'dataLayer' , 'GTM-W2NQZPX' ) ; < / s c r i p t >
<!-- Preconnect for performance -- >
< link rel = "preconnect" href = "https://fonts.googleapis.com" >
< link rel = "preconnect" href = "https://fonts.gstatic.com" crossorigin >
< link rel = "preconnect" href = "https://fonts.cdnfonts.com" >
< link rel = "preconnect" href = "https://unpkg.com" >
< link href = "https://fonts.cdnfonts.com/css/wasted-vindey" rel = "stylesheet" media = "print" onload = "this.media='all'" / >
< link href = "https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,500;0,600;0,700&display=swap" rel = "stylesheet" / >
< link href = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Manrope:wght@400;500;600;700&family=Montserrat:wght@400;500;600;700&display=swap" rel = "stylesheet" media = "print" onload = "this.media='all'" / >
< link href = "https://unpkg.com/aos@2.3.1/dist/aos.css" rel = "stylesheet" / >
< link rel = "sitemap" href = "/sitemap.xml" / >
<!-- Structured Data -- >
< script type = "application/ld+json" >
{
"@context" : "https://schema.org" ,
"@graph" : [
{
"@type" : "Organization" ,
"name" : "POZO" ,
"url" : "https://www.pozo.app/" ,
"logo" : "https://www.pozo.app/src/Images/PozoAppFavicon.png" ,
"foundingDate" : "2019" ,
"contactPoint" : {
"@type" : "ContactPoint" ,
"telephone" : "+91-7324000011" ,
"contactType" : "customer service"
} ,
"address" : {
"@type" : "PostalAddress" ,
"streetAddress" : "No 51 Step Colony, Dharga" ,
"addressLocality" : "Hosur" ,
"addressRegion" : "Tamil Nadu" ,
"postalCode" : "635126" ,
"addressCountry" : "IN"
} ,
"sameAs" : [ ]
} ,
{
"@type" : "WebSite" ,
"name" : "POZO" ,
"url" : "https://www.pozo.app/" ,
"potentialAction" : {
"@type" : "SearchAction" ,
"target" : "https://www.pozo.app/search?q={query}" ,
"query-input" : "required name=query"
}
} ,
{
"@type" : "WebPage" ,
"url" : "${route.url}" ,
"name" : "${pageSeo.title}" ,
"isPartOf" : { "@id" : "https://www.pozo.app/" } ,
"description" : "${pageSeo.description}"
} ,
{
"@type" : "SoftwareApplication" ,
"name" : "POZO - Retail ERP & POS" ,
"applicationCategory" : "BusinessApplication" ,
"operatingSystem" : "Windows, Android, iOS" ,
"offers" : {
"@type" : "Offer" ,
"price" : "0" ,
"priceCurrency" : "INR" ,
"availability" : "https://schema.org/InStock"
} ,
"aggregateRating" : {
"@type" : "AggregateRating" ,
"ratingValue" : "4.8" ,
"ratingCount" : "150"
} ,
"description" : "Complete retail ERP and POS solution for Indian MSMEs with GST billing, inventory management, and multi-store operations." ,
"featureList" : [
"GST Billing" ,
"Inventory Management" ,
"Multi-store Operations" ,
"Weighing Scale Integration" ,
"Real-time Analytics" ,
"Mobile POS"
] ,
"screenshot" : "${pageSeo.image}" ,
"softwareVersion" : "2.0" ,
"author" : {
"@type" : "Organization" ,
"name" : "POZO"
}
}
]
}
< / s c r i p t >
< script src = "https://assets.calendly.com/assets/external/widget.js" type = "text/javascript" > < / s c r i p t > ` ;
2025-11-19 17:26:31 +05:30
// Add all new SEO tags after title
2025-11-26 11:53:58 +05:30
const newSeoTags = ` ${ verificationTags }
<!-- SEO Meta Tags -- >
2025-11-19 17:26:31 +05:30
< meta name = "description" content = "${pageSeo.description}" / >
< meta name = "keywords" content = "${pageSeo.keywords}" / >
<!-- Open Graph / Facebook -- >
< meta property = "og:type" content = "website" / >
< meta property = "og:url" content = "${route.url}" / >
< meta property = "og:title" content = "${pageSeo.title}" / >
< meta property = "og:description" content = "${pageSeo.description}" / >
< meta property = "og:image" content = "${pageSeo.image}" / >
2025-11-26 11:53:58 +05:30
<!-- Twitter -- >
< meta name = "twitter:card" content = "summary_large_image" / >
< meta name = "twitter:url" content = "${route.url}" / >
< meta name = "twitter:title" content = "${pageSeo.title}" / >
< meta name = "twitter:description" content = "${pageSeo.description}" / >
< meta name = "twitter:image" content = "${pageSeo.image}" / >
2025-11-19 17:26:31 +05:30
2025-11-26 11:53:58 +05:30
< link rel = "canonical" href = "${route.url}" / > ` ;
// Only add verification tags if they don't exist
if ( ! html . includes ( 'google-site-verification' ) && ! html . includes ( 'gtag' ) ) {
html = html . replace ( /(<title>[^<]*<\/title>)/ , ` $ 1 ${ newSeoTags } ` ) ;
} else {
// Just add SEO tags without verification
const seoOnlyTags = `
<!-- SEO Meta Tags -- >
< meta name = "description" content = "${pageSeo.description}" / >
< meta name = "keywords" content = "${pageSeo.keywords}" / >
<!-- Open Graph / Facebook -- >
< meta property = "og:type" content = "website" / >
< meta property = "og:url" content = "${route.url}" / >
< meta property = "og:title" content = "${pageSeo.title}" / >
< meta property = "og:description" content = "${pageSeo.description}" / >
< meta property = "og:image" content = "${pageSeo.image}" / >
2025-11-19 17:26:31 +05:30
<!-- Twitter -- >
2025-11-26 11:53:58 +05:30
< meta name = "twitter:card" content = "summary_large_image" / >
< meta name = "twitter:url" content = "${route.url}" / >
< meta name = "twitter:title" content = "${pageSeo.title}" / >
< meta name = "twitter:description" content = "${pageSeo.description}" / >
< meta name = "twitter:image" content = "${pageSeo.image}" / >
2025-11-19 17:26:31 +05:30
< link rel = "canonical" href = "${route.url}" / > ` ;
2025-11-26 11:53:58 +05:30
html = html . replace ( /(<title>[^<]*<\/title>)/ , ` $ 1 ${ seoOnlyTags } ` ) ;
}
2025-11-19 17:26:31 +05:30
2025-11-26 11:53:58 +05:30
// Add GTM noscript to body if not present
if ( ! html . includes ( 'GTM-W2NQZPX' ) ) {
html = html . replace (
'<body>' ,
` <body>
<!-- Google Tag Manager ( noscript ) -- >
< noscript > < iframe src = "https://www.googletagmanager.com/ns.html?id=GTM-W2NQZPX" height = "0" width = "0" style = "display:none;visibility:hidden" > < / i f r a m e > < / n o s c r i p t >
<!-- End Google Tag Manager ( noscript ) -- > `
) ;
}
// Add AOS script before closing body tag
if ( ! html . includes ( 'aos.js' ) ) {
html = html . replace (
'</body>' ,
` <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
< / b o d y > `
) ;
}
2025-11-19 17:26:31 +05:30
fs . writeFileSync ( filePath , html ) ;
2025-11-26 11:53:58 +05:30
console . log ( ` ✓ Generated ${ route . path } with complete SEO ` ) ;
2025-11-19 17:26:31 +05:30
console . log ( ` Title: ${ pageSeo . title } ` ) ;
console . log ( ` Image: ${ pageSeo . image } ` ) ;
console . log ( ` URL: ${ route . url } ` ) ;
console . log ( '' ) ;
}
2025-11-26 11:53:58 +05:30
console . log ( "✓ All SEO files fixed with verification tags!" ) ;
2025-11-19 17:26:31 +05:30
}
generateSEOFiles ( ) . catch ( console . error ) ;