chore: normalize line endings
This commit is contained in:
parent
038c8dddbc
commit
e0871e2960
File diff suppressed because it is too large
Load Diff
|
|
@ -1,72 +1,72 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||||
import { organizationSchema, websiteSchema } from '@/lib/schema';
|
import { organizationSchema, websiteSchema } from '@/lib/schema';
|
||||||
import HomePageClient from '@/components/marketing/HomePageClient';
|
import HomePageClient from '@/components/marketing/HomePageClient';
|
||||||
|
|
||||||
function truncateAtWord(text: string, maxLength: number): string {
|
function truncateAtWord(text: string, maxLength: number): string {
|
||||||
if (text.length <= maxLength) return text;
|
if (text.length <= maxLength) return text;
|
||||||
const truncated = text.slice(0, maxLength);
|
const truncated = text.slice(0, maxLength);
|
||||||
const lastSpace = truncated.lastIndexOf(' ');
|
const lastSpace = truncated.lastIndexOf(' ');
|
||||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateMetadata(): Promise<Metadata> {
|
export async function generateMetadata(): Promise<Metadata> {
|
||||||
const title = truncateAtWord('QR Master: Dynamic QR Generator', 60);
|
const title = truncateAtWord('QR Master: Dynamic QR Generator', 60);
|
||||||
const description = truncateAtWord(
|
const description = truncateAtWord(
|
||||||
'Dynamic QR, branding, bulk generation & analytics for all campaigns.',
|
'Dynamic QR, branding, bulk generation & analytics for all campaigns.',
|
||||||
160
|
160
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: 'https://www.qrmaster.net/',
|
canonical: 'https://www.qrmaster.net/',
|
||||||
languages: {
|
languages: {
|
||||||
'x-default': 'https://www.qrmaster.net/',
|
'x-default': 'https://www.qrmaster.net/',
|
||||||
en: 'https://www.qrmaster.net/',
|
en: 'https://www.qrmaster.net/',
|
||||||
de: 'https://www.qrmaster.net/qr-code-erstellen',
|
de: 'https://www.qrmaster.net/qr-code-erstellen',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
url: 'https://www.qrmaster.net/',
|
url: 'https://www.qrmaster.net/',
|
||||||
type: 'website',
|
type: 'website',
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SeoJsonLd data={[organizationSchema(), websiteSchema()]} />
|
<SeoJsonLd data={[organizationSchema(), websiteSchema()]} />
|
||||||
|
|
||||||
{/* Server-rendered SEO content for crawlers */}
|
{/* Server-rendered SEO content for crawlers */}
|
||||||
<div className="sr-only" aria-hidden="false">
|
<div className="sr-only" aria-hidden="false">
|
||||||
<h1>QR Master: Free Dynamic QR Code Generator with Tracking & Analytics</h1>
|
<h1>QR Master: Free Dynamic QR Code Generator with Tracking & Analytics</h1>
|
||||||
<p>
|
<p>
|
||||||
Create professional QR codes for your business with QR Master. Our dynamic QR code generator
|
Create professional QR codes for your business with QR Master. Our dynamic QR code generator
|
||||||
lets you create trackable QR codes, edit destinations anytime, and view detailed analytics.
|
lets you create trackable QR codes, edit destinations anytime, and view detailed analytics.
|
||||||
Perfect for restaurants, retail, events, and marketing campaigns.
|
Perfect for restaurants, retail, events, and marketing campaigns.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Features include: Dynamic QR codes with real-time tracking, bulk QR code generation from Excel/CSV,
|
Features include: Dynamic QR codes with real-time tracking, bulk QR code generation from Excel/CSV,
|
||||||
custom branding with colors and logos, advanced scan analytics showing device types and locations,
|
custom branding with colors and logos, advanced scan analytics showing device types and locations,
|
||||||
vCard QR codes for digital business cards, and restaurant menu QR codes.
|
vCard QR codes for digital business cards, and restaurant menu QR codes.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Start free with 3 dynamic QR codes and unlimited static codes. Upgrade to Pro for 50 codes
|
Start free with 3 dynamic QR codes and unlimited static codes. Upgrade to Pro for 50 codes
|
||||||
with advanced analytics, or Business for 500 codes with bulk creation and priority support.
|
with advanced analytics, or Business for 500 codes with bulk creation and priority support.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HomePageClient />
|
<HomePageClient />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,44 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import AdBanner from '@/components/ads/AdBanner';
|
import AdBanner from '@/components/ads/AdBanner';
|
||||||
|
|
||||||
export default function ToolsLayout({
|
export default function ToolsLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col min-h-screen">
|
<div className="flex flex-col min-h-screen">
|
||||||
<div className="flex-grow relative">
|
<div className="flex-grow relative">
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
{/* Desktop Sidebar Ad - High Resolution Only */}
|
{/* Desktop Sidebar Ad - High Resolution Only */}
|
||||||
{/* Positioned absolute to the right, only visible on very wide screens (2xl) */}
|
{/* Positioned absolute to the right, only visible on very wide screens (2xl) */}
|
||||||
<div className="hidden 2xl:block absolute right-4 top-32 w-[160px] z-10">
|
<div className="hidden 2xl:block absolute right-4 top-32 w-[160px] z-10">
|
||||||
<div className="sticky top-24">
|
<div className="sticky top-24">
|
||||||
<div className="text-center text-[10px] text-slate-300 mb-1">AD</div>
|
<div className="text-center text-[10px] text-slate-300 mb-1">AD</div>
|
||||||
<AdBanner
|
<AdBanner
|
||||||
dataAdSlot="sidebar-slot-id"
|
dataAdSlot="sidebar-slot-id"
|
||||||
dataAdFormat="vertical"
|
dataAdFormat="vertical"
|
||||||
className="min-h-[600px] w-[160px]"
|
className="min-h-[600px] w-[160px]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer Ad Placement - Appears on ALL tool pages */}
|
{/* Footer Ad Placement - Appears on ALL tool pages */}
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl pb-8">
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl pb-8">
|
||||||
<div className="mx-auto max-w-4xl text-center text-xs text-slate-400 mb-2">
|
<div className="mx-auto max-w-4xl text-center text-xs text-slate-400 mb-2">
|
||||||
Sponsored
|
Sponsored
|
||||||
</div>
|
</div>
|
||||||
<AdBanner
|
<AdBanner
|
||||||
dataAdSlot="1234567890" // Placeholder
|
dataAdSlot="1234567890" // Placeholder
|
||||||
dataAdFormat="auto"
|
dataAdFormat="auto"
|
||||||
fullWidthResponsive={true}
|
fullWidthResponsive={true}
|
||||||
className="bg-slate-50 rounded-xl p-4 border border-slate-100 min-h-[100px]"
|
className="bg-slate-50 rounded-xl p-4 border border-slate-100 min-h-[100px]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,248 +1,248 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Footer } from '@/components/ui/Footer';
|
import { Footer } from '@/components/ui/Footer';
|
||||||
import de from '@/i18n/de.json';
|
import de from '@/i18n/de.json';
|
||||||
import { ChevronDown, Wifi, Contact, MessageCircle, QrCode, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users } from 'lucide-react';
|
import { ChevronDown, Wifi, Contact, MessageCircle, QrCode, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
|
|
||||||
export default function MarketingLayout({
|
export default function MarketingLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
const [scrolled, setScrolled] = useState(false);
|
const [scrolled, setScrolled] = useState(false);
|
||||||
const [toolsOpen, setToolsOpen] = useState(false);
|
const [toolsOpen, setToolsOpen] = useState(false);
|
||||||
const [mobileToolsOpen, setMobileToolsOpen] = useState(false);
|
const [mobileToolsOpen, setMobileToolsOpen] = useState(false);
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
setScrolled(window.scrollY > 20);
|
setScrolled(window.scrollY > 20);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check immediately on mount
|
// Check immediately on mount
|
||||||
handleScroll();
|
handleScroll();
|
||||||
|
|
||||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
return () => window.removeEventListener('scroll', handleScroll);
|
return () => window.removeEventListener('scroll', handleScroll);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Close simple menus when path changes
|
// Close simple menus when path changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMobileMenuOpen(false);
|
setMobileMenuOpen(false);
|
||||||
setToolsOpen(false);
|
setToolsOpen(false);
|
||||||
}, [pathname]);
|
}, [pathname]);
|
||||||
|
|
||||||
// Always German for this layout
|
// Always German for this layout
|
||||||
const t = de;
|
const t = de;
|
||||||
|
|
||||||
const tools = [
|
const tools = [
|
||||||
{ name: 'URL / Link', description: 'Link to any website', href: '/tools/url-qr-code', icon: Link2, color: 'text-blue-500', bgColor: 'bg-blue-50' },
|
{ name: 'URL / Link', description: 'Link to any website', href: '/tools/url-qr-code', icon: Link2, color: 'text-blue-500', bgColor: 'bg-blue-50' },
|
||||||
{ name: 'Text', description: 'Plain text message', href: '/tools/text-qr-code', icon: Type, color: 'text-slate-500', bgColor: 'bg-slate-50' },
|
{ name: 'Text', description: 'Plain text message', href: '/tools/text-qr-code', icon: Type, color: 'text-slate-500', bgColor: 'bg-slate-50' },
|
||||||
{ name: 'WiFi', description: 'Share WiFi credentials', href: '/tools/wifi-qr-code', icon: Wifi, color: 'text-indigo-500', bgColor: 'bg-indigo-50' },
|
{ name: 'WiFi', description: 'Share WiFi credentials', href: '/tools/wifi-qr-code', icon: Wifi, color: 'text-indigo-500', bgColor: 'bg-indigo-50' },
|
||||||
{ name: 'VCard', description: 'Digital business card', href: '/tools/vcard-qr-code', icon: Contact, color: 'text-pink-500', bgColor: 'bg-pink-50' },
|
{ name: 'VCard', description: 'Digital business card', href: '/tools/vcard-qr-code', icon: Contact, color: 'text-pink-500', bgColor: 'bg-pink-50' },
|
||||||
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
|
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
|
||||||
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
||||||
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
||||||
{ name: 'Phone', description: 'Start a call', href: '/tools/phone-qr-code', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
{ name: 'Phone', description: 'Start a call', href: '/tools/phone-qr-code', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
||||||
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
|
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
|
||||||
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
||||||
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
|
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
|
||||||
{ name: 'Instagram', description: 'Instagram profile', href: '/tools/instagram-qr-code', icon: Instagram, color: 'text-pink-600', bgColor: 'bg-pink-50' },
|
{ name: 'Instagram', description: 'Instagram profile', href: '/tools/instagram-qr-code', icon: Instagram, color: 'text-pink-600', bgColor: 'bg-pink-50' },
|
||||||
{ name: 'Twitter / X', description: 'Twitter profile', href: '/tools/twitter-qr-code', icon: Twitter, color: 'text-sky-500', bgColor: 'bg-sky-50' },
|
{ name: 'Twitter / X', description: 'Twitter profile', href: '/tools/twitter-qr-code', icon: Twitter, color: 'text-sky-500', bgColor: 'bg-sky-50' },
|
||||||
{ name: 'YouTube', description: 'YouTube video/channel', href: '/tools/youtube-qr-code', icon: Youtube, color: 'text-red-600', bgColor: 'bg-red-50' },
|
{ name: 'YouTube', description: 'YouTube video/channel', href: '/tools/youtube-qr-code', icon: Youtube, color: 'text-red-600', bgColor: 'bg-red-50' },
|
||||||
{ name: 'TikTok', description: 'TikTok profile', href: '/tools/tiktok-qr-code', icon: Music, color: 'text-slate-800', bgColor: 'bg-slate-100' },
|
{ name: 'TikTok', description: 'TikTok profile', href: '/tools/tiktok-qr-code', icon: Music, color: 'text-slate-800', bgColor: 'bg-slate-100' },
|
||||||
{ name: 'Crypto', description: 'Share wallet address', href: '/tools/crypto-qr-code', icon: Bitcoin, color: 'text-orange-500', bgColor: 'bg-orange-50' },
|
{ name: 'Crypto', description: 'Share wallet address', href: '/tools/crypto-qr-code', icon: Bitcoin, color: 'text-orange-500', bgColor: 'bg-orange-50' },
|
||||||
{ name: 'PayPal', description: 'Receive payments', href: '/tools/paypal-qr-code', icon: CreditCard, color: 'text-blue-700', bgColor: 'bg-blue-50' },
|
{ name: 'PayPal', description: 'Receive payments', href: '/tools/paypal-qr-code', icon: CreditCard, color: 'text-blue-700', bgColor: 'bg-blue-50' },
|
||||||
{ name: 'Zoom', description: 'Join Zoom meeting', href: '/tools/zoom-qr-code', icon: Video, color: 'text-sky-500', bgColor: 'bg-sky-50' },
|
{ name: 'Zoom', description: 'Join Zoom meeting', href: '/tools/zoom-qr-code', icon: Video, color: 'text-sky-500', bgColor: 'bg-sky-50' },
|
||||||
{ name: 'Teams', description: 'Join Teams meeting', href: '/tools/teams-qr-code', icon: Users, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
{ name: 'Teams', description: 'Join Teams meeting', href: '/tools/teams-qr-code', icon: Users, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-white">
|
<div className="min-h-screen bg-white">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<header
|
<header
|
||||||
className="fixed top-0 left-0 right-0 z-50 bg-white/80 backdrop-blur-md border-b border-slate-200 shadow-sm"
|
className="fixed top-0 left-0 right-0 z-50 bg-white/80 backdrop-blur-md border-b border-slate-200 shadow-sm"
|
||||||
>
|
>
|
||||||
<nav className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl h-20 flex items-center justify-between">
|
<nav className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl h-20 flex items-center justify-between">
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link href="/" className="flex items-center space-x-2.5 group">
|
<Link href="/" className="flex items-center space-x-2.5 group">
|
||||||
<div className="relative w-9 h-9 flex items-center justify-center bg-indigo-600 rounded-lg shadow-indigo-200 shadow-lg group-hover:scale-105 transition-transform duration-200">
|
<div className="relative w-9 h-9 flex items-center justify-center bg-indigo-600 rounded-lg shadow-indigo-200 shadow-lg group-hover:scale-105 transition-transform duration-200">
|
||||||
<QrCode className="w-5 h-5 text-white" />
|
<QrCode className="w-5 h-5 text-white" />
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xl font-bold text-slate-900 tracking-tight group-hover:text-indigo-600 transition-colors">QR Master</span>
|
<span className="text-xl font-bold text-slate-900 tracking-tight group-hover:text-indigo-600 transition-colors">QR Master</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
||||||
{/* Desktop Navigation */}
|
{/* Desktop Navigation */}
|
||||||
<div className="hidden md:flex items-center space-x-1">
|
<div className="hidden md:flex items-center space-x-1">
|
||||||
|
|
||||||
{/* Tools Dropdown */}
|
{/* Tools Dropdown */}
|
||||||
<div
|
<div
|
||||||
className="relative group px-3 py-2"
|
className="relative group px-3 py-2"
|
||||||
onMouseEnter={() => setToolsOpen(true)}
|
onMouseEnter={() => setToolsOpen(true)}
|
||||||
onMouseLeave={() => setToolsOpen(false)}
|
onMouseLeave={() => setToolsOpen(false)}
|
||||||
>
|
>
|
||||||
<button className="flex items-center space-x-1 text-sm font-medium text-slate-600 group-hover:text-slate-900 transition-colors">
|
<button className="flex items-center space-x-1 text-sm font-medium text-slate-600 group-hover:text-slate-900 transition-colors">
|
||||||
<span>{t.nav.tools}</span>
|
<span>{t.nav.tools}</span>
|
||||||
<ChevronDown className={cn("w-4 h-4 transition-transform duration-200", toolsOpen && "rotate-180")} />
|
<ChevronDown className={cn("w-4 h-4 transition-transform duration-200", toolsOpen && "rotate-180")} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{toolsOpen && (
|
{toolsOpen && (
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 10 }}
|
initial={{ opacity: 0, y: 10 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
exit={{ opacity: 0, y: 10 }}
|
exit={{ opacity: 0, y: 10 }}
|
||||||
transition={{ duration: 0.15 }}
|
transition={{ duration: 0.15 }}
|
||||||
className="absolute left-1/2 -translate-x-1/2 top-full mt-2 w-[750px] bg-white rounded-2xl shadow-lg border border-slate-100 p-4 overflow-hidden"
|
className="absolute left-1/2 -translate-x-1/2 top-full mt-2 w-[750px] bg-white rounded-2xl shadow-lg border border-slate-100 p-4 overflow-hidden"
|
||||||
>
|
>
|
||||||
<div className="grid grid-cols-3 gap-1">
|
<div className="grid grid-cols-3 gap-1">
|
||||||
{tools.map((tool) => (
|
{tools.map((tool) => (
|
||||||
<Link
|
<Link
|
||||||
key={tool.name}
|
key={tool.name}
|
||||||
href={tool.href}
|
href={tool.href}
|
||||||
className="flex items-center space-x-3 p-2.5 rounded-xl transition-colors hover:bg-slate-50"
|
className="flex items-center space-x-3 p-2.5 rounded-xl transition-colors hover:bg-slate-50"
|
||||||
>
|
>
|
||||||
<div className={cn("p-2 rounded-lg shrink-0", tool.bgColor, tool.color)}>
|
<div className={cn("p-2 rounded-lg shrink-0", tool.bgColor, tool.color)}>
|
||||||
<tool.icon className="w-4 h-4" />
|
<tool.icon className="w-4 h-4" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="text-sm font-semibold text-slate-900">{tool.name}</div>
|
<div className="text-sm font-semibold text-slate-900">{tool.name}</div>
|
||||||
<p className="text-xs text-slate-500 leading-snug">{tool.description}</p>
|
<p className="text-xs text-slate-500 leading-snug">{tool.description}</p>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 pt-3 border-t border-slate-100 -mx-4 -mb-4 px-4 py-3 text-center bg-slate-50/50">
|
<div className="mt-3 pt-3 border-t border-slate-100 -mx-4 -mb-4 px-4 py-3 text-center bg-slate-50/50">
|
||||||
<p className="text-xs text-slate-500 font-medium">{t.nav.all_free}</p>
|
<p className="text-xs text-slate-500 font-medium">{t.nav.all_free}</p>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link href="/#features" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
<Link href="/#features" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
||||||
{t.nav.features}
|
{t.nav.features}
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/#pricing" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
<Link href="/#pricing" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
||||||
{t.nav.pricing}
|
{t.nav.pricing}
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/blog" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
<Link href="/blog" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
||||||
{t.nav.blog}
|
{t.nav.blog}
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/#faq" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
<Link href="/#faq" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
||||||
{t.nav.faq}
|
{t.nav.faq}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="hidden md:flex items-center space-x-4">
|
<div className="hidden md:flex items-center space-x-4">
|
||||||
<Link href="/login" className="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
<Link href="/login" className="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
|
||||||
{t.nav.login}
|
{t.nav.login}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link href="/signup">
|
<Link href="/signup">
|
||||||
<Button className={cn(
|
<Button className={cn(
|
||||||
"font-semibold shadow-lg shadow-indigo-500/20 transition-all hover:scale-105",
|
"font-semibold shadow-lg shadow-indigo-500/20 transition-all hover:scale-105",
|
||||||
scrolled ? "bg-blue-600 text-white hover:bg-blue-700" : "bg-blue-600 text-white hover:bg-blue-700"
|
scrolled ? "bg-blue-600 text-white hover:bg-blue-700" : "bg-blue-600 text-white hover:bg-blue-700"
|
||||||
)}>
|
)}>
|
||||||
{t.nav.cta || "Get Started Free"}
|
{t.nav.cta || "Get Started Free"}
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Menu Button - Always dark */}
|
{/* Mobile Menu Button - Always dark */}
|
||||||
<button
|
<button
|
||||||
className="md:hidden p-2 text-slate-900"
|
className="md:hidden p-2 text-slate-900"
|
||||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||||
aria-label="Toggle menu"
|
aria-label="Toggle menu"
|
||||||
>
|
>
|
||||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
{mobileMenuOpen ? (
|
{mobileMenuOpen ? (
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
) : (
|
) : (
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
||||||
)}
|
)}
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* Mobile Menu */}
|
{/* Mobile Menu */}
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{mobileMenuOpen && (
|
{mobileMenuOpen && (
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, height: 0 }}
|
initial={{ opacity: 0, height: 0 }}
|
||||||
animate={{ opacity: 1, height: 'auto' }}
|
animate={{ opacity: 1, height: 'auto' }}
|
||||||
exit={{ opacity: 0, height: 0 }}
|
exit={{ opacity: 0, height: 0 }}
|
||||||
className="md:hidden bg-white border-b border-slate-100 overflow-hidden"
|
className="md:hidden bg-white border-b border-slate-100 overflow-hidden"
|
||||||
>
|
>
|
||||||
<div className="container mx-auto px-4 py-6 space-y-2">
|
<div className="container mx-auto px-4 py-6 space-y-2">
|
||||||
{/* Free Tools Accordion */}
|
{/* Free Tools Accordion */}
|
||||||
<button
|
<button
|
||||||
onClick={() => setMobileToolsOpen(!mobileToolsOpen)}
|
onClick={() => setMobileToolsOpen(!mobileToolsOpen)}
|
||||||
className="flex items-center justify-between w-full px-4 py-3 rounded-xl hover:bg-slate-50 text-slate-700 font-semibold"
|
className="flex items-center justify-between w-full px-4 py-3 rounded-xl hover:bg-slate-50 text-slate-700 font-semibold"
|
||||||
>
|
>
|
||||||
<span>{t.nav.tools}</span>
|
<span>{t.nav.tools}</span>
|
||||||
<ChevronDown className={cn("w-5 h-5 transition-transform", mobileToolsOpen && "rotate-180")} />
|
<ChevronDown className={cn("w-5 h-5 transition-transform", mobileToolsOpen && "rotate-180")} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{mobileToolsOpen && (
|
{mobileToolsOpen && (
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, height: 0 }}
|
initial={{ opacity: 0, height: 0 }}
|
||||||
animate={{ opacity: 1, height: 'auto' }}
|
animate={{ opacity: 1, height: 'auto' }}
|
||||||
exit={{ opacity: 0, height: 0 }}
|
exit={{ opacity: 0, height: 0 }}
|
||||||
className="overflow-hidden"
|
className="overflow-hidden"
|
||||||
>
|
>
|
||||||
<div className="max-h-[50vh] overflow-y-auto pl-4 space-y-1 border-l-2 border-slate-100 ml-4">
|
<div className="max-h-[50vh] overflow-y-auto pl-4 space-y-1 border-l-2 border-slate-100 ml-4">
|
||||||
{tools.map((tool) => (
|
{tools.map((tool) => (
|
||||||
<Link
|
<Link
|
||||||
key={tool.name}
|
key={tool.name}
|
||||||
href={tool.href}
|
href={tool.href}
|
||||||
className="flex items-center gap-3 px-4 py-2.5 rounded-lg hover:bg-slate-50 text-slate-600 text-sm"
|
className="flex items-center gap-3 px-4 py-2.5 rounded-lg hover:bg-slate-50 text-slate-600 text-sm"
|
||||||
onClick={() => { setMobileMenuOpen(false); setMobileToolsOpen(false); }}
|
onClick={() => { setMobileMenuOpen(false); setMobileToolsOpen(false); }}
|
||||||
>
|
>
|
||||||
<tool.icon className={cn("w-4 h-4", tool.color)} />
|
<tool.icon className={cn("w-4 h-4", tool.color)} />
|
||||||
{tool.name}
|
{tool.name}
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<div className="h-px bg-slate-100 my-2"></div>
|
<div className="h-px bg-slate-100 my-2"></div>
|
||||||
|
|
||||||
<Link href="/#features" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.features}</Link>
|
<Link href="/#features" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.features}</Link>
|
||||||
<Link href="/#pricing" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.pricing}</Link>
|
<Link href="/#pricing" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.pricing}</Link>
|
||||||
<Link href="/blog" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.blog}</Link>
|
<Link href="/blog" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.blog}</Link>
|
||||||
<Link href="/#faq" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.faq}</Link>
|
<Link href="/#faq" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.faq}</Link>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4 pt-4">
|
<div className="grid grid-cols-2 gap-4 pt-4">
|
||||||
<Link href="/login" onClick={() => setMobileMenuOpen(false)}>
|
<Link href="/login" onClick={() => setMobileMenuOpen(false)}>
|
||||||
<Button variant="outline" className="w-full justify-center">{t.nav.login}</Button>
|
<Button variant="outline" className="w-full justify-center">{t.nav.login}</Button>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/signup" onClick={() => setMobileMenuOpen(false)}>
|
<Link href="/signup" onClick={() => setMobileMenuOpen(false)}>
|
||||||
<Button className="w-full justify-center bg-indigo-600 hover:bg-indigo-700">{t.nav.cta}</Button>
|
<Button className="w-full justify-center bg-indigo-600 hover:bg-indigo-700">{t.nav.cta}</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<main className="pt-20">{children}</main>
|
<main className="pt-20">{children}</main>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<Footer t={t} />
|
<Footer t={t} />
|
||||||
</div >
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,108 +1,108 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||||
import { organizationSchema, websiteSchema } from '@/lib/schema';
|
import { organizationSchema, websiteSchema } from '@/lib/schema';
|
||||||
import { Hero } from '@/components/marketing/Hero';
|
import { Hero } from '@/components/marketing/Hero';
|
||||||
import { InstantGenerator } from '@/components/marketing/InstantGenerator';
|
import { InstantGenerator } from '@/components/marketing/InstantGenerator';
|
||||||
import { StaticVsDynamic } from '@/components/marketing/StaticVsDynamic';
|
import { StaticVsDynamic } from '@/components/marketing/StaticVsDynamic';
|
||||||
import { Features } from '@/components/marketing/Features';
|
import { Features } from '@/components/marketing/Features';
|
||||||
import { Pricing } from '@/components/marketing/Pricing';
|
import { Pricing } from '@/components/marketing/Pricing';
|
||||||
import { FAQ } from '@/components/marketing/FAQ';
|
import { FAQ } from '@/components/marketing/FAQ';
|
||||||
import { ScrollToTop } from '@/components/ui/ScrollToTop';
|
import { ScrollToTop } from '@/components/ui/ScrollToTop';
|
||||||
import de from '@/i18n/de.json';
|
import de from '@/i18n/de.json';
|
||||||
|
|
||||||
function truncateAtWord(text: string, maxLength: number): string {
|
function truncateAtWord(text: string, maxLength: number): string {
|
||||||
if (text.length <= maxLength) return text;
|
if (text.length <= maxLength) return text;
|
||||||
const truncated = text.slice(0, maxLength);
|
const truncated = text.slice(0, maxLength);
|
||||||
const lastSpace = truncated.lastIndexOf(' ');
|
const lastSpace = truncated.lastIndexOf(' ');
|
||||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateMetadata(): Promise<Metadata> {
|
export async function generateMetadata(): Promise<Metadata> {
|
||||||
const title = truncateAtWord('QR Code Erstellen – Kostenlos & Sofort | QR Master', 60);
|
const title = truncateAtWord('QR Code Erstellen – Kostenlos & Sofort | QR Master', 60);
|
||||||
const description = truncateAtWord(
|
const description = truncateAtWord(
|
||||||
'Erstellen Sie QR Codes kostenlos in Sekunden. Statische und dynamische QR-Codes mit Tracking, individuellem Branding und Massen-Erstellung. Für immer kostenlos.',
|
'Erstellen Sie QR Codes kostenlos in Sekunden. Statische und dynamische QR-Codes mit Tracking, individuellem Branding und Massen-Erstellung. Für immer kostenlos.',
|
||||||
160
|
160
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
keywords: [
|
keywords: [
|
||||||
'qr code erstellen',
|
'qr code erstellen',
|
||||||
'qr code generator',
|
'qr code generator',
|
||||||
'qr code kostenlos',
|
'qr code kostenlos',
|
||||||
'qr-code-generatoren',
|
'qr-code-generatoren',
|
||||||
'qr codes erstellen',
|
'qr codes erstellen',
|
||||||
'qr code erstellen kostenlos',
|
'qr code erstellen kostenlos',
|
||||||
'dynamischer qr code',
|
'dynamischer qr code',
|
||||||
'qr code mit logo'
|
'qr code mit logo'
|
||||||
],
|
],
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: 'https://www.qrmaster.net/qr-code-erstellen',
|
canonical: 'https://www.qrmaster.net/qr-code-erstellen',
|
||||||
languages: {
|
languages: {
|
||||||
'x-default': 'https://www.qrmaster.net/',
|
'x-default': 'https://www.qrmaster.net/',
|
||||||
en: 'https://www.qrmaster.net/',
|
en: 'https://www.qrmaster.net/',
|
||||||
de: 'https://www.qrmaster.net/qr-code-erstellen',
|
de: 'https://www.qrmaster.net/qr-code-erstellen',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: 'QR Code Erstellen – Kostenlos & Sofort | QR Master',
|
title: 'QR Code Erstellen – Kostenlos & Sofort | QR Master',
|
||||||
description: 'Erstellen Sie QR Codes kostenlos in Sekunden. Mit Tracking, Branding und Massen-Erstellung.',
|
description: 'Erstellen Sie QR Codes kostenlos in Sekunden. Mit Tracking, Branding und Massen-Erstellung.',
|
||||||
url: 'https://www.qrmaster.net/qr-code-erstellen',
|
url: 'https://www.qrmaster.net/qr-code-erstellen',
|
||||||
type: 'website',
|
type: 'website',
|
||||||
locale: 'de_DE',
|
locale: 'de_DE',
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
title: 'QR Code Erstellen – Kostenlos | QR Master',
|
title: 'QR Code Erstellen – Kostenlos | QR Master',
|
||||||
description: 'QR Codes erstellen in Sekunden. Kostenlos, mit Tracking und individuellem Branding.',
|
description: 'QR Codes erstellen in Sekunden. Kostenlos, mit Tracking und individuellem Branding.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function QRCodeErstellenPage() {
|
export default function QRCodeErstellenPage() {
|
||||||
// Use German translations
|
// Use German translations
|
||||||
const t = de;
|
const t = de;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SeoJsonLd data={[organizationSchema(), websiteSchema()]} />
|
<SeoJsonLd data={[organizationSchema(), websiteSchema()]} />
|
||||||
|
|
||||||
{/* Server-rendered SEO content for crawlers - GERMAN */}
|
{/* Server-rendered SEO content for crawlers - GERMAN */}
|
||||||
<div className="sr-only" aria-hidden="false">
|
<div className="sr-only" aria-hidden="false">
|
||||||
<h1>QR Code Erstellen – Kostenloser QR Code Generator mit Tracking & Statistiken</h1>
|
<h1>QR Code Erstellen – Kostenloser QR Code Generator mit Tracking & Statistiken</h1>
|
||||||
<p>
|
<p>
|
||||||
Erstellen Sie professionelle QR Codes für Ihr Unternehmen mit QR Master. Unser dynamischer QR Code Generator
|
Erstellen Sie professionelle QR Codes für Ihr Unternehmen mit QR Master. Unser dynamischer QR Code Generator
|
||||||
ermöglicht es Ihnen, trackbare QR Codes zu erstellen, Ziel-URLs jederzeit zu ändern und detaillierte Statistiken einzusehen.
|
ermöglicht es Ihnen, trackbare QR Codes zu erstellen, Ziel-URLs jederzeit zu ändern und detaillierte Statistiken einzusehen.
|
||||||
Perfekt für Restaurants, Einzelhandel, Events und Marketing-Kampagnen.
|
Perfekt für Restaurants, Einzelhandel, Events und Marketing-Kampagnen.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Funktionen: Dynamische QR Codes mit Echtzeit-Tracking, Massen-QR-Code-Erstellung aus Excel/CSV,
|
Funktionen: Dynamische QR Codes mit Echtzeit-Tracking, Massen-QR-Code-Erstellung aus Excel/CSV,
|
||||||
individuelles Branding mit Farben und Logos, erweiterte Scan-Statistiken mit Gerätetypen und Standorten,
|
individuelles Branding mit Farben und Logos, erweiterte Scan-Statistiken mit Gerätetypen und Standorten,
|
||||||
vCard QR Codes für digitale Visitenkarten und QR Codes für Restaurant-Speisekarten.
|
vCard QR Codes für digitale Visitenkarten und QR Codes für Restaurant-Speisekarten.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Starten Sie kostenlos mit 3 dynamischen QR Codes und unbegrenzten statischen Codes. Upgrade auf Pro für 50 Codes
|
Starten Sie kostenlos mit 3 dynamischen QR Codes und unbegrenzten statischen Codes. Upgrade auf Pro für 50 Codes
|
||||||
mit erweiterten Statistiken, oder Business für 500 Codes mit Massen-Erstellung und Prioritäts-Support.
|
mit erweiterten Statistiken, oder Business für 500 Codes mit Massen-Erstellung und Prioritäts-Support.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Hero t={t} />
|
<Hero t={t} />
|
||||||
|
|
||||||
{/* Main Interaction: Generator */}
|
{/* Main Interaction: Generator */}
|
||||||
<InstantGenerator t={t} />
|
<InstantGenerator t={t} />
|
||||||
|
|
||||||
<StaticVsDynamic t={t} />
|
<StaticVsDynamic t={t} />
|
||||||
<Features t={t} />
|
<Features t={t} />
|
||||||
|
|
||||||
{/* Pricing Section */}
|
{/* Pricing Section */}
|
||||||
<Pricing t={t} />
|
<Pricing t={t} />
|
||||||
|
|
||||||
{/* FAQ Section */}
|
{/* FAQ Section */}
|
||||||
<FAQ t={t} />
|
<FAQ t={t} />
|
||||||
|
|
||||||
{/* Scroll to Top Button */}
|
{/* Scroll to Top Button */}
|
||||||
<ScrollToTop />
|
<ScrollToTop />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,136 +1,136 @@
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import '@/styles/globals.css';
|
import '@/styles/globals.css';
|
||||||
import { ToastContainer } from '@/components/ui/Toast';
|
import { ToastContainer } from '@/components/ui/Toast';
|
||||||
import AuthProvider from '@/components/SessionProvider';
|
import AuthProvider from '@/components/SessionProvider';
|
||||||
import { PostHogProvider } from '@/components/PostHogProvider';
|
import { PostHogProvider } from '@/components/PostHogProvider';
|
||||||
import CookieBanner from '@/components/CookieBanner';
|
import CookieBanner from '@/components/CookieBanner';
|
||||||
|
|
||||||
const isIndexable = process.env.NEXT_PUBLIC_INDEXABLE === 'true';
|
const isIndexable = process.env.NEXT_PUBLIC_INDEXABLE === 'true';
|
||||||
|
|
||||||
// Organization Schema for all pages
|
// Organization Schema for all pages
|
||||||
const organizationSchema = {
|
const organizationSchema = {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'Organization',
|
'@type': 'Organization',
|
||||||
'@id': 'https://www.qrmaster.net/#organization',
|
'@id': 'https://www.qrmaster.net/#organization',
|
||||||
name: 'QR Master',
|
name: 'QR Master',
|
||||||
alternateName: 'QRMaster',
|
alternateName: 'QRMaster',
|
||||||
url: 'https://www.qrmaster.net',
|
url: 'https://www.qrmaster.net',
|
||||||
logo: {
|
logo: {
|
||||||
'@type': 'ImageObject',
|
'@type': 'ImageObject',
|
||||||
url: 'https://www.qrmaster.net/static/og-image.png',
|
url: 'https://www.qrmaster.net/static/og-image.png',
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
},
|
},
|
||||||
image: 'https://www.qrmaster.net/static/og-image.png',
|
image: 'https://www.qrmaster.net/static/og-image.png',
|
||||||
sameAs: ['https://twitter.com/qrmaster'],
|
sameAs: ['https://twitter.com/qrmaster'],
|
||||||
contactPoint: {
|
contactPoint: {
|
||||||
'@type': 'ContactPoint',
|
'@type': 'ContactPoint',
|
||||||
contactType: 'Customer Support',
|
contactType: 'Customer Support',
|
||||||
email: 'support@qrmaster.net',
|
email: 'support@qrmaster.net',
|
||||||
availableLanguage: ['English', 'German'],
|
availableLanguage: ['English', 'German'],
|
||||||
},
|
},
|
||||||
description: 'B2B SaaS platform for dynamic QR code generation with analytics, branding, and bulk generation for enterprise marketing campaigns.',
|
description: 'B2B SaaS platform for dynamic QR code generation with analytics, branding, and bulk generation for enterprise marketing campaigns.',
|
||||||
slogan: 'Dynamic QR codes that work smarter',
|
slogan: 'Dynamic QR codes that work smarter',
|
||||||
foundingDate: '2025',
|
foundingDate: '2025',
|
||||||
areaServed: 'Worldwide',
|
areaServed: 'Worldwide',
|
||||||
serviceType: 'Software as a Service',
|
serviceType: 'Software as a Service',
|
||||||
priceRange: '$0 - $29',
|
priceRange: '$0 - $29',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Website Schema for all pages
|
// Website Schema for all pages
|
||||||
const websiteSchema = {
|
const websiteSchema = {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'WebSite',
|
'@type': 'WebSite',
|
||||||
'@id': 'https://www.qrmaster.net/#website',
|
'@id': 'https://www.qrmaster.net/#website',
|
||||||
name: 'QR Master',
|
name: 'QR Master',
|
||||||
url: 'https://www.qrmaster.net',
|
url: 'https://www.qrmaster.net',
|
||||||
inLanguage: 'en',
|
inLanguage: 'en',
|
||||||
publisher: { '@id': 'https://www.qrmaster.net/#organization' },
|
publisher: { '@id': 'https://www.qrmaster.net/#organization' },
|
||||||
potentialAction: {
|
potentialAction: {
|
||||||
'@type': 'SearchAction',
|
'@type': 'SearchAction',
|
||||||
target: {
|
target: {
|
||||||
'@type': 'EntryPoint',
|
'@type': 'EntryPoint',
|
||||||
urlTemplate: 'https://www.qrmaster.net/blog?q={search_term_string}',
|
urlTemplate: 'https://www.qrmaster.net/blog?q={search_term_string}',
|
||||||
},
|
},
|
||||||
'query-input': 'required name=search_term_string',
|
'query-input': 'required name=search_term_string',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
metadataBase: new URL('https://www.qrmaster.net'),
|
metadataBase: new URL('https://www.qrmaster.net'),
|
||||||
title: {
|
title: {
|
||||||
default: 'QR Master – Smart QR Generator & Analytics',
|
default: 'QR Master – Smart QR Generator & Analytics',
|
||||||
template: '%s | QR Master',
|
template: '%s | QR Master',
|
||||||
},
|
},
|
||||||
description: 'Create dynamic QR codes, track scans, and scale campaigns with secure analytics.',
|
description: 'Create dynamic QR codes, track scans, and scale campaigns with secure analytics.',
|
||||||
keywords: 'QR code, QR generator, dynamic QR, QR tracking, QR analytics, branded QR, bulk QR generator',
|
keywords: 'QR code, QR generator, dynamic QR, QR tracking, QR analytics, branded QR, bulk QR generator',
|
||||||
robots: isIndexable
|
robots: isIndexable
|
||||||
? { index: true, follow: true }
|
? { index: true, follow: true }
|
||||||
: { index: false, follow: false },
|
: { index: false, follow: false },
|
||||||
icons: {
|
icons: {
|
||||||
icon: [
|
icon: [
|
||||||
{ url: '/favicon.svg', type: 'image/svg+xml' },
|
{ url: '/favicon.svg', type: 'image/svg+xml' },
|
||||||
{ url: '/logo.svg', type: 'image/svg+xml' },
|
{ url: '/logo.svg', type: 'image/svg+xml' },
|
||||||
],
|
],
|
||||||
apple: '/logo.svg',
|
apple: '/logo.svg',
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: 'summary_large_image',
|
card: 'summary_large_image',
|
||||||
site: '@qrmaster',
|
site: '@qrmaster',
|
||||||
images: ['https://www.qrmaster.net/static/og-image.png'],
|
images: ['https://www.qrmaster.net/static/og-image.png'],
|
||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
type: 'website',
|
type: 'website',
|
||||||
siteName: 'QR Master',
|
siteName: 'QR Master',
|
||||||
title: 'QR Master – Smart QR Generator & Analytics',
|
title: 'QR Master – Smart QR Generator & Analytics',
|
||||||
description: 'Create dynamic QR codes, track scans, and scale campaigns with secure analytics.',
|
description: 'Create dynamic QR codes, track scans, and scale campaigns with secure analytics.',
|
||||||
url: 'https://www.qrmaster.net',
|
url: 'https://www.qrmaster.net',
|
||||||
images: [
|
images: [
|
||||||
{
|
{
|
||||||
url: 'https://www.qrmaster.net/static/og-image.png',
|
url: 'https://www.qrmaster.net/static/og-image.png',
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: 'QR Master - Dynamic QR Code Generator and Analytics Platform',
|
alt: 'QR Master - Dynamic QR Code Generator and Analytics Platform',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
locale: 'en_US',
|
locale: 'en_US',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(organizationSchema) }}
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(organizationSchema) }}
|
||||||
/>
|
/>
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(websiteSchema) }}
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(websiteSchema) }}
|
||||||
/>
|
/>
|
||||||
<script
|
<script
|
||||||
async
|
async
|
||||||
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2782770414424875"
|
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2782770414424875"
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
/>
|
/>
|
||||||
</head>
|
</head>
|
||||||
<body className="font-sans">
|
<body className="font-sans">
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<PostHogProvider>
|
<PostHogProvider>
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
{children}
|
{children}
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
<CookieBanner />
|
<CookieBanner />
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
</PostHogProvider>
|
</PostHogProvider>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,59 +1,59 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
|
|
||||||
interface AdBannerProps {
|
interface AdBannerProps {
|
||||||
dataAdSlot: string;
|
dataAdSlot: string;
|
||||||
dataAdFormat?: string;
|
dataAdFormat?: string;
|
||||||
fullWidthResponsive?: boolean;
|
fullWidthResponsive?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AdBanner({
|
export default function AdBanner({
|
||||||
dataAdSlot,
|
dataAdSlot,
|
||||||
dataAdFormat = 'auto',
|
dataAdFormat = 'auto',
|
||||||
fullWidthResponsive = true,
|
fullWidthResponsive = true,
|
||||||
className = '',
|
className = '',
|
||||||
}: AdBannerProps) {
|
}: AdBannerProps) {
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
|
|
||||||
// Check if user has a paid plan
|
// Check if user has a paid plan
|
||||||
// Adjust 'pro' or 'premium' based on your actual plan values
|
// Adjust 'pro' or 'premium' based on your actual plan values
|
||||||
const isPaidUser = session?.user && (
|
const isPaidUser = session?.user && (
|
||||||
session.user.plan === 'PRO' ||
|
session.user.plan === 'PRO' ||
|
||||||
session.user.plan === 'PREMIUM' ||
|
session.user.plan === 'PREMIUM' ||
|
||||||
session.user.plan === 'LIFETIME'
|
session.user.plan === 'LIFETIME'
|
||||||
);
|
);
|
||||||
|
|
||||||
const [adLoaded, setAdLoaded] = useState(false);
|
const [adLoaded, setAdLoaded] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Don't load if loading session or if user is paid
|
// Don't load if loading session or if user is paid
|
||||||
if (status === 'loading' || isPaidUser) return;
|
if (status === 'loading' || isPaidUser) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||||
setAdLoaded(true);
|
setAdLoaded(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('AdSense error:', err);
|
console.error('AdSense error:', err);
|
||||||
}
|
}
|
||||||
}, [isPaidUser, status]);
|
}, [isPaidUser, status]);
|
||||||
|
|
||||||
// Don't render anything if paid user
|
// Don't render anything if paid user
|
||||||
if (status === 'authenticated' && isPaidUser) return null;
|
if (status === 'authenticated' && isPaidUser) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`ad-container my-8 flex justify-center items-center overflow-hidden ${className}`} aria-hidden={true}>
|
<div className={`ad-container my-8 flex justify-center items-center overflow-hidden ${className}`} aria-hidden={true}>
|
||||||
<ins
|
<ins
|
||||||
className="adsbygoogle"
|
className="adsbygoogle"
|
||||||
style={{ display: 'block', minWidth: '300px', minHeight: '50px', width: '100%' }}
|
style={{ display: 'block', minWidth: '300px', minHeight: '50px', width: '100%' }}
|
||||||
data-ad-client="ca-pub-2782770414424875"
|
data-ad-client="ca-pub-2782770414424875"
|
||||||
data-ad-slot={dataAdSlot}
|
data-ad-slot={dataAdSlot}
|
||||||
data-ad-format={dataAdFormat}
|
data-ad-format={dataAdFormat}
|
||||||
data-full-width-responsive={fullWidthResponsive}
|
data-full-width-responsive={fullWidthResponsive}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
798
src/i18n/de.json
798
src/i18n/de.json
|
|
@ -1,400 +1,400 @@
|
||||||
{
|
{
|
||||||
"nav": {
|
"nav": {
|
||||||
"features": "Funktionen",
|
"features": "Funktionen",
|
||||||
"pricing": "Preise",
|
"pricing": "Preise",
|
||||||
"faq": "FAQ",
|
"faq": "FAQ",
|
||||||
"blog": "Blog",
|
"blog": "Blog",
|
||||||
"login": "Anmelden",
|
"login": "Anmelden",
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
"create_qr": "QR erstellen",
|
"create_qr": "QR erstellen",
|
||||||
"bulk_creation": "Massen-Erstellung",
|
"bulk_creation": "Massen-Erstellung",
|
||||||
"analytics": "Analytik",
|
"analytics": "Analytik",
|
||||||
"settings": "Einstellungen",
|
"settings": "Einstellungen",
|
||||||
"cta": "Kostenlos loslegen",
|
"cta": "Kostenlos loslegen",
|
||||||
"tools": "Kostenlose Tools",
|
"tools": "Kostenlose Tools",
|
||||||
"all_free": "Alle Generatoren sind 100% kostenlos"
|
"all_free": "Alle Generatoren sind 100% kostenlos"
|
||||||
},
|
},
|
||||||
"hero": {
|
"hero": {
|
||||||
"badge": "Kostenloser QR-Code-Generator",
|
"badge": "Kostenloser QR-Code-Generator",
|
||||||
"title": "Erstellen Sie QR-Codes, die überall funktionieren",
|
"title": "Erstellen Sie QR-Codes, die überall funktionieren",
|
||||||
"subtitle": "Generieren Sie statische und dynamische QR-Codes mit Tracking, individuellem Branding und Massen-Erstellung. Kostenlos für immer.",
|
"subtitle": "Generieren Sie statische und dynamische QR-Codes mit Tracking, individuellem Branding und Massen-Erstellung. Kostenlos für immer.",
|
||||||
"features": [
|
"features": [
|
||||||
"Keine Kreditkarte zum Starten erforderlich",
|
"Keine Kreditkarte zum Starten erforderlich",
|
||||||
"QR-Codes für immer kostenlos erstellen",
|
"QR-Codes für immer kostenlos erstellen",
|
||||||
"Erweiterte Verfolgung und Analytik",
|
"Erweiterte Verfolgung und Analytik",
|
||||||
"Individuelle Farben und Stile"
|
"Individuelle Farben und Stile"
|
||||||
],
|
],
|
||||||
"cta_primary": "QR-Code kostenlos erstellen",
|
"cta_primary": "QR-Code kostenlos erstellen",
|
||||||
"cta_secondary": "Preise ansehen",
|
"cta_secondary": "Preise ansehen",
|
||||||
"engagement_badge": "Kostenlos für immer",
|
"engagement_badge": "Kostenlos für immer",
|
||||||
"get_started": "Loslegen",
|
"get_started": "Loslegen",
|
||||||
"view_full_pricing": "Alle Preisdetails ansehen →"
|
"view_full_pricing": "Alle Preisdetails ansehen →"
|
||||||
},
|
},
|
||||||
"trust": {
|
"trust": {
|
||||||
"users": "10.000+ Aktive Nutzer",
|
"users": "10.000+ Aktive Nutzer",
|
||||||
"codes": "500.000+ QR-Codes erstellt",
|
"codes": "500.000+ QR-Codes erstellt",
|
||||||
"scans": "50M+ Scans verfolgt",
|
"scans": "50M+ Scans verfolgt",
|
||||||
"countries": "120+ Länder"
|
"countries": "120+ Länder"
|
||||||
},
|
},
|
||||||
"industries": {
|
"industries": {
|
||||||
"restaurant": "Restaurant-Kette",
|
"restaurant": "Restaurant-Kette",
|
||||||
"tech": "Tech-Startup",
|
"tech": "Tech-Startup",
|
||||||
"realestate": "Immobilien",
|
"realestate": "Immobilien",
|
||||||
"events": "Event-Agentur",
|
"events": "Event-Agentur",
|
||||||
"retail": "Einzelhandel",
|
"retail": "Einzelhandel",
|
||||||
"healthcare": "Gesundheitswesen"
|
"healthcare": "Gesundheitswesen"
|
||||||
},
|
},
|
||||||
"templates": {
|
"templates": {
|
||||||
"title": "Mit einer Vorlage beginnen",
|
"title": "Mit einer Vorlage beginnen",
|
||||||
"restaurant": "Restaurant-Menü",
|
"restaurant": "Restaurant-Menü",
|
||||||
"business": "Visitenkarte",
|
"business": "Visitenkarte",
|
||||||
"vcard": "Kontaktkarte",
|
"vcard": "Kontaktkarte",
|
||||||
"event": "Event-Ticket",
|
"event": "Event-Ticket",
|
||||||
"use_template": "Vorlage verwenden →"
|
"use_template": "Vorlage verwenden →"
|
||||||
},
|
},
|
||||||
"generator": {
|
"generator": {
|
||||||
"title": "Sofortiger QR-Code-Generator",
|
"title": "Sofortiger QR-Code-Generator",
|
||||||
"url_placeholder": "Geben Sie hier Ihre URL ein...",
|
"url_placeholder": "Geben Sie hier Ihre URL ein...",
|
||||||
"foreground": "Vordergrund",
|
"foreground": "Vordergrund",
|
||||||
"background": "Hintergrund",
|
"background": "Hintergrund",
|
||||||
"corners": "Ecken",
|
"corners": "Ecken",
|
||||||
"size": "Größe",
|
"size": "Größe",
|
||||||
"contrast_good": "Guter Kontrast",
|
"contrast_good": "Guter Kontrast",
|
||||||
"download_svg": "SVG herunterladen",
|
"download_svg": "SVG herunterladen",
|
||||||
"download_png": "PNG herunterladen",
|
"download_png": "PNG herunterladen",
|
||||||
"save_track": "Speichern & Verfolgen",
|
"save_track": "Speichern & Verfolgen",
|
||||||
"live_preview": "Live-Vorschau",
|
"live_preview": "Live-Vorschau",
|
||||||
"demo_note": "Dies ist ein Demo-QR-Code"
|
"demo_note": "Dies ist ein Demo-QR-Code"
|
||||||
},
|
},
|
||||||
"static_vs_dynamic": {
|
"static_vs_dynamic": {
|
||||||
"title": "Warum dynamische QR-Codes Geld sparen",
|
"title": "Warum dynamische QR-Codes Geld sparen",
|
||||||
"description": "Hören Sie auf, Materialien neu zu drucken. Ändern Sie Zielorte sofort und verfolgen Sie jeden Scan.",
|
"description": "Hören Sie auf, Materialien neu zu drucken. Ändern Sie Zielorte sofort und verfolgen Sie jeden Scan.",
|
||||||
"static": {
|
"static": {
|
||||||
"title": "Statische QR-Codes",
|
"title": "Statische QR-Codes",
|
||||||
"subtitle": "Immer kostenlos",
|
"subtitle": "Immer kostenlos",
|
||||||
"description": "Perfekt für permanente Inhalte, die sich nie ändern",
|
"description": "Perfekt für permanente Inhalte, die sich nie ändern",
|
||||||
"features": [
|
"features": [
|
||||||
"Inhalt kann nicht bearbeitet werden",
|
"Inhalt kann nicht bearbeitet werden",
|
||||||
"Keine Scan-Verfolgung",
|
"Keine Scan-Verfolgung",
|
||||||
"Funktioniert für immer",
|
"Funktioniert für immer",
|
||||||
"Kein Konto erforderlich"
|
"Kein Konto erforderlich"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dynamic": {
|
"dynamic": {
|
||||||
"title": "Dynamische QR-Codes",
|
"title": "Dynamische QR-Codes",
|
||||||
"subtitle": "Empfohlen",
|
"subtitle": "Empfohlen",
|
||||||
"description": "Volle Kontrolle mit Tracking- und Bearbeitungsfunktionen",
|
"description": "Volle Kontrolle mit Tracking- und Bearbeitungsfunktionen",
|
||||||
"features": [
|
"features": [
|
||||||
"Inhalt jederzeit bearbeiten",
|
"Inhalt jederzeit bearbeiten",
|
||||||
"Erweiterte Analytik",
|
"Erweiterte Analytik",
|
||||||
"Individuelles Branding",
|
"Individuelles Branding",
|
||||||
"Bulk-Operationen"
|
"Bulk-Operationen"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"features": {
|
"features": {
|
||||||
"title": "Alles was Sie brauchen, um professionelle QR-Codes zu erstellen",
|
"title": "Alles was Sie brauchen, um professionelle QR-Codes zu erstellen",
|
||||||
"analytics": {
|
"analytics": {
|
||||||
"title": "Erweiterte Analytik",
|
"title": "Erweiterte Analytik",
|
||||||
"description": "Verfolgen Sie Scans, Standorte, Geräte und Nutzerverhalten mit detaillierten Einblicken."
|
"description": "Verfolgen Sie Scans, Standorte, Geräte und Nutzerverhalten mit detaillierten Einblicken."
|
||||||
},
|
},
|
||||||
"customization": {
|
"customization": {
|
||||||
"title": "Vollständige Anpassung",
|
"title": "Vollständige Anpassung",
|
||||||
"description": "Branden Sie Ihre QR-Codes mit individuellen Farben, Logos und Styling-Optionen."
|
"description": "Branden Sie Ihre QR-Codes mit individuellen Farben, Logos und Styling-Optionen."
|
||||||
},
|
},
|
||||||
"unlimited": {
|
"unlimited": {
|
||||||
"title": "Unbegrenzte statische QR-Codes",
|
"title": "Unbegrenzte statische QR-Codes",
|
||||||
"description": "Erstellen Sie so viele statische QR-Codes wie Sie möchten. Für immer kostenlos, ohne Limits."
|
"description": "Erstellen Sie so viele statische QR-Codes wie Sie möchten. Für immer kostenlos, ohne Limits."
|
||||||
},
|
},
|
||||||
"bulk": {
|
"bulk": {
|
||||||
"title": "Bulk-Operationen",
|
"title": "Bulk-Operationen",
|
||||||
"description": "Erstellen Sie hunderte von QR-Codes auf einmal mit CSV-Import und Batch-Verarbeitung."
|
"description": "Erstellen Sie hunderte von QR-Codes auf einmal mit CSV-Import und Batch-Verarbeitung."
|
||||||
},
|
},
|
||||||
"integrations": {
|
"integrations": {
|
||||||
"title": "Integrationen",
|
"title": "Integrationen",
|
||||||
"description": "Verbinden Sie sich mit Zapier, Airtable, Google Sheets und weiteren beliebten Tools."
|
"description": "Verbinden Sie sich mit Zapier, Airtable, Google Sheets und weiteren beliebten Tools."
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"title": "Entwickler-API",
|
"title": "Entwickler-API",
|
||||||
"description": "Integrieren Sie QR-Code-Generierung in Ihre Anwendungen mit unserer REST-API."
|
"description": "Integrieren Sie QR-Code-Generierung in Ihre Anwendungen mit unserer REST-API."
|
||||||
},
|
},
|
||||||
"support": {
|
"support": {
|
||||||
"title": "24/7 Support",
|
"title": "24/7 Support",
|
||||||
"description": "Erhalten Sie Hilfe, wenn Sie sie brauchen, mit unserem dedizierten Kundensupport-Team."
|
"description": "Erhalten Sie Hilfe, wenn Sie sie brauchen, mit unserem dedizierten Kundensupport-Team."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pricing": {
|
"pricing": {
|
||||||
"title": "Wählen Sie Ihren Plan",
|
"title": "Wählen Sie Ihren Plan",
|
||||||
"subtitle": "Wählen Sie den perfekten Plan für Ihre QR-Code-Bedürfnisse",
|
"subtitle": "Wählen Sie den perfekten Plan für Ihre QR-Code-Bedürfnisse",
|
||||||
"choose_plan": "Wählen Sie Ihren Plan",
|
"choose_plan": "Wählen Sie Ihren Plan",
|
||||||
"select_plan": "Wählen Sie den perfekten Plan für Ihre QR-Code-Bedürfnisse",
|
"select_plan": "Wählen Sie den perfekten Plan für Ihre QR-Code-Bedürfnisse",
|
||||||
"current_plan": "Aktueller Plan",
|
"current_plan": "Aktueller Plan",
|
||||||
"upgrade_to": "Upgrade auf",
|
"upgrade_to": "Upgrade auf",
|
||||||
"downgrade_to_free": "Zu Kostenlos zurückstufen",
|
"downgrade_to_free": "Zu Kostenlos zurückstufen",
|
||||||
"most_popular": "Beliebteste",
|
"most_popular": "Beliebteste",
|
||||||
"all_plans_note": "Alle Pläne beinhalten unbegrenzte statische QR-Codes und Basis-Anpassung.",
|
"all_plans_note": "Alle Pläne beinhalten unbegrenzte statische QR-Codes und Basis-Anpassung.",
|
||||||
"free": {
|
"free": {
|
||||||
"title": "Kostenlos",
|
"title": "Kostenlos",
|
||||||
"name": "Free",
|
"name": "Free",
|
||||||
"price": "€0",
|
"price": "€0",
|
||||||
"period": "für immer",
|
"period": "für immer",
|
||||||
"features": [
|
"features": [
|
||||||
"3 dynamische QR-Codes",
|
"3 dynamische QR-Codes",
|
||||||
"Unbegrenzte statische QR-Codes",
|
"Unbegrenzte statische QR-Codes",
|
||||||
"Basis-Scan-Tracking",
|
"Basis-Scan-Tracking",
|
||||||
"Standard QR-Design-Vorlagen"
|
"Standard QR-Design-Vorlagen"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"pro": {
|
"pro": {
|
||||||
"title": "Pro",
|
"title": "Pro",
|
||||||
"name": "Pro",
|
"name": "Pro",
|
||||||
"price": "€9",
|
"price": "€9",
|
||||||
"period": "pro Monat",
|
"period": "pro Monat",
|
||||||
"badge": "Beliebteste",
|
"badge": "Beliebteste",
|
||||||
"features": [
|
"features": [
|
||||||
"50 dynamische QR-Codes",
|
"50 dynamische QR-Codes",
|
||||||
"Unbegrenzte statische QR-Codes",
|
"Unbegrenzte statische QR-Codes",
|
||||||
"Erweiterte Analytik (Scans, Geräte, Standorte)",
|
"Erweiterte Analytik (Scans, Geräte, Standorte)",
|
||||||
"Individuelles Branding (Farben)",
|
"Individuelles Branding (Farben)",
|
||||||
"Download als SVG/PNG"
|
"Download als SVG/PNG"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"business": {
|
"business": {
|
||||||
"title": "Business",
|
"title": "Business",
|
||||||
"name": "Business",
|
"name": "Business",
|
||||||
"price": "€29",
|
"price": "€29",
|
||||||
"period": "pro Monat",
|
"period": "pro Monat",
|
||||||
"features": [
|
"features": [
|
||||||
"500 dynamische QR-Codes",
|
"500 dynamische QR-Codes",
|
||||||
"Unbegrenzte statische QR-Codes",
|
"Unbegrenzte statische QR-Codes",
|
||||||
"Alles aus Pro",
|
"Alles aus Pro",
|
||||||
"Massen-QR-Erstellung (bis zu 1.000)",
|
"Massen-QR-Erstellung (bis zu 1.000)",
|
||||||
"Prioritäts-E-Mail-Support",
|
"Prioritäts-E-Mail-Support",
|
||||||
"Erweiterte Tracking & Insights"
|
"Erweiterte Tracking & Insights"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"faq": {
|
"faq": {
|
||||||
"title": "Häufig gestellte Fragen",
|
"title": "Häufig gestellte Fragen",
|
||||||
"questions": {
|
"questions": {
|
||||||
"account": {
|
"account": {
|
||||||
"question": "Benötige ich ein Konto, um QR-Codes zu erstellen?",
|
"question": "Benötige ich ein Konto, um QR-Codes zu erstellen?",
|
||||||
"answer": "Für statische QR-Codes ist kein Konto erforderlich. Dynamische QR-Codes mit Tracking- und Bearbeitungsfunktionen erfordern jedoch ein kostenloses Konto."
|
"answer": "Für statische QR-Codes ist kein Konto erforderlich. Dynamische QR-Codes mit Tracking- und Bearbeitungsfunktionen erfordern jedoch ein kostenloses Konto."
|
||||||
},
|
},
|
||||||
"static_vs_dynamic": {
|
"static_vs_dynamic": {
|
||||||
"question": "Was ist der Unterschied zwischen statischen und dynamischen QR-Codes?",
|
"question": "Was ist der Unterschied zwischen statischen und dynamischen QR-Codes?",
|
||||||
"answer": "Statische QR-Codes enthalten feste Inhalte, die nicht geändert werden können. Dynamische QR-Codes können jederzeit bearbeitet werden und bieten detaillierte Analytik."
|
"answer": "Statische QR-Codes enthalten feste Inhalte, die nicht geändert werden können. Dynamische QR-Codes können jederzeit bearbeitet werden und bieten detaillierte Analytik."
|
||||||
},
|
},
|
||||||
"forever": {
|
"forever": {
|
||||||
"question": "Funktionieren meine QR-Codes für immer?",
|
"question": "Funktionieren meine QR-Codes für immer?",
|
||||||
"answer": "Statische QR-Codes funktionieren für immer, da der Inhalt direkt eingebettet ist. Dynamische QR-Codes funktionieren, solange Ihr Konto aktiv ist."
|
"answer": "Statische QR-Codes funktionieren für immer, da der Inhalt direkt eingebettet ist. Dynamische QR-Codes funktionieren, solange Ihr Konto aktiv ist."
|
||||||
},
|
},
|
||||||
"file_type": {
|
"file_type": {
|
||||||
"question": "Welchen Dateityp sollte ich zum Drucken verwenden?",
|
"question": "Welchen Dateityp sollte ich zum Drucken verwenden?",
|
||||||
"answer": "Für Druckmaterialien empfehlen wir das SVG-Format für Skalierbarkeit oder hochauflösendes PNG (300+ DPI) für beste Qualität."
|
"answer": "Für Druckmaterialien empfehlen wir das SVG-Format für Skalierbarkeit oder hochauflösendes PNG (300+ DPI) für beste Qualität."
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"question": "Kann ich einen QR-Code mit einem Passwort schützen?",
|
"question": "Kann ich einen QR-Code mit einem Passwort schützen?",
|
||||||
"answer": "Ja, Pro- und Business-Pläne beinhalten Passwortschutz und Zugriffskontrollfunktionen für Ihre QR-Codes."
|
"answer": "Ja, Pro- und Business-Pläne beinhalten Passwortschutz und Zugriffskontrollfunktionen für Ihre QR-Codes."
|
||||||
},
|
},
|
||||||
"analytics": {
|
"analytics": {
|
||||||
"question": "Wie funktioniert die Analytik?",
|
"question": "Wie funktioniert die Analytik?",
|
||||||
"answer": "Wir verfolgen Scans, Standorte, Geräte und Referrer unter Beachtung der Privatsphäre der Nutzer. Keine persönlichen Daten werden gespeichert."
|
"answer": "Wir verfolgen Scans, Standorte, Geräte und Referrer unter Beachtung der Privatsphäre der Nutzer. Keine persönlichen Daten werden gespeichert."
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"question": "Verfolgen Sie persönliche Daten?",
|
"question": "Verfolgen Sie persönliche Daten?",
|
||||||
"answer": "Wir respektieren die Privatsphäre und sammeln nur anonyme Nutzungsdaten. IP-Adressen werden gehasht und wir respektieren Do-Not-Track-Header."
|
"answer": "Wir respektieren die Privatsphäre und sammeln nur anonyme Nutzungsdaten. IP-Adressen werden gehasht und wir respektieren Do-Not-Track-Header."
|
||||||
},
|
},
|
||||||
"bulk": {
|
"bulk": {
|
||||||
"question": "Kann ich Codes in großen Mengen mit meinen eigenen Daten erstellen?",
|
"question": "Kann ich Codes in großen Mengen mit meinen eigenen Daten erstellen?",
|
||||||
"answer": "Ja, Sie können CSV- oder Excel-Dateien hochladen, um mehrere QR-Codes auf einmal mit individueller Datenzuordnung zu erstellen."
|
"answer": "Ja, Sie können CSV- oder Excel-Dateien hochladen, um mehrere QR-Codes auf einmal mit individueller Datenzuordnung zu erstellen."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"title": "Dashboard",
|
"title": "Dashboard",
|
||||||
"subtitle": "Verwalten Sie Ihre QR-Codes und verfolgen Sie Ihre Performance",
|
"subtitle": "Verwalten Sie Ihre QR-Codes und verfolgen Sie Ihre Performance",
|
||||||
"stats": {
|
"stats": {
|
||||||
"total_scans": "Gesamte Scans",
|
"total_scans": "Gesamte Scans",
|
||||||
"active_codes": "Aktive QR-Codes",
|
"active_codes": "Aktive QR-Codes",
|
||||||
"conversion_rate": "Konversionsrate"
|
"conversion_rate": "Konversionsrate"
|
||||||
},
|
},
|
||||||
"recent_codes": "Aktuelle QR-Codes",
|
"recent_codes": "Aktuelle QR-Codes",
|
||||||
"blog_resources": "Blog & Ressourcen",
|
"blog_resources": "Blog & Ressourcen",
|
||||||
"menu": {
|
"menu": {
|
||||||
"edit": "Bearbeiten",
|
"edit": "Bearbeiten",
|
||||||
"duplicate": "Duplizieren",
|
"duplicate": "Duplizieren",
|
||||||
"pause": "Pausieren",
|
"pause": "Pausieren",
|
||||||
"delete": "Löschen"
|
"delete": "Löschen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"create": {
|
"create": {
|
||||||
"title": "QR-Code erstellen",
|
"title": "QR-Code erstellen",
|
||||||
"subtitle": "Generieren Sie dynamische und statische QR-Codes mit individuellem Branding",
|
"subtitle": "Generieren Sie dynamische und statische QR-Codes mit individuellem Branding",
|
||||||
"content": "Inhalt",
|
"content": "Inhalt",
|
||||||
"type": "QR-Code-Typ",
|
"type": "QR-Code-Typ",
|
||||||
"style": "Stil & Branding",
|
"style": "Stil & Branding",
|
||||||
"preview": "Live-Vorschau",
|
"preview": "Live-Vorschau",
|
||||||
"title_label": "Titel",
|
"title_label": "Titel",
|
||||||
"title_placeholder": "Mein QR-Code",
|
"title_placeholder": "Mein QR-Code",
|
||||||
"content_type": "Inhaltstyp",
|
"content_type": "Inhaltstyp",
|
||||||
"url_label": "URL",
|
"url_label": "URL",
|
||||||
"url_placeholder": "https://beispiel.de",
|
"url_placeholder": "https://beispiel.de",
|
||||||
"tags_label": "Tags (durch Komma getrennt)",
|
"tags_label": "Tags (durch Komma getrennt)",
|
||||||
"tags_placeholder": "marketing, kampagne, 2025",
|
"tags_placeholder": "marketing, kampagne, 2025",
|
||||||
"qr_code_type": "QR-Code-Typ",
|
"qr_code_type": "QR-Code-Typ",
|
||||||
"dynamic": "Dynamisch",
|
"dynamic": "Dynamisch",
|
||||||
"static": "Statisch",
|
"static": "Statisch",
|
||||||
"recommended": "Empfohlen",
|
"recommended": "Empfohlen",
|
||||||
"dynamic_description": "Dynamisch: Scans verfolgen, URL später bearbeiten, Analytik ansehen. QR enthält Tracking-Link.",
|
"dynamic_description": "Dynamisch: Scans verfolgen, URL später bearbeiten, Analytik ansehen. QR enthält Tracking-Link.",
|
||||||
"static_description": "Statisch: Direkt zum Inhalt, kein Tracking, nicht bearbeitbar. QR enthält tatsächlichen Inhalt.",
|
"static_description": "Statisch: Direkt zum Inhalt, kein Tracking, nicht bearbeitbar. QR enthält tatsächlichen Inhalt.",
|
||||||
"foreground_color": "Vordergrundfarbe",
|
"foreground_color": "Vordergrundfarbe",
|
||||||
"background_color": "Hintergrundfarbe",
|
"background_color": "Hintergrundfarbe",
|
||||||
"corner_style": "Eckenstil",
|
"corner_style": "Eckenstil",
|
||||||
"size": "Größe",
|
"size": "Größe",
|
||||||
"good_contrast": "Guter Kontrast",
|
"good_contrast": "Guter Kontrast",
|
||||||
"contrast_ratio": "Kontrastverhältnis",
|
"contrast_ratio": "Kontrastverhältnis",
|
||||||
"download_svg": "SVG herunterladen",
|
"download_svg": "SVG herunterladen",
|
||||||
"download_png": "PNG herunterladen",
|
"download_png": "PNG herunterladen",
|
||||||
"save_qr_code": "QR-Code speichern"
|
"save_qr_code": "QR-Code speichern"
|
||||||
},
|
},
|
||||||
"analytics": {
|
"analytics": {
|
||||||
"title": "Analytik",
|
"title": "Analytik",
|
||||||
"subtitle": "Verfolgen und analysieren Sie die Performance Ihrer QR-Codes",
|
"subtitle": "Verfolgen und analysieren Sie die Performance Ihrer QR-Codes",
|
||||||
"export_report": "Bericht exportieren",
|
"export_report": "Bericht exportieren",
|
||||||
"from_last_period": "vom letzten Zeitraum",
|
"from_last_period": "vom letzten Zeitraum",
|
||||||
"no_mobile_scans": "Keine mobilen Scans",
|
"no_mobile_scans": "Keine mobilen Scans",
|
||||||
"of_total": "der Gesamtmenge",
|
"of_total": "der Gesamtmenge",
|
||||||
"ranges": {
|
"ranges": {
|
||||||
"7d": "7 Tage",
|
"7d": "7 Tage",
|
||||||
"30d": "30 Tage",
|
"30d": "30 Tage",
|
||||||
"90d": "90 Tage"
|
"90d": "90 Tage"
|
||||||
},
|
},
|
||||||
"kpis": {
|
"kpis": {
|
||||||
"total_scans": "Gesamte Scans",
|
"total_scans": "Gesamte Scans",
|
||||||
"avg_scans": "Ø Scans/QR",
|
"avg_scans": "Ø Scans/QR",
|
||||||
"mobile_usage": "Mobile Nutzung",
|
"mobile_usage": "Mobile Nutzung",
|
||||||
"top_country": "Top Land"
|
"top_country": "Top Land"
|
||||||
},
|
},
|
||||||
"charts": {
|
"charts": {
|
||||||
"scans_over_time": "Scans über Zeit",
|
"scans_over_time": "Scans über Zeit",
|
||||||
"device_types": "Gerätetypen",
|
"device_types": "Gerätetypen",
|
||||||
"top_countries": "Top Länder"
|
"top_countries": "Top Länder"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"qr_code": "QR-Code",
|
"qr_code": "QR-Code",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
"total_scans": "Gesamte Scans",
|
"total_scans": "Gesamte Scans",
|
||||||
"unique_scans": "Einzigartige Scans",
|
"unique_scans": "Einzigartige Scans",
|
||||||
"conversion": "Konversion",
|
"conversion": "Konversion",
|
||||||
"trend": "Trend",
|
"trend": "Trend",
|
||||||
"scans": "Scans",
|
"scans": "Scans",
|
||||||
"percentage": "Prozent",
|
"percentage": "Prozent",
|
||||||
"country": "Land",
|
"country": "Land",
|
||||||
"performance": "Performance",
|
"performance": "Performance",
|
||||||
"created": "Erstellt",
|
"created": "Erstellt",
|
||||||
"status": "Status"
|
"status": "Status"
|
||||||
},
|
},
|
||||||
"performance_title": "QR-Code-Performance"
|
"performance_title": "QR-Code-Performance"
|
||||||
},
|
},
|
||||||
"bulk": {
|
"bulk": {
|
||||||
"title": "Massen-Erstellung",
|
"title": "Massen-Erstellung",
|
||||||
"subtitle": "Erstellen Sie mehrere QR-Codes gleichzeitig aus CSV- oder Excel-Dateien",
|
"subtitle": "Erstellen Sie mehrere QR-Codes gleichzeitig aus CSV- oder Excel-Dateien",
|
||||||
"template_warning_title": "Bitte folgen Sie dem Vorlagenformat",
|
"template_warning_title": "Bitte folgen Sie dem Vorlagenformat",
|
||||||
"template_warning_text": "Laden Sie die Vorlage unten herunter und folgen Sie dem Format genau. Ihre CSV muss Spalten für Titel und Inhalt (URL) enthalten.",
|
"template_warning_text": "Laden Sie die Vorlage unten herunter und folgen Sie dem Format genau. Ihre CSV muss Spalten für Titel und Inhalt (URL) enthalten.",
|
||||||
"static_only_title": "Nur statische QR-Codes",
|
"static_only_title": "Nur statische QR-Codes",
|
||||||
"static_only_text": "Massen-Erstellung generiert statische QR-Codes, die nach der Erstellung nicht bearbeitet werden können. Diese QR-Codes beinhalten kein Tracking oder Analytik. Perfekt für Druckmaterialien und Offline-Nutzung.",
|
"static_only_text": "Massen-Erstellung generiert statische QR-Codes, die nach der Erstellung nicht bearbeitet werden können. Diese QR-Codes beinhalten kein Tracking oder Analytik. Perfekt für Druckmaterialien und Offline-Nutzung.",
|
||||||
"download_template": "Vorlage herunterladen",
|
"download_template": "Vorlage herunterladen",
|
||||||
"no_file_selected": "Keine ausgewählt",
|
"no_file_selected": "Keine ausgewählt",
|
||||||
"simple_format": "Einfaches Format",
|
"simple_format": "Einfaches Format",
|
||||||
"just_title_url": "Nur Titel & URL",
|
"just_title_url": "Nur Titel & URL",
|
||||||
"static_qr_codes": "Statische QR-Codes",
|
"static_qr_codes": "Statische QR-Codes",
|
||||||
"no_tracking": "Kein Tracking enthalten",
|
"no_tracking": "Kein Tracking enthalten",
|
||||||
"instant_download": "Sofortiger Download",
|
"instant_download": "Sofortiger Download",
|
||||||
"get_zip": "ZIP mit allen SVGs erhalten",
|
"get_zip": "ZIP mit allen SVGs erhalten",
|
||||||
"max_rows": "max 1.000 Zeilen",
|
"max_rows": "max 1.000 Zeilen",
|
||||||
"steps": {
|
"steps": {
|
||||||
"upload": "Datei hochladen",
|
"upload": "Datei hochladen",
|
||||||
"preview": "Vorschau & Zuordnung",
|
"preview": "Vorschau & Zuordnung",
|
||||||
"download": "Herunterladen"
|
"download": "Herunterladen"
|
||||||
},
|
},
|
||||||
"drag_drop": "Datei hier hinziehen",
|
"drag_drop": "Datei hier hinziehen",
|
||||||
"or_click": "oder klicken zum Durchsuchen",
|
"or_click": "oder klicken zum Durchsuchen",
|
||||||
"supported_formats": "Unterstützt CSV, XLS, XLSX (max 1.000 Zeilen)"
|
"supported_formats": "Unterstützt CSV, XLS, XLSX (max 1.000 Zeilen)"
|
||||||
},
|
},
|
||||||
"integrations": {
|
"integrations": {
|
||||||
"title": "Integrationen",
|
"title": "Integrationen",
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"total_codes": "QR-Codes Gesamt",
|
"total_codes": "QR-Codes Gesamt",
|
||||||
"active_integrations": "Aktive Integrationen",
|
"active_integrations": "Aktive Integrationen",
|
||||||
"sync_status": "Sync-Status",
|
"sync_status": "Sync-Status",
|
||||||
"available_services": "Verfügbare Services"
|
"available_services": "Verfügbare Services"
|
||||||
},
|
},
|
||||||
"zapier": {
|
"zapier": {
|
||||||
"title": "Zapier",
|
"title": "Zapier",
|
||||||
"description": "Automatisieren Sie QR-Code-Erstellung mit 5000+ Apps",
|
"description": "Automatisieren Sie QR-Code-Erstellung mit 5000+ Apps",
|
||||||
"features": [
|
"features": [
|
||||||
"Trigger bei neuen QR-Codes",
|
"Trigger bei neuen QR-Codes",
|
||||||
"Codes aus anderen Apps erstellen",
|
"Codes aus anderen Apps erstellen",
|
||||||
"Scan-Daten synchronisieren"
|
"Scan-Daten synchronisieren"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"airtable": {
|
"airtable": {
|
||||||
"title": "Airtable",
|
"title": "Airtable",
|
||||||
"description": "Synchronisieren Sie QR-Codes mit Ihren Airtable-Basen",
|
"description": "Synchronisieren Sie QR-Codes mit Ihren Airtable-Basen",
|
||||||
"features": [
|
"features": [
|
||||||
"Bidirektionale Synchronisation",
|
"Bidirektionale Synchronisation",
|
||||||
"Individuelle Feldzuordnung",
|
"Individuelle Feldzuordnung",
|
||||||
"Echtzeit-Updates"
|
"Echtzeit-Updates"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sheets": {
|
"sheets": {
|
||||||
"title": "Google Sheets",
|
"title": "Google Sheets",
|
||||||
"description": "Exportieren Sie Daten automatisch zu Google Sheets",
|
"description": "Exportieren Sie Daten automatisch zu Google Sheets",
|
||||||
"features": [
|
"features": [
|
||||||
"Automatisierte Exporte",
|
"Automatisierte Exporte",
|
||||||
"Individuelle Vorlagen",
|
"Individuelle Vorlagen",
|
||||||
"Geplante Updates"
|
"Geplante Updates"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"activate": "Aktivieren & Konfigurieren"
|
"activate": "Aktivieren & Konfigurieren"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "Einstellungen",
|
"title": "Einstellungen",
|
||||||
"subtitle": "Verwalten Sie Ihre Kontoeinstellungen und Präferenzen",
|
"subtitle": "Verwalten Sie Ihre Kontoeinstellungen und Präferenzen",
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"profile": "Profil",
|
"profile": "Profil",
|
||||||
"billing": "Abrechnung",
|
"billing": "Abrechnung",
|
||||||
"team": "Team & Rollen",
|
"team": "Team & Rollen",
|
||||||
"api": "API-Schlüssel",
|
"api": "API-Schlüssel",
|
||||||
"workspace": "Arbeitsbereich"
|
"workspace": "Arbeitsbereich"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"save": "Speichern",
|
"save": "Speichern",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"edit": "Bearbeiten",
|
"edit": "Bearbeiten",
|
||||||
"create": "Erstellen",
|
"create": "Erstellen",
|
||||||
"loading": "Lädt...",
|
"loading": "Lädt...",
|
||||||
"error": "Ein Fehler ist aufgetreten",
|
"error": "Ein Fehler ist aufgetreten",
|
||||||
"success": "Erfolgreich!"
|
"success": "Erfolgreich!"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"product": "Produkt",
|
"product": "Produkt",
|
||||||
"features": "Funktionen",
|
"features": "Funktionen",
|
||||||
"pricing": "Preise",
|
"pricing": "Preise",
|
||||||
"faq": "FAQ",
|
"faq": "FAQ",
|
||||||
"blog": "Blog",
|
"blog": "Blog",
|
||||||
"resources": "Ressourcen",
|
"resources": "Ressourcen",
|
||||||
"full_pricing": "Alle Preise",
|
"full_pricing": "Alle Preise",
|
||||||
"all_questions": "Alle Fragen",
|
"all_questions": "Alle Fragen",
|
||||||
"all_articles": "Alle Artikel",
|
"all_articles": "Alle Artikel",
|
||||||
"get_started": "Loslegen",
|
"get_started": "Loslegen",
|
||||||
"legal": "Rechtliches",
|
"legal": "Rechtliches",
|
||||||
"privacy_policy": "Datenschutzerklärung",
|
"privacy_policy": "Datenschutzerklärung",
|
||||||
"tagline": "Erstellen Sie individuelle QR-Codes in Sekunden mit erweitertem Tracking und Analytik.",
|
"tagline": "Erstellen Sie individuelle QR-Codes in Sekunden mit erweitertem Tracking und Analytik.",
|
||||||
"newsletter": "Newsletter Anmeldung",
|
"newsletter": "Newsletter Anmeldung",
|
||||||
"rights_reserved": "QR Master. Alle Rechte vorbehalten."
|
"rights_reserved": "QR Master. Alle Rechte vorbehalten."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue