diff --git a/next.config.mjs b/next.config.mjs index 02bf2c7..4eff15a 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -34,66 +34,68 @@ const nextConfig = { pagesBufferLength: 2, }, poweredByHeader: false, - webpack: (config, { dev }) => { - if (!dev && isWslOnWindowsMount()) { - config.cache = { - type: 'filesystem', - cacheDirectory: path.join(os.tmpdir(), 'qrmaster-next-webpack-cache'), + webpack: (config, { dev }) => { + if (!dev && isWslOnWindowsMount()) { + config.cache = { + type: 'filesystem', + cacheDirectory: path.join(os.tmpdir(), 'qrmaster-next-webpack-cache'), }; } - - return config; - }, - async headers() { - const longCacheHeaders = [ - { - key: 'Cache-Control', - value: 'public, max-age=31536000, immutable', - }, - ]; - - return [ - { source: '/favicon1.png', headers: longCacheHeaders }, - { source: '/favicon.svg', headers: longCacheHeaders }, - { source: '/favicon.ico', headers: longCacheHeaders }, - { source: '/logo.svg', headers: longCacheHeaders }, - { source: '/producthunt-featured.svg', headers: longCacheHeaders }, - ]; - }, - async redirects() { - return [ - // SEO Cannibalization Redirects - { - source: '/tools/teams-qr-code', - destination: '/blog/microsoft-teams-qr-code', - permanent: true, - }, - { - source: '/dynamic-barcode-generator', - destination: '/tools/barcode-generator', - permanent: true, - }, - { - source: '/barcode-generator', - destination: '/tools/barcode-generator', - permanent: true, - }, - { - source: '/blog/qr-code-analytics', - destination: '/qr-code-analytics', - permanent: true, - }, - { - source: '/use-cases/restaurant-menu-qr-codes', - destination: '/restaurants', - permanent: true, - }, - { - source: '/blog/qr-code-restaurant-menu', - destination: '/restaurants', - permanent: true, - }, - + + return config; + }, + async headers() { + const longCacheHeaders = [ + { + key: 'Cache-Control', + value: 'public, max-age=31536000, immutable', + }, + ]; + + return [ + { source: '/favicon1.png', headers: longCacheHeaders }, + { source: '/favicon.svg', headers: longCacheHeaders }, + { source: '/favicon.ico', headers: longCacheHeaders }, + { source: '/logo.svg', headers: longCacheHeaders }, + { source: '/producthunt-featured.svg', headers: longCacheHeaders }, + ]; + }, + async redirects() { + return [ + // German home lives at /qr-code-erstellen (established ranking page); + // /de only hosts the German subpages. + { + source: '/de', + destination: '/qr-code-erstellen', + permanent: true, + }, + // SEO Cannibalization Redirects + { + source: '/dynamic-barcode-generator', + destination: '/tools/barcode-generator', + permanent: true, + }, + { + source: '/barcode-generator', + destination: '/tools/barcode-generator', + permanent: true, + }, + { + source: '/blog/qr-code-analytics', + destination: '/qr-code-analytics', + permanent: true, + }, + { + source: '/use-cases/restaurant-menu-qr-codes', + destination: '/restaurants', + permanent: true, + }, + { + source: '/blog/qr-code-restaurant-menu', + destination: '/restaurants', + permanent: true, + }, + { source: '/create-qr', destination: '/dynamic-qr-code-generator', diff --git a/src/app/(main)/(marketing)/MarketingLayout.tsx b/src/app/(main)/(marketing)/MarketingLayout.tsx index 33ae362..8d2ed34 100644 --- a/src/app/(main)/(marketing)/MarketingLayout.tsx +++ b/src/app/(main)/(marketing)/MarketingLayout.tsx @@ -5,10 +5,9 @@ import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { Button } from '@/components/ui/Button'; import { Footer } from '@/components/ui/Footer'; -import en from '@/i18n/en.json'; -import { allUseCases } from '@/lib/growth-pages'; -import { LayoutGrid } from 'lucide-react'; -import { ChevronDown, BookOpen, Building2, Wifi, Contact, MessageCircle, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users, Barcode as BarcodeIcon, Star } from 'lucide-react'; +import en from '@/i18n/en.json'; +import { publishedUseCases } from '@/lib/growth-pages'; +import { ChevronDown, LayoutGrid, BookOpen, Building2, Wifi, Contact, MessageCircle, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users, Barcode as BarcodeIcon, Star } from 'lucide-react'; import { cn } from '@/lib/utils'; import { AnimatePresence, motion } from 'framer-motion'; import Image from 'next/image'; @@ -20,10 +19,10 @@ export default function MarketingLayout({ }) { const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [scrolled, setScrolled] = useState(false); - const [toolsOpen, setToolsOpen] = useState(false); + const [toolsOpen, setToolsOpen] = useState(false); const [useCasesOpen, setUseCasesOpen] = useState(false); const [resourcesOpen, setResourcesOpen] = useState(false); - const [mobileToolsOpen, setMobileToolsOpen] = useState(false); + const [mobileToolsOpen, setMobileToolsOpen] = useState(false); const [mobileUseCasesOpen, setMobileUseCasesOpen] = useState(false); const [mobileResourcesOpen, setMobileResourcesOpen] = useState(false); const pathname = usePathname(); @@ -40,10 +39,10 @@ export default function MarketingLayout({ // Close simple menus when path changes useEffect(() => { setMobileMenuOpen(false); - setToolsOpen(false); + setToolsOpen(false); setUseCasesOpen(false); setResourcesOpen(false); - setMobileToolsOpen(false); + setMobileToolsOpen(false); setMobileUseCasesOpen(false); setMobileResourcesOpen(false); }, [pathname]); @@ -151,50 +150,50 @@ export default function MarketingLayout({ - {/* Use Cases Dropdown */} -
- Compare free QR generators with paid dynamic QR workflows before - choosing a plan. The difference usually comes down to editing - after print, scan tracking, branding, and reprint risk. -
- - Read the free vs paid QR generator comparison - -+ Compare free QR generators with paid dynamic QR workflows before + choosing a plan. The difference usually comes down to editing + after print, scan tracking, branding, and reprint risk. +
+ + Read the free vs paid QR generator comparison + +Free includes 3 active dynamic QR codes and unlimited static QR codes. Pro diff --git a/src/app/(main)/(marketing)/use-cases/[slug]/page.tsx b/src/app/(main)/(marketing)/use-cases/[slug]/page.tsx index c79e73f..c6b8cb2 100644 --- a/src/app/(main)/(marketing)/use-cases/[slug]/page.tsx +++ b/src/app/(main)/(marketing)/use-cases/[slug]/page.tsx @@ -5,6 +5,7 @@ import { UseCasePageTemplate, } from '@/components/marketing/UseCasePageTemplate'; import { allUseCases, getUseCasePage } from '@/lib/growth-pages'; +import { getGermanTwinByEnSlug } from '@/lib/growth-pages-de'; export function generateStaticParams() { return allUseCases.map((item) => ({ @@ -23,6 +24,7 @@ export function generateMetadata({ params }: { params: { slug: string } }) { title: page.title, description: page.metaDescription, canonicalPath: page.href, + dePath: getGermanTwinByEnSlug(page.slug)?.href, }); } diff --git a/src/app/(main)/(marketing)/use-cases/page.tsx b/src/app/(main)/(marketing)/use-cases/page.tsx index b0a84e7..52125ee 100644 --- a/src/app/(main)/(marketing)/use-cases/page.tsx +++ b/src/app/(main)/(marketing)/use-cases/page.tsx @@ -19,9 +19,9 @@ import { import { Button } from "@/components/ui/Button"; import { Card } from "@/components/ui/Card"; import { - allUseCases, commercialPages, featuredUseCases, + publishedUseCases, supportResources, upcomingUseCaseIdeas, } from "@/lib/growth-pages"; @@ -184,7 +184,7 @@ export default function UseCasesHubPage() {
- These industry routes connect practical use cases with the QR - tools local businesses usually need first. -
-- {item.description} -
-+ These industry routes connect practical use cases with the QR + tools local businesses usually need first. +
++ {item.description} +
+- QR Masters kostenloser Barcode Generator ermöglicht es Ihnen, - professionelle Barcodes für Produkte, Etiketten und Inventarsysteme zu - erstellen. Unterstützt EAN-13 für europäischen Einzelhandel, UPC-A für - US-Markt und Code 128 für Logistik und interne Verwendung. Alle - Barcodes sind standardkonform und sofort druckfertig. -
-- Unser Barcode Generator funktioniert vollständig im Browser. Keine - Software-Installation erforderlich. Exportieren Sie Ihre Barcodes als - PNG für den sofortigen Druck oder als SVG für professionelle - Verpackungsdesigns. Perfekt für kleine Unternehmen, Online-Händler und - Lagerverwaltung. -
-- Erstellen Sie professionelle Barcodes in Sekunden. Für{' '} - - Einzelhandel, Lager und Logistik - - . Unterstützt EAN-13, UPC-A und Code 128. Keine Anmeldung - erforderlich. -
- -- Geben Sie Ihre Daten ein und laden Sie den Barcode herunter -
-- Internationaler Standard für Einzelhandel. 13 Ziffern, weltweit - anerkannt. -
-- Amerikanischer Standard. 12 Ziffern, hauptsächlich in - Nordamerika. -
-- Flexible Lösung für Logistik. Alphanumerisch, hohe Datendichte. -
-- Geben Sie Ihre Produktnummer oder Text ein. -
-- EAN-13, UPC-A oder Code 128 auswählen. -
-- Barcode wird in Echtzeit aktualisiert. -
-- Als PNG oder SVG speichern. -
-- Sofort auf Etiketten drucken. -
-- Ob Kleinunternehmer, Online-Händler oder Lagerverwaltung – unser - Tool unterstützt Sie bei allen Barcode-Bedarfen. -
- -- EAN-13 Barcodes für Produktetiketten im stationären Handel. -
-- UPC/EAN für Amazon, eBay und andere Marktplätze. -
-- Code 128 für interne Bestandsverfolgung und Versand. -
-- SVG-Export für professionelle Verpackungsdesigns. -
-