diff --git a/new_issues_seo.md b/new_issues_seo.md index e69de29..2605655 100644 --- a/new_issues_seo.md +++ b/new_issues_seo.md @@ -0,0 +1,641 @@ +Issues +/ +Open Graph tags incomplete + +Why and how to fix + +Submit to IndexNow + +Create new issue + +All URLs + +Pages + +Resources + +Content + +Links + +Redirects + +Indexability + +Sitemaps + +Ahrefs metrics +Word or phrase + +URL + +Advanced filter +Crawl history +Hide chart +12 Jan +13 Jan +13 Jan +14 Jan +14 Jan +15 Jan +0 +2 +4 +6 +8 +All filter results + +All filter results +8 + +Lost from filter results +0 + +Lost +0 + +Patches + +Changes: Don't show + +Columns + +Export +PR +URL +Organic traffic +Is valid Open graph +Open graph attributes +Open graph values +Depth +Is indexable page +No. of all inlinks +24 +html +Free vCard QR Generator: Digital Cards | QR Master +https://www.qrmaster.net/blog/vcard-qr-code-generator +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +Professional business card with vCard QR code being scanned by smartphone +https://www.qrmaster.net/blog/vcard-qr-code.png +Create professional vCard QR codes for digital business cards. Share contact info instantly with a scan—includes templates and best practices. +Free vCard QR Generator: Digital Cards +0 +Yes +8 +24 +html +Restaurant Menu QR Codes: 2025 Guide | QR Master +https://www.qrmaster.net/blog/qr-code-restaurant-menu +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +Restaurant table with QR code menu card and smartphone scanning +https://www.qrmaster.net/blog/restaurant-qr-menu.png +Step-by-step guide to creating digital menu QR codes for your restaurant. Learn best practices for touchless menus, placement tips, and tracking. +Restaurant Menu QR Codes: 2025 Guide +0 +Yes +8 +24 +html +QR Code Analytics: The Complete Guide | QR Master +https://www.qrmaster.net/blog/qr-code-analytics +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +QR Code Analytics dashboard displaying scan metrics and user data +https://www.qrmaster.net/blog/qr-code-analytics-hero.webp +Master QR Code Analytics with our complete guide. Learn how to track scans, measure ROI, and optimize your marketing campaigns using real-time data. +QR Code Analytics: The Complete Guide +0 +Yes +8 +24 +html +Dynamic vs Static QR Codes: The Ultimate Comparison | QR Master +https://www.qrmaster.net/blog/dynamic-vs-static-qr-codes +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +Comparison graphic showing features of static versus dynamic QR codes +https://www.qrmaster.net/blog/static-vs-dynamic-qr-codes-hero.png +Static vs Dynamic QR Codes: Which should you choose? Learn the key differences, pros and cons, and why dynamic codes are better for business. +Dynamic vs Static QR Codes: The Ultimate Comparison +0 +Yes +8 +24 +html +How to Generate Bulk QR Codes from Excel | QR Master +https://www.qrmaster.net/blog/bulk-qr-code-generator-excel +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +Excel spreadsheet being converted into multiple QR codes +https://www.qrmaster.net/blog/building-qr-generator.png +Generate hundreds of QR codes from Excel or CSV files in minutes. Step-by-step guide with templates, best practices, and free tools. +How to Generate Bulk QR Codes from Excel +0 +Yes +8 +24 +html +QR Code Print Size Guide: Minimum Sizes for Every Use Case | QR Master +https://www.qrmaster.net/blog/qr-code-print-size-guide +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +Various print materials showing different QR code sizes +https://www.qrmaster.net/blog/qr-print-sizes.png +Complete guide to QR code print sizes. Learn minimum dimensions for business cards, posters, banners, and more to ensure reliable scanning. +QR Code Print Size Guide: Minimum Sizes for Every Use Case +0 +Yes +8 +24 +html +Best QR Code Generator for Small Business 2025 | QR Master +https://www.qrmaster.net/blog/qr-code-small-business +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +Small business owner using QR codes for customer engagement +https://www.qrmaster.net/blog/small-business-qr.png +Find the best QR code solution for your small business. Compare features, pricing, and use cases for marketing, payments, and operations. +Best QR Code Generator for Small Business 2025 +0 +Yes +8 +24 +html +QR Code Tracking: Complete Guide 2025 | QR Master +https://www.qrmaster.net/blog/qr-code-tracking-guide-2025 +0 +No +og:type +og:image:alt +og:image +og:description +og:title +article +QR Code Tracking and analytics dashboard visualization +https://www.qrmaster.net/blog/qr-code-tracking-guide-hero.webp +The complete guide to QR Code Tracking in 2025. Learn how to track scans, measure ROI, and optimize your marketing campaigns. +QR Code Tracking: Complete Guide 2025 +0 +Yes +8 +Showing 8 of 8 + + + + + + + + + + + + + + + + +Issues +/ +Pages to submit to IndexNow + +Why and how to fix + +Submit to IndexNow + +Create new issue + +All URLs + +Pages + +Resources + +Content + +Links + +Redirects + +Indexability + +Sitemaps + +Ahrefs metrics +Word or phrase + +URL + +Advanced filter +Crawl history +Hide chart +12 Jan +13 Jan +13 Jan +14 Jan +14 Jan +15 Jan +0 +9 +18 +27 +36 +All filter results + +All filter results +12 + +Lost from filter results + +Lost + +Patches: Show all + +Changes: Absolute + +Columns + +Export +PR +URL +Organic traffic +Changes +HTTP status code +Content type +Is indexable page +Title +Patch it + +Batch AI +Meta description +Patch it + +Batch AI +H1 +H2 +No. of content words +Changes +No. of internal outlinks +Changes +No. of external outlinks +Changes +Page text +First found at +40 +html +QR Master: Dynamic QR Generator +https://www.qrmaster.net/ +0 +200 +text/html; charset=utf-8 +Yes +QR Master: Dynamic QR Generator +Enter new title +Create professional QR codes with QR Master. Dynamic QR with tracking, bulk generation, custom branding, and real-time analytics for all your campaigns. +Enter new meta description +QR Master: Dynamic QR Code Generator with Analytics +Create QR Codes That Work Everywhere +Create QR Codes That Work Everywhere +Instant QR Code Generator +The Future of QR Codes is AI-Powered +More Free QR Code Tools +Why Dynamic QR Codes Save You Money +All 8 +777 +29 +0 +View text +5 KB +38 +html +QR Insights: Latest QR Strategies | QR Master +https://www.qrmaster.net/blog +0 +200 +text/html; charset=utf-8 +Yes +QR Insights: Latest QR Strategies | QR Master +Enter new title +Expert guides on QR code analytics, dynamic vs static codes, bulk generation, and smart marketing use cases. Learn how to maximize your QR campaign ROI. +Enter new meta description +QR Code Insights +481 +495 +−14 +37 +0 +View changes +3 KB +3 KB +38 +html +Pricing Plans | QR Master +https://www.qrmaster.net/pricing +0 +200 +text/html; charset=utf-8 +Yes +Pricing Plans | QR Master +Enter new title +Choose the perfect QR code plan for your needs. Free, Pro, and Business plans with dynamic QR codes, analytics, bulk generation, and custom branding. +Enter new meta description +QR Master Pricing – Choose Your QR Code Plan +Choose Your Plan +Compare our plans +Choose Your Plan +271 +29 +30 +−1 +0 +View text +2 KB +38 +html +QR Code Erstellen – Kostenlos | QR Master +https://www.qrmaster.net/qr-code-erstellen +0 +200 +text/html; charset=utf-8 +Yes +QR Code Erstellen – Kostenlos | QR Master +Enter new title +Erstellen Sie QR Codes kostenlos in Sekunden. Dynamische QR-Codes mit Tracking, Branding und Massen-Erstellung. Für immer kostenlos. +Enter new meta description +QR Code Erstellen – Kostenloser QR Code Generator mit Tracking +Erstellen Sie QR-Codes, die überall funktionieren +Erstellen Sie QR-Codes, die überall funktionieren +Sofortiger QR-Code-Generator +Warum dynamische QR-Codes Geld sparen +Alles was Sie brauchen, um professionelle QR-Codes zu erstellen +Wählen Sie Ihren Plan +All 6 +554 +29 +0 +View text +4 KB +24 +html +Free vCard QR Generator: Digital Cards | QR Master +https://www.qrmaster.net/blog/vcard-qr-code-generator +0 +200 +text/html; charset=utf-8 +Yes +Free vCard QR Generator: Digital Cards | QR Master +Enter new title +Create professional vCard QR codes for digital business cards. Share contact info instantly with a scan—includes templates and best practices. +Enter new meta description +Free vCard QR Generator: Digital Cards +Quick Answer +What is a vCard QR Code? +Why Use a Digital Business Card QR Code? +Information You Can Include in a vCard +Static vs Dynamic vCard QR Codes +All 13 +1,135 +1,149 +−14 +37 +0 +View changes +7 KB +7 KB +24 +html +Restaurant Menu QR Codes: 2025 Guide | QR Master +https://www.qrmaster.net/blog/qr-code-restaurant-menu +0 +200 +text/html; charset=utf-8 +Yes +Restaurant Menu QR Codes: 2025 Guide | QR Master +Enter new title +Step-by-step guide to creating digital menu QR codes for your restaurant. Learn best practices for touchless menus, placement tips, and tracking. +Enter new meta description +Restaurant Menu QR Codes: 2025 Guide +Quick Answer +Why Restaurants Need QR Code Menus in 2025 +Step 1: Prepare Your Digital Menu +Step 2: Create Your QR Code with QR Master +Step 3: Customize Your Restaurant QR Code +All 13 +1,242 +1,256 +−14 +38 +0 +View changes +8 KB +8 KB +24 +html +QR Code Analytics: The Complete Guide | QR Master +https://www.qrmaster.net/blog/qr-code-analytics +0 +200 +text/html; charset=utf-8 +Yes +QR Code Analytics: The Complete Guide | QR Master +Enter new title +Master QR Code Analytics with our complete guide. Learn how to track scans, measure ROI, and optimize your marketing campaigns using real-time data. +Master QR Code Analytics with our complete guide. Learn how to track scans, measure ROI, and optimize your marketing campaigns using real-time data and insights. +Enter new meta description +QR Code Analytics: The Complete Guide +Quick Answer +What Are Scan Analytics? +How to Set Up QR Code Analytics +Key Metrics in QR Code Analytics +Advanced Campaign Tracking Strategies +All 12 +1,526 +1,538 +−12 +37 +0 +View changes +10 KB +10 KB +24 +html +Dynamic vs Static QR Codes: The Ultimate Comparison | QR Master +https://www.qrmaster.net/blog/dynamic-vs-static-qr-codes +0 +200 +text/html; charset=utf-8 +Yes +Dynamic vs Static QR Codes: The Ultimate Comparison | QR Master +Enter new title +Static vs Dynamic QR Codes: Which should you choose? Learn the key differences, pros and cons, and why dynamic codes are better for business. +Static vs Dynamic QR Codes: Which one should you choose? Learn the key differences, pros and cons, and why dynamic QR codes are the better choice for business and marketing. +Enter new meta description +Dynamic vs Static QR Codes: The Ultimate Comparison +Quick Answer +What is a Static QR Code? +What is a Dynamic QR Code? +Direct Comparison: Static vs Dynamic +Why Dynamic QR Codes Are Better for Business +All 10 +1,074 +1,082 +−8 +37 +0 +View changes +7 KB +7 KB +24 +html +How to Generate Bulk QR Codes from Excel | QR Master +https://www.qrmaster.net/blog/bulk-qr-code-generator-excel +0 +200 +text/html; charset=utf-8 +Yes +How to Generate Bulk QR Codes from Excel | QR Master +Enter new title +Generate hundreds of QR codes from Excel or CSV files in minutes. Step-by-step guide with templates, best practices, and free tools. +Enter new meta description +How to Generate Bulk QR Codes from Excel +Quick Answer +How Bulk QR Code Generation Works +Step-by-Step Guide: Excel to QR Codes +Use Cases for Bulk QR Codes +Free vs Paid Bulk QR Tools +All 12 +1,882 +1,896 +−14 +37 +1 +View changes +12 KB +13 KB +24 +html +QR Code Print Size Guide: Minimum Sizes for Every Use Case | QR Master +https://www.qrmaster.net/blog/qr-code-print-size-guide +0 +200 +text/html; charset=utf-8 +Yes +QR Code Print Size Guide: Minimum Sizes for Every Use Case | QR Master +Enter new title +Complete guide to QR code print sizes. Learn minimum dimensions for business cards, posters, banners, and more to ensure reliable scanning. +Enter new meta description +QR Code Print Size Guide: Minimum Sizes for Every Use Case +Quick Answer +Why QR Code Size Matters +The Scanning Distance Formula +QR Code Sizes by Application +Factors Affecting Scanability +All 12 +948 +962 +−14 +37 +0 +View changes +6 KB +6 KB +24 +html +Best QR Code Generator for Small Business 2025 | QR Master +https://www.qrmaster.net/blog/qr-code-small-business +0 +200 +text/html; charset=utf-8 +Yes +Best QR Code Generator for Small Business 2025 | QR Master +Enter new title +Find the best QR code solution for your small business. Compare features, pricing, and use cases for marketing, payments, and operations. +Enter new meta description +Best QR Code Generator for Small Business 2025 +Quick Answer +Why Small Businesses Need QR Codes +Top 10 QR Code Use Cases for Small Business +What to Look for in a Small Business QR Solution +QR Master for Small Business +All 11 +1,034 +1,048 +−14 +37 +0 +View changes +7 KB +7 KB +24 +html +QR Code Tracking: Complete Guide 2025 | QR Master +https://www.qrmaster.net/blog/qr-code-tracking-guide-2025 +0 +200 +text/html; charset=utf-8 +Yes +QR Code Tracking: Complete Guide 2025 | QR Master +Enter new title +The complete guide to QR Code Tracking in 2025. Learn how to track scans, measure ROI, and optimize your marketing campaigns. +The complete guide to QR Code Tracking in 2025. Learn how to track scans, measure ROI with analytics tools, and optimize your marketing campaigns for maximum engagement. +Enter new meta description +QR Code Tracking: Complete Guide 2025 +Quick Answer +What is QR Code Tracking? +Why Track QR Codes? Key Benefits +How to Track QR Code Scans: 4 Methods +QR Code Tracking Tools Comparison +All 15 +2,959 +2,967 +−8 +38 +1 +View changes +19 KB +19 KB +Showing 12 of 12 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e52b99d..5334084 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,11 +14,13 @@ "@prisma/client": "^5.7.0", "@stripe/stripe-js": "^8.0.0", "@types/d3-scale": "^4.0.9", + "axios": "^1.13.2", "bcryptjs": "^2.4.3", "chart.js": "^4.4.0", "clsx": "^2.0.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.10", + "dotenv": "^17.2.3", "exceljs": "^4.4.0", "file-saver": "^2.0.5", "framer-motion": "^12.24.10", @@ -3085,6 +3087,12 @@ "node": ">= 0.4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/attr-accept": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", @@ -3158,6 +3166,17 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -3687,6 +3706,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -4175,6 +4206,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -4237,6 +4277,18 @@ "@types/trusted-types": "^2.0.7" } }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4421,7 +4473,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5249,6 +5300,26 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -5282,6 +5353,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -5723,7 +5810,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6832,6 +6918,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -7844,6 +7951,12 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index 2b4b775..718566c 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "submit:indexnow": "tsx scripts/submit-indexnow.ts", "start": "next start", "lint": "next lint", + "indexnow": "tsx scripts/submit-indexnow.ts", "db:generate": "prisma generate", "db:migrate": "prisma migrate dev", "db:deploy": "prisma migrate deploy", @@ -31,11 +32,13 @@ "@prisma/client": "^5.7.0", "@stripe/stripe-js": "^8.0.0", "@types/d3-scale": "^4.0.9", + "axios": "^1.13.2", "bcryptjs": "^2.4.3", "chart.js": "^4.4.0", "clsx": "^2.0.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.10", + "dotenv": "^17.2.3", "exceljs": "^4.4.0", "file-saver": "^2.0.5", "framer-motion": "^12.24.10", @@ -87,4 +90,4 @@ "engines": { "node": ">=18.0.0" } -} +} \ No newline at end of file diff --git a/scripts/submit-indexnow.ts b/scripts/submit-indexnow.ts index ebe1ede..bc52125 100644 --- a/scripts/submit-indexnow.ts +++ b/scripts/submit-indexnow.ts @@ -1,81 +1,21 @@ -import { blogPostList } from '../src/lib/blog-data'; -import fs from 'fs'; -import path from 'path'; +// Helper script to run IndexNow submission +// Run with: npx tsx scripts/submit-indexnow.ts -const HOST = 'www.qrmaster.net'; -const KEY = 'bb6dfaacf1ed41a880281c426c54ed7c'; -const KEY_LOCATION = `https://${HOST}/${KEY}.txt`; -const INDEXNOW_ENDPOINT = 'https://api.indexnow.org/indexnow'; +import { getAllIndexableUrls, submitToIndexNow } from '../src/lib/indexnow'; -async function submitIndexNow() { - console.log('🚀 Starting IndexNow submission...'); +async function main() { + console.log('Gathering URLs for IndexNow submission...'); + const urls = getAllIndexableUrls(); + console.log(`Found ${urls.length} indexable URLs.`); - // 1. Gather all URLs - const baseUrl = `https://${HOST}`; - const staticPages = [ - '', - '/pricing', - '/faq', - '/blog', - '/signup', - '/login', - '/privacy', - '/qr-code-erstellen', - '/qr-code-tracking', - '/dynamic-qr-code-generator', - '/bulk-qr-code-generator', - '/reprint-calculator', - '/newsletter', - ]; - - // Dynamically get tool slugs from directory - const toolsDir = path.join(process.cwd(), 'src/app/(marketing)/tools'); - let freeTools: string[] = []; - - try { - freeTools = fs.readdirSync(toolsDir).filter(file => { - return fs.statSync(path.join(toolsDir, file)).isDirectory(); - }); - } catch (e) { - console.warn('⚠️ Could not read tools directory:', e); + // Basic validation of key presence (logic can be improved) + if (!process.env.INDEXNOW_KEY) { + console.warn('⚠️ WARNING: INDEXNOW_KEY environment variable is not set. Using placeholder.'); + // In production, you'd fail here. For dev/demo, we proceed but expect failure from API. } - const toolTypeUrls = freeTools.map(slug => `/tools/${slug}`); - const blogUrls = blogPostList.map(post => `/blog/${post.slug}`); - - const allPaths = [...staticPages, ...toolTypeUrls, ...blogUrls]; - const urlList = allPaths.map(path => `${baseUrl}${path}`); - - console.log(`📝 Found ${urlList.length} URLs to submit.`); - - // 2. Prepare payload - const payload = { - host: HOST, - key: KEY, - keyLocation: KEY_LOCATION, - urlList: urlList, - }; - - try { - // 3. Send Request - const response = await fetch(INDEXNOW_ENDPOINT, { - method: 'POST', - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - body: JSON.stringify(payload), - }); - - if (response.status === 200 || response.status === 202) { - console.log('✅ IndexNow submission successful!'); - } else { - console.error(`❌ IndexNow submission failed. Status: ${response.status}`); - console.error(await response.text()); - } - } catch (error) { - console.error('❌ Error submitting to IndexNow:', error); - } + await submitToIndexNow(urls); } -submitIndexNow(); +main().catch(console.error); diff --git a/src/app/(marketing)/bulk-qr-code-generator/page.tsx b/src/app/(marketing)/bulk-qr-code-generator/page.tsx index 2d0e2a6..83662ad 100644 --- a/src/app/(marketing)/bulk-qr-code-generator/page.tsx +++ b/src/app/(marketing)/bulk-qr-code-generator/page.tsx @@ -54,7 +54,7 @@ export default function BulkQRCodeGeneratorPage() { title: 'Contact Cards', description: 'Create vCard QR codes with contact information', format: 'FirstName,LastName,Email,Phone,Organization,Title', - example: 'John Doe,VCARD,John,Doe,john@example.com,+1234567890,Company Inc,CEO', + example: 'John Doe,VCARD,John,Doe,john' + '@' + 'example.com,+1234567890,Company Inc,CEO', }, { type: 'GEO', @@ -448,7 +448,7 @@ export default function BulkQRCodeGeneratorPage() { John Doe VCARD - John,Doe,john@example.com,+1234567890,Company,CEO + John,Doe,john{'@'}example.com,+1234567890,Company,CEO contact diff --git a/src/components/ui/ObfuscatedMailto.tsx b/src/components/ui/ObfuscatedMailto.tsx index 2d6e718..9d46b80 100644 --- a/src/components/ui/ObfuscatedMailto.tsx +++ b/src/components/ui/ObfuscatedMailto.tsx @@ -20,9 +20,10 @@ export function ObfuscatedMailto({ email, className, children }: ObfuscatedMailt setIsMounted(true); }, []); - // Before hydration, render as plain text/span to avoid Cloudflare manipulation + // Before hydration, render as obfuscated text to avoid Cloudflare manipulation if (!isMounted) { - return {children || email}; + const obfuscatedEmail = email.replace('@', ' [at] ').replace(/\./g, ' [dot] '); + return {children || obfuscatedEmail}; } // After hydration, render as a proper mailto link diff --git a/src/lib/indexnow.ts b/src/lib/indexnow.ts new file mode 100644 index 0000000..0b772a7 --- /dev/null +++ b/src/lib/indexnow.ts @@ -0,0 +1,83 @@ +import axios from 'axios'; +import dotenv from 'dotenv'; +import { blogPostList } from '../lib/blog-data'; + +dotenv.config(); + +const INDEXNOW_ENDPOINT = 'https://api.indexnow.org/indexnow'; +const HOST = 'www.qrmaster.net'; +// You need to generate a key from https://www.bing.com/indexnow and place it in your public folder +// For now, we'll assume a key exists or is provided via env +const KEY = process.env.INDEXNOW_KEY || 'your-indexnow-key'; +const KEY_LOCATION = `https://${HOST}/${KEY}.txt`; + +export async function submitToIndexNow(urls: string[]) { + try { + const payload = { + host: HOST, + key: KEY, + keyLocation: KEY_LOCATION, + urlList: urls, + }; + + console.log(`Submitting ${urls.length} URLs to IndexNow...`); + const response = await axios.post(INDEXNOW_ENDPOINT, payload, { + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (response.status === 200 || response.status === 202) { + console.log('✅ Successfully submitted URLs to IndexNow.'); + } else { + console.error(`⚠️ IndexNow submission returned status: ${response.status}`); + } + } catch (error) { + if (axios.isAxiosError(error)) { + console.error('❌ Error submitting to IndexNow:', error.message); + console.error('Response data:', error.response?.data); + } else { + console.error('❌ Unknown error submitting to IndexNow:', error); + } + } +} + +// Function to gather all indexable URLs +export function getAllIndexableUrls(): string[] { + const baseUrl = `https://${HOST}`; + + // Free tools + const freeTools = [ + 'url-qr-code', 'vcard-qr-code', 'text-qr-code', 'email-qr-code', 'sms-qr-code', + 'wifi-qr-code', 'crypto-qr-code', 'event-qr-code', 'facebook-qr-code', + 'instagram-qr-code', 'twitter-qr-code', 'youtube-qr-code', 'whatsapp-qr-code', + 'tiktok-qr-code', 'geolocation-qr-code', 'phone-qr-code', 'paypal-qr-code', + 'zoom-qr-code', 'teams-qr-code', + ].map(slug => `${baseUrl}/tools/${slug}`); + + // Blog posts + const blogPages = blogPostList.map(post => `${baseUrl}/blog/${post.slug}`); + + // Main pages + const mainPages = [ + baseUrl, + `${baseUrl}/qr-code-erstellen`, + `${baseUrl}/qr-code-tracking`, + `${baseUrl}/pricing`, + `${baseUrl}/bulk-qr-code-generator`, + `${baseUrl}/dynamic-qr-code-generator`, + `${baseUrl}/reprint-calculator`, + `${baseUrl}/faq`, + `${baseUrl}/blog`, + `${baseUrl}/signup`, + `${baseUrl}/login`, + ]; + + return [...mainPages, ...freeTools, ...blogPages]; +} + +// If run directly +if (require.main === module) { + const urls = getAllIndexableUrls(); + submitToIndexNow(urls); +}