SEO blog post
This commit is contained in:
@@ -8,6 +8,25 @@ type Props = {
|
||||
title?: string;
|
||||
};
|
||||
|
||||
const COMPETITOR_DOMAINS = [
|
||||
'bitly.com',
|
||||
'qrcode-tiger.com',
|
||||
'qr-code-generator.com',
|
||||
'flowcode.com',
|
||||
'beaconstac.com',
|
||||
'uniqode.com',
|
||||
'qrfy.com',
|
||||
];
|
||||
|
||||
function isCompetitor(url: string): boolean {
|
||||
try {
|
||||
const host = new URL(url).hostname.replace(/^www\./, '');
|
||||
return COMPETITOR_DOMAINS.some((d) => host === d || host.endsWith(`.${d}`));
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function SourcesList({ sources, title = "Sources & References" }: Props) {
|
||||
if (!sources?.length) return null;
|
||||
|
||||
@@ -21,7 +40,11 @@ export function SourcesList({ sources, title = "Sources & References" }: Props)
|
||||
<a
|
||||
href={source.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
rel={
|
||||
isCompetitor(source.url)
|
||||
? "noopener noreferrer nofollow"
|
||||
: "noopener noreferrer"
|
||||
}
|
||||
className="text-blue-600 hover:text-blue-800 hover:underline"
|
||||
>
|
||||
{source.name}
|
||||
|
||||
@@ -85,8 +85,8 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
|
||||
<li><Link href="/manage-qr-codes" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Manage QR Codes</Link></li>
|
||||
<li><Link href="/custom-qr-code-generator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Custom QR</Link></li>
|
||||
<li><Link href="/qr-code-for-marketing-campaigns" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Campaign QR Codes</Link></li>
|
||||
<li><Link href="/guide/tracking-analytics" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Tracking Guide</Link></li>
|
||||
<li><Link href="/guide/qr-code-best-practices" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Best Practices</Link></li>
|
||||
<li><Link href="/learn/tracking" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Tracking Guide</Link></li>
|
||||
<li><Link href="/learn/basics" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Best Practices</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -133,10 +133,10 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
|
||||
<li><a href="https://open-vsx.org/extension/qrmaster/qrmaster-generator" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>VS Code / Cursor Extension</a></li>
|
||||
<li><a href="https://github.com/marketplace/actions/qr-master-code-generator" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>GitHub Action Marketplace</a></li>
|
||||
<li><a href="https://www.npmjs.com/package/qrmaster-cli" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>npm Package (Node.js)</a></li>
|
||||
<li><a href="https://pypi.org/project/qrmaster/" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>PyPI Package (Python)</a></li>
|
||||
<li><a href="https://github.com/knuthtimo-lab/qrmaster-cli" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>GitHub Repository</a></li>
|
||||
<li><a href="https://chromewebstore.google.com" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Chrome Web Store Extension (Soon)</a></li>
|
||||
</ul>
|
||||
<li><a href="https://pypi.org/project/qrmaster/" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>PyPI Package (Python)</a></li>
|
||||
<li><a href="https://github.com/knuthtimo-lab/qrmaster-cli" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>GitHub Repository</a></li>
|
||||
<li><a href="https://chromewebstore.google.com" target="_blank" rel="noopener noreferrer" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Chrome Web Store Extension (Soon)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
8650
src/lib/blog-data.ts
8650
src/lib/blog-data.ts
File diff suppressed because it is too large
Load Diff
@@ -121,11 +121,12 @@ export function getAllIndexableUrls(): string[] {
|
||||
...publishedGuidePages.map(page => `${baseUrl}${page.canonicalPath}`),
|
||||
];
|
||||
|
||||
// Standalone guide pages (not part of the pSEO [slug] route)
|
||||
// Learn hub pillars (the /guide/* URLs these replaced are 301'd in next.config.mjs
|
||||
// and must never be submitted to IndexNow - see redirects() there)
|
||||
const guidePages = [
|
||||
`${baseUrl}/guide/bulk-qr-code-generation`,
|
||||
`${baseUrl}/guide/qr-code-best-practices`,
|
||||
`${baseUrl}/guide/tracking-analytics`,
|
||||
`${baseUrl}/learn/developer`,
|
||||
`${baseUrl}/learn/basics`,
|
||||
`${baseUrl}/learn/tracking`,
|
||||
];
|
||||
|
||||
// Industry landing pages
|
||||
|
||||
Reference in New Issue
Block a user