Seobility und Ahrefs 100/100 score fixes

This commit is contained in:
Timo Knuth
2026-01-13 09:59:40 +01:00
parent ffe4cca5e5
commit 4fc1dcd7d8
9 changed files with 103 additions and 3682 deletions

View File

@@ -3,7 +3,9 @@ import type { Metadata } from 'next';
import LoginClientPage from './ClientPage';
export const metadata: Metadata = {
title: 'Login to QR Master | Access Your Dashboard',
title: {
absolute: 'Login to QR Master | Access Your Dashboard'
},
description: 'Sign in to QR Master to create, manage, and track your QR codes. Access your dashboard and view analytics.',
alternates: {
canonical: 'https://www.qrmaster.net/login',
@@ -17,6 +19,7 @@ export default function LoginPage() {
<div className="sr-only">
<h2>Secure Dashboard Access</h2>
<p>Log in to manage your dynamic QR codes, view scan analytics, and update destination URLs instantly.</p>
<a href="/">Back to Home</a>
</div>
<LoginClientPage />
</>

View File

@@ -3,7 +3,9 @@ import type { Metadata } from 'next';
import SignupClientPage from './ClientPage';
export const metadata: Metadata = {
title: 'Create Free Account | QR Master',
title: {
absolute: 'Create Free Account | QR Master'
},
description: 'Sign up for QR Master to create free QR codes. Start with tracking, customization, and bulk generation features.',
alternates: {
canonical: 'https://www.qrmaster.net/signup',
@@ -17,6 +19,7 @@ export default function SignupPage() {
<div className="sr-only">
<h2>Get Started Free</h2>
<p>Create your account today. No credit card required for the free tier. Start generating trackable QR codes in minutes.</p>
<a href="/">Back to Home</a>
</div>
<SignupClientPage />
</>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import type { Metadata } from 'next';
import Link from 'next/link';
import Image from 'next/image';
import { notFound } from 'next/navigation';
import { notFound, permanentRedirect } from 'next/navigation';
import SeoJsonLd from '@/components/SeoJsonLd';
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
import { blogPostingSchema, breadcrumbSchema, howToSchema } from '@/lib/schema';
@@ -30,7 +30,7 @@ interface BlogPostData {
const blogPosts: Record<string, BlogPostData> = {
'qr-code-analytics': {
slug: 'qr-code-analytics',
title: 'QR Code Analytics: Track, Measure & Optimize',
title: 'QR Code Analytics: Track & Measure',
excerpt: 'Master scan analytics, campaign tracking & dashboard insights to maximize QR ROI with dynamic codes.',
date: 'October 16, 2025',
datePublished: '2025-10-16T09:00:00Z',
@@ -146,14 +146,14 @@ const blogPosts: Record<string, BlogPostData> = {
},
'qr-code-tracking-guide-2025': {
slug: 'qr-code-tracking-guide-2025',
title: 'QR Code Tracking: Complete Guide 2025 (Free Tools & Best Practices)',
title: 'QR Code Tracking: Complete Guide 2025',
excerpt: 'Learn how to track QR code scans with real-time analytics. Compare free vs paid tracking tools, setup Google Analytics, and measure ROI. Complete guide 2025.',
date: 'October 18, 2025',
datePublished: '2025-10-18T09:00:00Z',
dateModified: '2025-10-18T09:00:00Z',
readTime: '12 Min',
category: 'Tracking & Analytics',
image: '/blog/1-hero.png',
image: '/blog/1-boy.webp',
imageAlt: 'QR code tracking and analytics visualization',
author: 'QR Master Team',
authorUrl: 'https://www.qrmaster.net/about',
@@ -672,22 +672,20 @@ app.get('/qr/:id', async (req, res) => {
},
'dynamic-vs-static-qr-codes': {
slug: 'dynamic-vs-static-qr-codes',
title: 'Dynamic vs Static QR Codes: Which Should You Use? Complete Comparison 2025',
excerpt: 'Understand the difference between static and dynamic QR codes. Learn when to use each type, pros/cons, and how dynamic QR codes save money. Expert guide 2025.',
title: 'Dynamic vs Static QR Codes: Complete Guide',
excerpt: 'Detailed comparison of static vs dynamic QR codes. Learn which type is right for your business, marketing campaign, or personal use.',
date: 'October 17, 2025',
datePublished: '2025-10-17T09:00:00Z',
dateModified: '2025-10-17T09:00:00Z',
readTime: '10 Min',
category: 'QR Code Basics',
image: '/blog/2-hero.png',
image: '/blog/2-body.webp',
imageAlt: 'Two QR codes side by side showing static and dynamic comparison',
author: 'QR Master Team',
authorUrl: 'https://www.qrmaster.net/about',
answer: 'Static QR codes encode data directly and cannot be edited after creation, while dynamic QR codes contain a short redirect URL that can be updated anytime. Dynamic QR codes also provide tracking analytics, making them ideal for marketing campaigns. Static QR codes work forever without subscriptions, perfect for permanent content like contact cards or fixed URLs.',
answer: 'Static QR codes are permanent and cannot be edited or tracked. Dynamic QR codes can be edited after printing and provide scan tracking. Use static QR codes for permanent links like personal vCards or Wi-Fi access. Use dynamic QR codes for marketing, business cards, and any application where you might need to change the destination URL or measure performance.',
content: `<div class="blog-content">
<p>Choosing between static and dynamic QR codes is one of the most important decisions when implementing a QR code strategy. According to <a href="https://en.wikipedia.org/wiki/QR_code" target="_blank" rel="noopener">Wikipedia</a>, QR codes were invented in 1994 by Masahiro Hara at Denso Wave for automotive part tracking. Today, QR codes have evolved into sophisticated marketing tools, with dynamic QR codes offering features unimaginable in their original static form.</p>
<p>This comprehensive guide explains the critical differences between static and dynamic QR codes, helping you choose the right type for your specific needs. Whether you're deploying QR codes on business cards, product packaging, or marketing campaigns, understanding these differences will save you time, money, and potential headaches.</p>
<p>The choice between static and dynamic QR codes is the most important decision when starting a QR code campaign. According to <a href="https://en.wikipedia.org/wiki/QR_code" target="_blank" rel="noopener">Wikipedia</a>, the QR code system was designed to be scanned quickly, but modern applications require more flexibility. In this guide, we'll compare both types to help you choose the right solution for your needs.</p>
<h2>What is a Static QR Code?</h2>
@@ -1189,7 +1187,7 @@ Will the destination URL ever change?
},
'bulk-qr-code-generator-excel': {
slug: 'bulk-qr-code-generator-excel',
title: 'How to Generate Bulk QR Codes from Excel: Complete Tutorial 2025',
title: 'Bulk QR Codes from Excel: 2025 Guide',
excerpt: 'Generate hundreds of QR codes from Excel or CSV files in minutes. Step-by-step guide with templates, best practices, and free tools. Perfect for products, events, inventory.',
date: 'October 16, 2025',
datePublished: '2025-10-16T10:00:00Z',
@@ -1846,7 +1844,7 @@ const response = await fetch('https://api.qrmaster.net/v1/bulk', {
'qr-code-restaurant-menu': {
slug: 'qr-code-restaurant-menu',
title: 'How to Create a QR Code for Restaurant Menu: Complete 2025 Guide',
title: 'Restaurant Menu QR Codes: 2025 Guide',
excerpt: 'Step-by-step guide to creating digital menu QR codes for your restaurant. Learn best practices for touchless menus, placement tips, and tracking.',
date: 'January 5, 2026',
datePublished: '2026-01-05T09:00:00Z',
@@ -2006,7 +2004,7 @@ const response = await fetch('https://api.qrmaster.net/v1/bulk', {
'vcard-qr-code-generator': {
slug: 'vcard-qr-code-generator',
title: 'Free vCard QR Code Generator: Digital Business Cards Made Easy',
title: 'Free vCard QR Generator: Digital Cards',
excerpt: 'Create professional vCard QR codes for digital business cards. Share contact info instantly with a scan—includes templates and best practices.',
date: 'January 5, 2026',
datePublished: '2026-01-05T10:00:00Z',
@@ -2165,7 +2163,7 @@ const response = await fetch('https://api.qrmaster.net/v1/bulk', {
'qr-code-small-business': {
slug: 'qr-code-small-business',
title: 'Best QR Code Generator for Small Business: 2025 Complete Guide',
title: 'Best QR Code Generator for Small Business 2025',
excerpt: 'Find the best QR code solution for your small business. Compare features, pricing, and use cases for marketing, payments, and operations.',
date: 'January 5, 2026',
datePublished: '2026-01-05T11:00:00Z',
@@ -2480,6 +2478,20 @@ export async function generateMetadata({ params }: { params: { slug: string } })
}
export default function BlogPostPage({ params }: { params: { slug: string } }) {
// Handle redirects for deprecated/legacy URLs
if (params.slug === 'vcard-qr-code-generator') {
permanentRedirect('/create');
}
if (params.slug === 'qr-code-restaurant-menu') {
permanentRedirect('/dynamic-qr-code-generator');
}
if (params.slug === 'bulk-qr-code-generator') {
permanentRedirect('/bulk-qr-code-generator');
}
if (params.slug === 'qr-code-small-business') {
permanentRedirect('/analytics');
}
const post = blogPosts[params.slug];
if (!post) {

View File

@@ -55,6 +55,7 @@ const blogPosts = [
readTime: '12 Min',
category: 'Restaurant',
image: '/blog/restaurant-qr-menu.png',
link: '/dynamic-qr-code-generator',
},
{
slug: 'vcard-qr-code-generator',
@@ -64,6 +65,7 @@ const blogPosts = [
readTime: '10 Min',
category: 'Business Cards',
image: '/blog/vcard-qr-code.png',
link: '/create',
},
{
slug: 'qr-code-small-business',
@@ -145,8 +147,8 @@ export default function BlogPage() {
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto">
{blogPosts.map((post) => (
<Link key={post.slug} href={`/blog/${post.slug}`}>
{blogPosts.map((post: any) => (
<Link key={post.slug} href={post.link || `/blog/${post.slug}`}>
<Card hover className="h-full overflow-hidden shadow-md hover:shadow-xl transition-all duration-300">
<div className="relative h-56 overflow-hidden">
<Image
@@ -168,7 +170,9 @@ export default function BlogPage() {
<p className="text-gray-600 mb-4 leading-relaxed">{post.excerpt}</p>
<div className="flex items-center justify-between pt-4 border-t border-gray-100">
<p className="text-sm text-gray-500">{post.date}</p>
<span className="text-primary-600 text-sm font-medium">Read more </span>
<span className="text-primary-600 text-sm font-medium">
{post.link ? 'Try Now →' : 'Read Article →'}
</span>
</div>
</CardContent>
</Card>

View File

@@ -2,6 +2,7 @@
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
@@ -198,6 +199,9 @@ export default function NewsletterClient() {
<p className="text-muted-foreground text-sm">
Sign in to access admin panel
</p>
<Link href="/" className="sr-only">
Back to Home
</Link>
</div>
<form onSubmit={handleLogin} className="space-y-4">

View File

@@ -3,7 +3,9 @@ import type { Metadata } from 'next';
import PricingClient from './PricingClient';
export const metadata: Metadata = {
title: 'Pricing Plans | QR Master',
title: {
absolute: 'Pricing Plans | QR Master'
},
description: 'Choose the perfect QR code plan for your needs. Free, Pro, and Business plans with dynamic QR codes, analytics, bulk generation, and custom branding.',
alternates: {
canonical: 'https://www.qrmaster.net/pricing',

View File

@@ -24,7 +24,9 @@ export async function generateMetadata(): Promise<Metadata> {
const description = 'Erstellen Sie QR Codes kostenlos in Sekunden. Dynamische QR-Codes mit Tracking, Branding und Massen-Erstellung. Für immer kostenlos.';
return {
title,
title: {
absolute: title
},
description,
keywords: [
'qr code erstellen',