This commit is contained in:
Timo Knuth
2026-01-25 14:59:25 +01:00
parent eef4855c1b
commit 30c1e57eab
104 changed files with 24652 additions and 24741 deletions

View File

@@ -1,318 +1,318 @@
'use client';
import React, { useState, useRef } from 'react';
import Link from 'next/link';
import { QRCodeSVG } from 'qrcode.react';
import {
Users,
Download,
Check,
Sparkles,
Video,
MessageCircle
} from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { cn } from '@/lib/utils';
// Brand Colors - Microsoft Teams Purple
const BRAND = {
paleGrey: '#F3F2F1',
primary: '#6264A7',
primaryDark: '#464775',
};
// QR Color Options
const QR_COLORS = [
{ name: 'Teams Purple', value: '#6264A7' },
{ name: 'Teams Dark', value: '#464775' },
{ name: 'Classic Black', value: '#000000' },
{ name: 'Indigo', value: '#4F46E5' },
{ name: 'Violet', value: '#7C3AED' },
{ name: 'Emerald', value: '#10B981' },
{ name: 'Rose', value: '#F43F5E' },
];
// Frame Options
const FRAME_OPTIONS = [
{ id: 'none', label: 'No Frame' },
{ id: 'scanme', label: 'Scan Me' },
{ id: 'join', label: 'Join Meeting' },
{ id: 'teams', label: 'Teams' },
];
// Link Type Options
const LINK_TYPES = [
{ id: 'meeting', label: 'Meeting Link', icon: Video },
{ id: 'chat', label: 'Chat with User', icon: MessageCircle },
];
export default function TeamsGenerator() {
const [linkType, setLinkType] = useState('meeting');
const [meetingUrl, setMeetingUrl] = useState('');
const [userEmail, setUserEmail] = useState('');
const [qrColor, setQrColor] = useState(BRAND.primary);
const [frameType, setFrameType] = useState('none');
const qrRef = useRef<HTMLDivElement>(null);
// Generate Teams link
const generateTeamsLink = () => {
if (linkType === 'meeting') {
// If user pastes full Teams meeting URL, use it directly
if (meetingUrl.trim().includes('teams.microsoft.com') || meetingUrl.trim().includes('teams.live.com')) {
return meetingUrl.trim();
}
// Otherwise return placeholder
return meetingUrl.trim() || 'https://teams.microsoft.com';
} else {
// Chat link with email
if (!userEmail.trim()) return 'https://teams.microsoft.com';
return `https://teams.microsoft.com/l/chat/0/0?users=${encodeURIComponent(userEmail.trim())}`;
}
};
const handleDownload = async (format: 'png' | 'svg') => {
if (!qrRef.current) return;
try {
if (format === 'png') {
const { toPng } = await import('html-to-image');
const dataUrl = await toPng(qrRef.current, { cacheBust: true, pixelRatio: 3 });
const link = document.createElement('a');
link.download = `teams-qr-code.png`;
link.href = dataUrl;
link.click();
} else {
const svgData = qrRef.current.querySelector('svg')?.outerHTML;
if (svgData) {
const blob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `teams-qr-code.svg`;
link.click();
}
}
} catch (err) {
console.error('Download failed', err);
}
};
const getFrameLabel = () => {
const frame = FRAME_OPTIONS.find(f => f.id === frameType);
return frame?.id !== 'none' ? frame?.label : null;
};
return (
<div className="w-full max-w-5xl mx-auto px-4 md:px-6">
{/* Main Generator Card */}
<div className="bg-white rounded-3xl shadow-2xl shadow-slate-900/10 overflow-hidden border border-slate-100">
<div className="grid lg:grid-cols-2">
{/* LEFT: Input Section */}
<div className="p-6 md:p-8 lg:p-10 space-y-8 border-r border-slate-100">
{/* Teams Details */}
<div className="space-y-6">
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
<Users className="w-5 h-5 text-[#6264A7]" />
Microsoft Teams
</h2>
<div className="space-y-4">
{/* Link Type Toggle */}
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">What do you want to share?</label>
<div className="grid grid-cols-2 gap-3">
{LINK_TYPES.map((type) => (
<button
key={type.id}
onClick={() => setLinkType(type.id)}
className={cn(
"flex items-center justify-center gap-2 py-3 px-4 rounded-xl font-medium transition-all border",
linkType === type.id
? "bg-[#6264A7] text-white border-[#6264A7]"
: "bg-slate-50 text-slate-600 border-slate-200 hover:border-slate-300"
)}
>
<type.icon className="w-4 h-4" />
{type.label}
</button>
))}
</div>
</div>
{linkType === 'meeting' ? (
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Teams Meeting URL</label>
<Input
placeholder="Paste your Teams meeting link here"
value={meetingUrl}
onChange={(e) => setMeetingUrl(e.target.value)}
className="h-12 text-base rounded-xl border-slate-200 focus:border-[#6264A7] focus:ring-[#6264A7]"
/>
<p className="text-xs text-slate-600 mt-2">
Copy the meeting link from your Teams calendar invite.
</p>
</div>
) : (
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">User Email Address</label>
<Input
type="email"
placeholder="e.g. colleague@company.com"
value={userEmail}
onChange={(e) => setUserEmail(e.target.value)}
className="h-12 text-base rounded-xl border-slate-200 focus:border-[#6264A7] focus:ring-[#6264A7]"
/>
<p className="text-xs text-slate-600 mt-2">
The person's work email to start a Teams chat.
</p>
</div>
)}
</div>
</div>
<div className="border-t border-slate-100"></div>
{/* Design Options */}
<div className="space-y-6">
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
<Sparkles className="w-5 h-5 text-[#6264A7]" />
Design Options
</h2>
{/* Color Picker */}
<div>
<label className="block text-sm font-medium text-slate-700 mb-3">QR Code Color</label>
<div className="flex flex-wrap gap-2">
{QR_COLORS.map((c) => (
<button
key={c.name}
onClick={() => setQrColor(c.value)}
className={cn(
"w-9 h-9 rounded-full border-2 flex items-center justify-center transition-all hover:scale-110",
qrColor === c.value ? "border-slate-900 ring-2 ring-offset-2 ring-slate-200" : "border-white shadow-md"
)}
style={{ backgroundColor: c.value }}
aria-label={`Select ${c.name}`}
title={c.name}
>
{qrColor === c.value && <Check className="w-4 h-4 text-white" strokeWidth={3} />}
</button>
))}
</div>
</div>
{/* Frame Selector */}
<div>
<label className="block text-sm font-medium text-slate-700 mb-3">Frame Label</label>
<div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
{FRAME_OPTIONS.map((frame) => (
<button
key={frame.id}
onClick={() => setFrameType(frame.id)}
className={cn(
"py-2.5 px-2 rounded-lg text-xs font-medium transition-all border",
frameType === frame.id
? "bg-[#6264A7] text-white border-[#6264A7]"
: "bg-slate-50 text-slate-600 border-slate-200 hover:border-slate-300"
)}
>
{frame.label}
</button>
))}
</div>
</div>
</div>
</div>
{/* RIGHT: Preview Section */}
<div className="p-6 md:p-8 lg:p-10 flex flex-col items-center justify-center" style={{ backgroundColor: BRAND.paleGrey }}>
{/* QR Card with Frame */}
<div
ref={qrRef}
className="bg-white rounded-3xl shadow-xl p-6 sm:p-8 flex flex-col items-center w-full max-w-[320px]"
>
{/* Frame Label */}
{getFrameLabel() && (
<div
className="mb-5 px-8 py-2.5 rounded-full text-white font-bold text-sm tracking-widest uppercase shadow-md"
style={{ backgroundColor: qrColor }}
>
{getFrameLabel()}
</div>
)}
{/* QR Code */}
<div className="bg-white">
<QRCodeSVG
value={generateTeamsLink()}
size={240}
level="M"
includeMargin={false}
fgColor={qrColor}
/>
</div>
{/* Teams Info */}
<div className="mt-6 text-center max-w-[260px]">
<h3 className="font-bold text-slate-900 text-lg flex items-center justify-center gap-2">
{linkType === 'meeting' ? (
<Video className="w-4 h-4 text-[#6264A7] shrink-0" />
) : (
<MessageCircle className="w-4 h-4 text-[#6264A7] shrink-0" />
)}
<span className="truncate">
{linkType === 'meeting' ? 'Teams Meeting' : (userEmail || 'Teams Chat')}
</span>
</h3>
<p className="text-sm text-slate-600 mt-1">
{linkType === 'meeting' ? 'Join Meeting' : 'Start Chat'}
</p>
</div>
</div>
{/* Download Buttons */}
<div className="flex items-center gap-3 mt-8">
<Button
onClick={() => handleDownload('png')}
className="bg-[#6264A7] hover:bg-[#464775] text-white shadow-lg"
>
<Download className="w-4 h-4 mr-2" />
Download PNG
</Button>
<Button
onClick={() => handleDownload('svg')}
variant="outline"
className="border-slate-300 hover:bg-white"
>
<Download className="w-4 h-4 mr-2" />
SVG
</Button>
</div>
<p className="text-xs text-slate-600 mt-4 text-center">
Works with Microsoft Teams desktop and mobile apps.
</p>
</div>
</div>
</div>
{/* Upsell Banner */}
<div className="mt-8 bg-gradient-to-r from-[#6264A7] to-[#464775] rounded-2xl p-6 flex flex-col sm:flex-row items-center justify-between gap-4">
<div className="text-white text-center sm:text-left">
<h3 className="font-bold text-lg">Need to update meeting links?</h3>
<p className="text-white/80 text-sm mt-1">Dynamic QR Codes let you change the destination without reprinting.</p>
</div>
<Link href="/signup">
<Button className="bg-white text-[#6264A7] hover:bg-slate-100 shrink-0 shadow-lg">
Create Dynamic QR
</Button>
</Link>
</div>
</div>
);
}
'use client';
import React, { useState, useRef } from 'react';
import Link from 'next/link';
import { QRCodeSVG } from 'qrcode.react';
import {
Users,
Download,
Check,
Sparkles,
Video,
MessageCircle
} from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { cn } from '@/lib/utils';
// Brand Colors - Microsoft Teams Purple
const BRAND = {
paleGrey: '#F3F2F1',
primary: '#6264A7',
primaryDark: '#464775',
};
// QR Color Options
const QR_COLORS = [
{ name: 'Teams Purple', value: '#6264A7' },
{ name: 'Teams Dark', value: '#464775' },
{ name: 'Classic Black', value: '#000000' },
{ name: 'Indigo', value: '#4F46E5' },
{ name: 'Violet', value: '#7C3AED' },
{ name: 'Emerald', value: '#10B981' },
{ name: 'Rose', value: '#F43F5E' },
];
// Frame Options
const FRAME_OPTIONS = [
{ id: 'none', label: 'No Frame' },
{ id: 'scanme', label: 'Scan Me' },
{ id: 'join', label: 'Join Meeting' },
{ id: 'teams', label: 'Teams' },
];
// Link Type Options
const LINK_TYPES = [
{ id: 'meeting', label: 'Meeting Link', icon: Video },
{ id: 'chat', label: 'Chat with User', icon: MessageCircle },
];
export default function TeamsGenerator() {
const [linkType, setLinkType] = useState('meeting');
const [meetingUrl, setMeetingUrl] = useState('');
const [userEmail, setUserEmail] = useState('');
const [qrColor, setQrColor] = useState(BRAND.primary);
const [frameType, setFrameType] = useState('none');
const qrRef = useRef<HTMLDivElement>(null);
// Generate Teams link
const generateTeamsLink = () => {
if (linkType === 'meeting') {
// If user pastes full Teams meeting URL, use it directly
if (meetingUrl.trim().includes('teams.microsoft.com') || meetingUrl.trim().includes('teams.live.com')) {
return meetingUrl.trim();
}
// Otherwise return placeholder
return meetingUrl.trim() || 'https://teams.microsoft.com';
} else {
// Chat link with email
if (!userEmail.trim()) return 'https://teams.microsoft.com';
return `https://teams.microsoft.com/l/chat/0/0?users=${encodeURIComponent(userEmail.trim())}`;
}
};
const handleDownload = async (format: 'png' | 'svg') => {
if (!qrRef.current) return;
try {
if (format === 'png') {
const { toPng } = await import('html-to-image');
const dataUrl = await toPng(qrRef.current, { cacheBust: true, pixelRatio: 3 });
const link = document.createElement('a');
link.download = `teams-qr-code.png`;
link.href = dataUrl;
link.click();
} else {
const svgData = qrRef.current.querySelector('svg')?.outerHTML;
if (svgData) {
const blob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `teams-qr-code.svg`;
link.click();
}
}
} catch (err) {
console.error('Download failed', err);
}
};
const getFrameLabel = () => {
const frame = FRAME_OPTIONS.find(f => f.id === frameType);
return frame?.id !== 'none' ? frame?.label : null;
};
return (
<div className="w-full max-w-5xl mx-auto px-4 md:px-6">
{/* Main Generator Card */}
<div className="bg-white rounded-3xl shadow-2xl shadow-slate-900/10 overflow-hidden border border-slate-100">
<div className="grid lg:grid-cols-2">
{/* LEFT: Input Section */}
<div className="p-6 md:p-8 lg:p-10 space-y-8 border-r border-slate-100">
{/* Teams Details */}
<div className="space-y-6">
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
<Users className="w-5 h-5 text-[#6264A7]" />
Microsoft Teams
</h2>
<div className="space-y-4">
{/* Link Type Toggle */}
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">What do you want to share?</label>
<div className="grid grid-cols-2 gap-3">
{LINK_TYPES.map((type) => (
<button
key={type.id}
onClick={() => setLinkType(type.id)}
className={cn(
"flex items-center justify-center gap-2 py-3 px-4 rounded-xl font-medium transition-all border",
linkType === type.id
? "bg-[#6264A7] text-white border-[#6264A7]"
: "bg-slate-50 text-slate-600 border-slate-200 hover:border-slate-300"
)}
>
<type.icon className="w-4 h-4" />
{type.label}
</button>
))}
</div>
</div>
{linkType === 'meeting' ? (
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Teams Meeting URL</label>
<Input
placeholder="Paste your Teams meeting link here"
value={meetingUrl}
onChange={(e) => setMeetingUrl(e.target.value)}
className="h-12 text-base rounded-xl border-slate-200 focus:border-[#6264A7] focus:ring-[#6264A7]"
/>
<p className="text-xs text-slate-600 mt-2">
Copy the meeting link from your Teams calendar invite.
</p>
</div>
) : (
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">User Email Address</label>
<Input
type="email"
placeholder="e.g. colleague@company.com"
value={userEmail}
onChange={(e) => setUserEmail(e.target.value)}
className="h-12 text-base rounded-xl border-slate-200 focus:border-[#6264A7] focus:ring-[#6264A7]"
/>
<p className="text-xs text-slate-600 mt-2">
The person's work email to start a Teams chat.
</p>
</div>
)}
</div>
</div>
<div className="border-t border-slate-100"></div>
{/* Design Options */}
<div className="space-y-6">
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
<Sparkles className="w-5 h-5 text-[#6264A7]" />
Design Options
</h2>
{/* Color Picker */}
<div>
<label className="block text-sm font-medium text-slate-700 mb-3">QR Code Color</label>
<div className="flex flex-wrap gap-2">
{QR_COLORS.map((c) => (
<button
key={c.name}
onClick={() => setQrColor(c.value)}
className={cn(
"w-9 h-9 rounded-full border-2 flex items-center justify-center transition-all hover:scale-110",
qrColor === c.value ? "border-slate-900 ring-2 ring-offset-2 ring-slate-200" : "border-white shadow-md"
)}
style={{ backgroundColor: c.value }}
aria-label={`Select ${c.name}`}
title={c.name}
>
{qrColor === c.value && <Check className="w-4 h-4 text-white" strokeWidth={3} />}
</button>
))}
</div>
</div>
{/* Frame Selector */}
<div>
<label className="block text-sm font-medium text-slate-700 mb-3">Frame Label</label>
<div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
{FRAME_OPTIONS.map((frame) => (
<button
key={frame.id}
onClick={() => setFrameType(frame.id)}
className={cn(
"py-2.5 px-2 rounded-lg text-xs font-medium transition-all border",
frameType === frame.id
? "bg-[#6264A7] text-white border-[#6264A7]"
: "bg-slate-50 text-slate-600 border-slate-200 hover:border-slate-300"
)}
>
{frame.label}
</button>
))}
</div>
</div>
</div>
</div>
{/* RIGHT: Preview Section */}
<div className="p-6 md:p-8 lg:p-10 flex flex-col items-center justify-center" style={{ backgroundColor: BRAND.paleGrey }}>
{/* QR Card with Frame */}
<div
ref={qrRef}
className="bg-white rounded-3xl shadow-xl p-6 sm:p-8 flex flex-col items-center w-full max-w-[320px]"
>
{/* Frame Label */}
{getFrameLabel() && (
<div
className="mb-5 px-8 py-2.5 rounded-full text-white font-bold text-sm tracking-widest uppercase shadow-md"
style={{ backgroundColor: qrColor }}
>
{getFrameLabel()}
</div>
)}
{/* QR Code */}
<div className="bg-white">
<QRCodeSVG
value={generateTeamsLink()}
size={240}
level="M"
includeMargin={false}
fgColor={qrColor}
/>
</div>
{/* Teams Info */}
<div className="mt-6 text-center max-w-[260px]">
<h3 className="font-bold text-slate-900 text-lg flex items-center justify-center gap-2">
{linkType === 'meeting' ? (
<Video className="w-4 h-4 text-[#6264A7] shrink-0" />
) : (
<MessageCircle className="w-4 h-4 text-[#6264A7] shrink-0" />
)}
<span className="truncate">
{linkType === 'meeting' ? 'Teams Meeting' : (userEmail || 'Teams Chat')}
</span>
</h3>
<p className="text-sm text-slate-600 mt-1">
{linkType === 'meeting' ? 'Join Meeting' : 'Start Chat'}
</p>
</div>
</div>
{/* Download Buttons */}
<div className="flex items-center gap-3 mt-8">
<Button
onClick={() => handleDownload('png')}
className="bg-[#6264A7] hover:bg-[#464775] text-white shadow-lg"
>
<Download className="w-4 h-4 mr-2" />
Download PNG
</Button>
<Button
onClick={() => handleDownload('svg')}
variant="outline"
className="border-slate-300 hover:bg-white"
>
<Download className="w-4 h-4 mr-2" />
SVG
</Button>
</div>
<p className="text-xs text-slate-600 mt-4 text-center">
Works with Microsoft Teams desktop and mobile apps.
</p>
</div>
</div>
</div>
{/* Upsell Banner */}
<div className="mt-8 bg-gradient-to-r from-[#6264A7] to-[#464775] rounded-2xl p-6 flex flex-col sm:flex-row items-center justify-between gap-4">
<div className="text-white text-center sm:text-left">
<h3 className="font-bold text-lg">Need to update meeting links?</h3>
<p className="text-white/80 text-sm mt-1">Dynamic QR Codes let you change the destination without reprinting.</p>
</div>
<Link href="/signup">
<Button className="bg-white text-[#6264A7] hover:bg-slate-100 shrink-0 shadow-lg">
Create Dynamic QR
</Button>
</Link>
</div>
</div>
);
}

View File

@@ -1,308 +1,308 @@
import React from 'react';
import type { Metadata } from 'next';
import TeamsGenerator from './TeamsGenerator';
import { Users, Shield, Zap, Video, MessageCircle, Download, Share2 } from 'lucide-react';
import { QRCodeSVG } from 'qrcode.react';
import { ToolBreadcrumb } from '@/components/seo/BreadcrumbSchema';
import { RelatedTools } from '@/components/marketing/RelatedTools';
import { generateSoftwareAppSchema, generateFaqSchema } from '@/lib/schema-utils';
// SEO Optimized Metadata
export const metadata: Metadata = {
title: {
absolute: 'Free Microsoft Teams QR Code Generator | Join Meetings | QR Master',
},
description: 'Create a QR code for your Microsoft Teams meeting. Teams QR Code erstellen. Attendees scan to join instantly. For hybrid meetings & office displays.',
keywords: ['teams qr code', 'microsoft teams meeting qr', 'join teams qr code', 'meeting room qr', 'teams invitation qr', 'hybrid meeting qr code', 'microsoft teams qr code erstellen', 'teams meeting qr code', 'teams besprechung qr', 'teams beitreten qr'],
alternates: {
canonical: 'https://www.qrmaster.net/tools/teams-qr-code',
},
openGraph: {
title: 'Free Microsoft Teams QR Code Generator | QR Master',
description: 'Generate QR codes for Teams meetings. One scan to join instantly.',
type: 'website',
url: 'https://www.qrmaster.net/tools/teams-qr-code',
images: [{ url: '/og-teams-generator.png', width: 1200, height: 630 }],
},
twitter: {
card: 'summary_large_image',
title: 'Free Microsoft Teams QR Code Generator',
description: 'Create Teams meeting QR codes. Instant and free.',
},
robots: {
index: true,
follow: true,
},
};
// JSON-LD Structured Data
const jsonLd = {
'@context': 'https://schema.org',
'@graph': [
generateSoftwareAppSchema(
'Microsoft Teams QR Code Generator',
'Generate QR codes that let people join your Microsoft Teams meeting with one scan.',
'/og-teams-generator.png',
'BusinessApplication'
),
{
'@type': 'HowTo',
name: 'How to Create a Microsoft Teams QR Code',
description: 'Create a QR code for joining Teams meetings.',
step: [
{
'@type': 'HowToStep',
position: 1,
name: 'Copy Meeting Link',
text: 'Copy the Teams meeting URL from your calendar invitation.',
},
{
'@type': 'HowToStep',
position: 2,
name: 'Paste Link',
text: 'Paste the meeting link into the generator.',
},
{
'@type': 'HowToStep',
position: 3,
name: 'Customize',
text: 'Choose Teams colors and add a frame label.',
},
{
'@type': 'HowToStep',
position: 4,
name: 'Download',
text: 'Download your QR code and display it in your meeting room.',
},
],
totalTime: 'PT30S',
},
generateFaqSchema({
'What happens when someone scans the QR code?': {
question: 'What happens when someone scans the QR code?',
answer: 'Microsoft Teams opens and the user is prompted to join the meeting. Works on desktop, mobile, and web.',
},
'Does it work for recurring meetings?': {
question: 'Does it work for recurring meetings?',
answer: 'Yes! If your recurring meeting uses the same meeting link, the QR code will work for all sessions.',
},
'Can guests without Teams accounts join?': {
question: 'Can guests without Teams accounts join?',
answer: 'Yes. Guests can join Teams meetings via the web browser without needing a Microsoft account.',
},
'Is this for personal or business Teams?': {
question: 'Is this for personal or business Teams?',
answer: 'Both! Works with Microsoft Teams for work, school, and personal accounts.',
},
}),
],
};
export default function TeamsQRCodePage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<ToolBreadcrumb toolName="Teams QR Code Generator" toolSlug="teams-qr-code" />
<div className="min-h-screen" style={{ backgroundColor: '#EBEBDF' }}>
{/* HERO SECTION */}
<section className="relative pt-20 pb-20 lg:pt-32 lg:pb-32 px-4 sm:px-6 lg:px-8 overflow-hidden" style={{ backgroundColor: '#6264A7' }}>
<div className="absolute inset-0 opacity-10">
<svg className="w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none">
<path d="M0 100 C 20 0 50 0 100 100 Z" fill="url(#grad1)" />
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style={{ stopColor: 'white', stopOpacity: 1 }} />
<stop offset="100%" style={{ stopColor: 'white', stopOpacity: 0 }} />
</linearGradient>
</defs>
</svg>
</div>
<div className="max-w-7xl mx-auto grid lg:grid-cols-2 gap-12 items-center relative z-10">
<div className="text-center lg:text-left">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/10 text-white/90 text-sm font-medium mb-6 backdrop-blur-sm border border-white/10 hover:bg-white/20 transition-colors cursor-default">
<span className="flex h-2 w-2 relative">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-white opacity-75"></span>
<span className="relative inline-flex rounded-full h-2 w-2 bg-white"></span>
</span>
Free Tool No Signup Required
</div>
<h1 className="text-4xl md:text-5xl lg:text-6xl font-extrabold text-white tracking-tight leading-tight mb-6">
Join Meetings with <br className="hidden lg:block" />
<span className="text-transparent bg-clip-text bg-gradient-to-r from-violet-200 to-white">Teams QR Codes</span>
</h1>
<p className="text-lg md:text-xl text-violet-100 max-w-2xl mx-auto lg:mx-0 mb-8 leading-relaxed">
Create QR codes for Microsoft Teams meetings. Attendees scan to join instantly.
<strong className="text-white block sm:inline mt-2 sm:mt-0"> Perfect for hybrid workplaces.</strong>
</p>
<div className="flex flex-wrap justify-center lg:justify-start gap-4 text-sm font-medium text-white/80">
<div className="flex items-center gap-2 bg-white/5 px-4 py-2.5 rounded-xl border border-white/5 backdrop-blur-sm">
<Video className="w-4 h-4 text-white" />
Meeting Links
</div>
<div className="flex items-center gap-2 bg-white/5 px-4 py-2.5 rounded-xl border border-white/5 backdrop-blur-sm">
<MessageCircle className="w-4 h-4 text-white" />
Chat Links
</div>
<div className="flex items-center gap-2 bg-white/5 px-4 py-2.5 rounded-xl border border-white/5 backdrop-blur-sm">
<Zap className="w-4 h-4 text-amber-300" />
Instant Join
</div>
</div>
</div>
{/* Visual Abstract */}
<div className="hidden lg:flex relative items-center justify-center min-h-[400px]">
<div className="absolute w-[500px] h-[500px] bg-violet-400/30 rounded-full blur-[100px] -top-20 -right-20 animate-pulse" />
<div className="relative w-80 h-96 bg-white/5 backdrop-blur-xl border border-white/20 rounded-3xl shadow-2xl flex flex-col items-center justify-center p-8 transform rotate-3 hover:rotate-0 transition-all duration-700 group">
<div className="absolute inset-0 bg-gradient-to-br from-white/10 to-transparent rounded-3xl" />
{/* Meeting Card Mock */}
<div className="w-full bg-white rounded-xl shadow-lg p-4 mb-6 relative overflow-hidden">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-[#6264A7] rounded-lg flex items-center justify-center">
<Users className="w-5 h-5 text-white" />
</div>
<div>
<div className="font-bold text-slate-900 text-sm">Team Standup</div>
<div className="text-xs text-slate-600">Daily at 9:00 AM</div>
</div>
</div>
<div className="flex gap-2">
<div className="bg-green-100 text-green-700 text-xs px-2 py-1 rounded-full">Live Now</div>
<div className="bg-slate-100 text-slate-600 text-xs px-2 py-1 rounded-full">8 attending</div>
</div>
</div>
<div className="w-48 h-48 bg-white rounded-xl p-2 shadow-inner relative overflow-hidden flex items-center justify-center">
<QRCodeSVG value="https://www.qrmaster.net" size={170} fgColor="#6264A7" level="Q" />
</div>
{/* Floating Badge */}
<div className="absolute -bottom-6 -left-6 bg-white py-3 px-5 rounded-xl shadow-xl flex items-center gap-3 transform transition-transform hover:scale-105 duration-300">
<div className="bg-violet-100 p-2 rounded-full">
<Video className="w-5 h-5 text-[#6264A7]" />
</div>
<div className="text-left">
<div className="text-[10px] text-slate-400 font-bold uppercase tracking-wider">Status</div>
<div className="text-sm font-bold text-slate-900">Ready to Join</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* GENERATOR SECTION */}
<section className="py-12 px-4 sm:px-6 lg:px-8 -mt-8">
<TeamsGenerator />
</section>
{/* HOW IT WORKS */}
<section className="py-16 px-4 sm:px-6 lg:px-8 bg-white">
<div className="max-w-4xl mx-auto">
<h2 className="text-3xl font-bold text-slate-900 text-center mb-12">
How Teams QR Codes Work
</h2>
<div className="grid md:grid-cols-4 gap-8">
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Video className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">1. Get Link</h3>
<p className="text-slate-600 text-xs leading-relaxed">Copy your Teams meeting URL.</p>
</article>
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Shield className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">2. Paste</h3>
<p className="text-slate-600 text-xs leading-relaxed">Paste into the generator.</p>
</article>
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Download className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">3. Download</h3>
<p className="text-slate-600 text-xs leading-relaxed">Save your QR code.</p>
</article>
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Share2 className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">4. Display</h3>
<p className="text-slate-600 text-xs leading-relaxed">Put in meeting rooms or invites.</p>
</article>
</div>
</div>
</section>
{/* RELATED TOOLS */}
<RelatedTools />
{/* FAQ SECTION */}
<section className="py-16 px-4 sm:px-6 lg:px-8" style={{ backgroundColor: '#EBEBDF' }}>
<div className="max-w-3xl mx-auto">
<h2 className="text-3xl font-bold text-slate-900 text-center mb-4">
Frequently Asked Questions
</h2>
<p className="text-slate-600 text-center mb-10">
Common questions about Teams QR codes.
</p>
<div className="space-y-4">
<FaqItem
question="What happens when someone scans the QR code?"
answer="Microsoft Teams opens and the user is prompted to join the meeting. Works on desktop, mobile, and web browser."
/>
<FaqItem
question="Does it work for recurring meetings?"
answer="Yes! If your recurring meeting uses the same meeting link, the QR code will work for all sessions."
/>
<FaqItem
question="Can guests without Teams accounts join?"
answer="Yes. Guests can join Teams meetings via the web browser without needing a Microsoft account."
/>
<FaqItem
question="What about meeting rooms with digital displays?"
answer="Perfect for that! Display the QR code on your room's screen so attendees can scan to join from their devices."
/>
</div>
</div>
</section>
</div>
</>
);
}
function FaqItem({ question, answer }: { question: string; answer: string }) {
return (
<details className="group bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
<summary className="flex items-center justify-between p-5 cursor-pointer list-none text-slate-900 font-semibold hover:bg-slate-50 transition-colors">
{question}
<span className="transition group-open:rotate-180 text-slate-400">
<svg fill="none" height="20" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="20">
<path d="M6 9l6 6 6-6" />
</svg>
</span>
</summary>
<div className="text-slate-600 px-5 pb-5 pt-0 leading-relaxed text-sm">
{answer}
</div>
</details>
);
}
import React from 'react';
import type { Metadata } from 'next';
import TeamsGenerator from './TeamsGenerator';
import { Users, Shield, Zap, Video, MessageCircle, Download, Share2 } from 'lucide-react';
import { QRCodeSVG } from 'qrcode.react';
import { ToolBreadcrumb } from '@/components/seo/BreadcrumbSchema';
import { RelatedTools } from '@/components/marketing/RelatedTools';
import { generateSoftwareAppSchema, generateFaqSchema } from '@/lib/schema-utils';
// SEO Optimized Metadata
export const metadata: Metadata = {
title: {
absolute: 'Free Microsoft Teams QR Code Generator | Join Meetings | QR Master',
},
description: 'Create a QR code for your Microsoft Teams meeting. Teams QR Code erstellen. Attendees scan to join instantly. For hybrid meetings & office displays.',
keywords: ['teams qr code', 'microsoft teams meeting qr', 'join teams qr code', 'meeting room qr', 'teams invitation qr', 'hybrid meeting qr code', 'microsoft teams qr code erstellen', 'teams meeting qr code', 'teams besprechung qr', 'teams beitreten qr'],
alternates: {
canonical: 'https://www.qrmaster.net/tools/teams-qr-code',
},
openGraph: {
title: 'Free Microsoft Teams QR Code Generator | QR Master',
description: 'Generate QR codes for Teams meetings. One scan to join instantly.',
type: 'website',
url: 'https://www.qrmaster.net/tools/teams-qr-code',
images: [{ url: '/og-teams-generator.png', width: 1200, height: 630 }],
},
twitter: {
card: 'summary_large_image',
title: 'Free Microsoft Teams QR Code Generator',
description: 'Create Teams meeting QR codes. Instant and free.',
},
robots: {
index: true,
follow: true,
},
};
// JSON-LD Structured Data
const jsonLd = {
'@context': 'https://schema.org',
'@graph': [
generateSoftwareAppSchema(
'Microsoft Teams QR Code Generator',
'Generate QR codes that let people join your Microsoft Teams meeting with one scan.',
'/og-teams-generator.png',
'BusinessApplication'
),
{
'@type': 'HowTo',
name: 'How to Create a Microsoft Teams QR Code',
description: 'Create a QR code for joining Teams meetings.',
step: [
{
'@type': 'HowToStep',
position: 1,
name: 'Copy Meeting Link',
text: 'Copy the Teams meeting URL from your calendar invitation.',
},
{
'@type': 'HowToStep',
position: 2,
name: 'Paste Link',
text: 'Paste the meeting link into the generator.',
},
{
'@type': 'HowToStep',
position: 3,
name: 'Customize',
text: 'Choose Teams colors and add a frame label.',
},
{
'@type': 'HowToStep',
position: 4,
name: 'Download',
text: 'Download your QR code and display it in your meeting room.',
},
],
totalTime: 'PT30S',
},
generateFaqSchema({
'What happens when someone scans the QR code?': {
question: 'What happens when someone scans the QR code?',
answer: 'Microsoft Teams opens and the user is prompted to join the meeting. Works on desktop, mobile, and web.',
},
'Does it work for recurring meetings?': {
question: 'Does it work for recurring meetings?',
answer: 'Yes! If your recurring meeting uses the same meeting link, the QR code will work for all sessions.',
},
'Can guests without Teams accounts join?': {
question: 'Can guests without Teams accounts join?',
answer: 'Yes. Guests can join Teams meetings via the web browser without needing a Microsoft account.',
},
'Is this for personal or business Teams?': {
question: 'Is this for personal or business Teams?',
answer: 'Both! Works with Microsoft Teams for work, school, and personal accounts.',
},
}),
],
};
export default function TeamsQRCodePage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<ToolBreadcrumb toolName="Teams QR Code Generator" toolSlug="teams-qr-code" />
<div className="min-h-screen" style={{ backgroundColor: '#EBEBDF' }}>
{/* HERO SECTION */}
<section className="relative pt-20 pb-20 lg:pt-32 lg:pb-32 px-4 sm:px-6 lg:px-8 overflow-hidden" style={{ backgroundColor: '#6264A7' }}>
<div className="absolute inset-0 opacity-10">
<svg className="w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none">
<path d="M0 100 C 20 0 50 0 100 100 Z" fill="url(#grad1)" />
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style={{ stopColor: 'white', stopOpacity: 1 }} />
<stop offset="100%" style={{ stopColor: 'white', stopOpacity: 0 }} />
</linearGradient>
</defs>
</svg>
</div>
<div className="max-w-7xl mx-auto grid lg:grid-cols-2 gap-12 items-center relative z-10">
<div className="text-center lg:text-left">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/10 text-white/90 text-sm font-medium mb-6 backdrop-blur-sm border border-white/10 hover:bg-white/20 transition-colors cursor-default">
<span className="flex h-2 w-2 relative">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-white opacity-75"></span>
<span className="relative inline-flex rounded-full h-2 w-2 bg-white"></span>
</span>
Free Tool No Signup Required
</div>
<h1 className="text-4xl md:text-5xl lg:text-6xl font-extrabold text-white tracking-tight leading-tight mb-6">
Join Meetings with <br className="hidden lg:block" />
<span className="text-transparent bg-clip-text bg-gradient-to-r from-violet-200 to-white">Teams QR Codes</span>
</h1>
<p className="text-lg md:text-xl text-violet-100 max-w-2xl mx-auto lg:mx-0 mb-8 leading-relaxed">
Create QR codes for Microsoft Teams meetings. Attendees scan to join instantly.
<strong className="text-white block sm:inline mt-2 sm:mt-0"> Perfect for hybrid workplaces.</strong>
</p>
<div className="flex flex-wrap justify-center lg:justify-start gap-4 text-sm font-medium text-white/80">
<div className="flex items-center gap-2 bg-white/5 px-4 py-2.5 rounded-xl border border-white/5 backdrop-blur-sm">
<Video className="w-4 h-4 text-white" />
Meeting Links
</div>
<div className="flex items-center gap-2 bg-white/5 px-4 py-2.5 rounded-xl border border-white/5 backdrop-blur-sm">
<MessageCircle className="w-4 h-4 text-white" />
Chat Links
</div>
<div className="flex items-center gap-2 bg-white/5 px-4 py-2.5 rounded-xl border border-white/5 backdrop-blur-sm">
<Zap className="w-4 h-4 text-amber-300" />
Instant Join
</div>
</div>
</div>
{/* Visual Abstract */}
<div className="hidden lg:flex relative items-center justify-center min-h-[400px]">
<div className="absolute w-[500px] h-[500px] bg-violet-400/30 rounded-full blur-[100px] -top-20 -right-20 animate-pulse" />
<div className="relative w-80 h-96 bg-white/5 backdrop-blur-xl border border-white/20 rounded-3xl shadow-2xl flex flex-col items-center justify-center p-8 transform rotate-3 hover:rotate-0 transition-all duration-700 group">
<div className="absolute inset-0 bg-gradient-to-br from-white/10 to-transparent rounded-3xl" />
{/* Meeting Card Mock */}
<div className="w-full bg-white rounded-xl shadow-lg p-4 mb-6 relative overflow-hidden">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-[#6264A7] rounded-lg flex items-center justify-center">
<Users className="w-5 h-5 text-white" />
</div>
<div>
<div className="font-bold text-slate-900 text-sm">Team Standup</div>
<div className="text-xs text-slate-600">Daily at 9:00 AM</div>
</div>
</div>
<div className="flex gap-2">
<div className="bg-green-100 text-green-700 text-xs px-2 py-1 rounded-full">Live Now</div>
<div className="bg-slate-100 text-slate-600 text-xs px-2 py-1 rounded-full">8 attending</div>
</div>
</div>
<div className="w-48 h-48 bg-white rounded-xl p-2 shadow-inner relative overflow-hidden flex items-center justify-center">
<QRCodeSVG value="https://www.qrmaster.net" size={170} fgColor="#6264A7" level="Q" />
</div>
{/* Floating Badge */}
<div className="absolute -bottom-6 -left-6 bg-white py-3 px-5 rounded-xl shadow-xl flex items-center gap-3 transform transition-transform hover:scale-105 duration-300">
<div className="bg-violet-100 p-2 rounded-full">
<Video className="w-5 h-5 text-[#6264A7]" />
</div>
<div className="text-left">
<div className="text-[10px] text-slate-400 font-bold uppercase tracking-wider">Status</div>
<div className="text-sm font-bold text-slate-900">Ready to Join</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* GENERATOR SECTION */}
<section className="py-12 px-4 sm:px-6 lg:px-8 -mt-8">
<TeamsGenerator />
</section>
{/* HOW IT WORKS */}
<section className="py-16 px-4 sm:px-6 lg:px-8 bg-white">
<div className="max-w-4xl mx-auto">
<h2 className="text-3xl font-bold text-slate-900 text-center mb-12">
How Teams QR Codes Work
</h2>
<div className="grid md:grid-cols-4 gap-8">
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Video className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">1. Get Link</h3>
<p className="text-slate-600 text-xs leading-relaxed">Copy your Teams meeting URL.</p>
</article>
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Shield className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">2. Paste</h3>
<p className="text-slate-600 text-xs leading-relaxed">Paste into the generator.</p>
</article>
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Download className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">3. Download</h3>
<p className="text-slate-600 text-xs leading-relaxed">Save your QR code.</p>
</article>
<article className="text-center">
<div className="w-12 h-12 rounded-2xl bg-[#6264A7]/10 flex items-center justify-center mx-auto mb-4">
<Share2 className="w-6 h-6 text-[#6264A7]" />
</div>
<h3 className="font-bold text-slate-900 mb-2">4. Display</h3>
<p className="text-slate-600 text-xs leading-relaxed">Put in meeting rooms or invites.</p>
</article>
</div>
</div>
</section>
{/* RELATED TOOLS */}
<RelatedTools />
{/* FAQ SECTION */}
<section className="py-16 px-4 sm:px-6 lg:px-8" style={{ backgroundColor: '#EBEBDF' }}>
<div className="max-w-3xl mx-auto">
<h2 className="text-3xl font-bold text-slate-900 text-center mb-4">
Frequently Asked Questions
</h2>
<p className="text-slate-600 text-center mb-10">
Common questions about Teams QR codes.
</p>
<div className="space-y-4">
<FaqItem
question="What happens when someone scans the QR code?"
answer="Microsoft Teams opens and the user is prompted to join the meeting. Works on desktop, mobile, and web browser."
/>
<FaqItem
question="Does it work for recurring meetings?"
answer="Yes! If your recurring meeting uses the same meeting link, the QR code will work for all sessions."
/>
<FaqItem
question="Can guests without Teams accounts join?"
answer="Yes. Guests can join Teams meetings via the web browser without needing a Microsoft account."
/>
<FaqItem
question="What about meeting rooms with digital displays?"
answer="Perfect for that! Display the QR code on your room's screen so attendees can scan to join from their devices."
/>
</div>
</div>
</section>
</div>
</>
);
}
function FaqItem({ question, answer }: { question: string; answer: string }) {
return (
<details className="group bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
<summary className="flex items-center justify-between p-5 cursor-pointer list-none text-slate-900 font-semibold hover:bg-slate-50 transition-colors">
{question}
<span className="transition group-open:rotate-180 text-slate-400">
<svg fill="none" height="20" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" width="20">
<path d="M6 9l6 6 6-6" />
</svg>
</span>
</summary>
<div className="text-slate-600 px-5 pb-5 pt-0 leading-relaxed text-sm">
{answer}
</div>
</details>
);
}