feat(web): add 7 new SEO-optimized pages for organic traffic (#236)

New Pages Added:
- /changelog/ - Release history showing project growth
- /faq/ - SEO-optimized FAQ with JSON-LD schema
- /privacy/ - Privacy policy (trust signal for voice software)
- /shortcuts/ - Keyboard shortcuts and voice commands reference
- /troubleshooting/ - Common issues and solutions
- /use-cases/ - Target audience pages (developers, writers, students, accessibility)
- /alternatives/ - Comparison vs Dragon, Otter.ai, Google Voice Typing

Changes:
- Updated SeoSubpageShell navigation with new pages
- Updated sitemap.xml with all new URLs
- Updated homepage footer with links to new pages
- All pages include proper metadata, JSON-LD schema, and internal linking

SEO Improvements:
- FAQ page with FAQPage schema for rich snippets
- Comparison pages for high-intent keywords
- Use case pages targeting specific audiences
- Privacy page as trust signal for voice software
This commit is contained in:
Jatin K Malik
2026-02-19 00:15:52 -08:00
committed by GitHub
parent d7d91a7db2
commit df97164c47
11 changed files with 1800 additions and 18 deletions
-1
View File
@@ -1,6 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./out/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
+48 -6
View File
@@ -2,37 +2,79 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://vocalinux.com/</loc>
<lastmod>2026-02-12</lastmod>
<lastmod>2026-02-19</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://vocalinux.com/install/</loc>
<lastmod>2026-02-12</lastmod>
<lastmod>2026-02-19</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://vocalinux.com/install/ubuntu/</loc>
<lastmod>2026-02-12</lastmod>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://vocalinux.com/install/fedora/</loc>
<lastmod>2026-02-12</lastmod>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://vocalinux.com/install/arch/</loc>
<lastmod>2026-02-12</lastmod>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://vocalinux.com/compare/</loc>
<lastmod>2026-02-12</lastmod>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://vocalinux.com/changelog/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://vocalinux.com/faq/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://vocalinux.com/privacy/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://vocalinux.com/shortcuts/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://vocalinux.com/troubleshooting/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://vocalinux.com/use-cases/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://vocalinux.com/alternatives/</loc>
<lastmod>2026-02-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
+260
View File
@@ -0,0 +1,260 @@
import Link from "next/link";
import { type Metadata } from "next";
import { CheckCircle2, ChevronRight, Cloud, DollarSign, Lock, Server, Shield, XCircle, Zap } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const alternatives = [
{
name: "Dragon Naturally Speaking",
type: "Proprietary Desktop",
pros: ["High accuracy", "Industry standard", "Advanced commands"],
cons: ["No Linux support", "Expensive subscription", "Closed source", "Cloud dependency"],
pricing: "$500/year+",
},
{
name: "Otter.ai",
type: "Cloud Service",
pros: ["Good accuracy", "Meeting transcription", "Collaboration features"],
cons: ["Cloud-only (no offline)", "Subscription required", "Privacy concerns", "No Linux desktop app"],
pricing: "$10-30/month",
},
{
name: "Google Voice Typing",
type: "Cloud Service",
pros: ["Free", "Good accuracy", "Multi-language"],
cons: ["Requires Chrome/Google Docs", "Cloud-only", "Privacy concerns", "No Linux desktop integration"],
pricing: "Free",
},
{
name: "Speechnotes",
type: "Web App",
pros: ["Free tier available", "Simple to use", "No installation"],
cons: ["Browser-only", "Limited offline support", "No desktop integration", "Privacy concerns"],
pricing: "$10/month pro",
},
{
name: "Windows Voice Typing",
type: "OS Built-in",
pros: ["Free", "Integrated with Windows", "Decent accuracy"],
cons: ["Windows only", "No Linux support", "Limited customization", "Cloud processing"],
pricing: "Free (Windows only)",
},
];
const comparisonTable = [
{ feature: "Linux Support", vocalinux: true, dragon: false, otter: false, google: true },
{ feature: "100% Offline", vocalinux: true, dragon: false, otter: false, google: false },
{ feature: "Open Source", vocalinux: true, dragon: false, otter: false, google: false },
{ feature: "Free Forever", vocalinux: true, dragon: false, otter: false, google: true },
{ feature: "Desktop Integration", vocalinux: true, dragon: true, otter: false, google: false },
{ feature: "Wayland Support", vocalinux: true, dragon: false, otter: false, google: false },
{ feature: "Custom Shortcuts", vocalinux: true, dragon: true, otter: false, google: false },
{ feature: "Voice Commands", vocalinux: true, dragon: true, otter: true, google: true },
{ feature: "Multi-language", vocalinux: true, dragon: true, otter: true, google: true },
{ feature: "GPU Acceleration", vocalinux: true, dragon: false, otter: false, google: false },
];
export const metadata: Metadata = buildPageMetadata({
title: "Vocalinux Alternatives - Linux Voice Dictation Comparison",
description:
"Compare Vocalinux to Dragon, Otter.ai, Google Voice Typing, and other speech-to-text alternatives. See why Vocalinux is the best choice for Linux voice dictation.",
path: "/alternatives",
keywords: [
"vocalinux alternatives",
"dragon naturally speaking linux alternative",
"otter.ai alternative",
"linux speech to text comparison",
"offline voice dictation",
],
});
export default function AlternativesPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Vocalinux vs Dragon, Otter, Google - Voice Dictation Comparison",
description:
"Comprehensive comparison of Vocalinux with other voice dictation solutions for Linux users.",
dateModified: "2026-02-19",
author: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
publisher: {
"@type": "Organization",
name: "Vocalinux",
logo: {
"@type": "ImageObject",
url: absoluteUrl("/vocalinux.png"),
},
},
mainEntityOfPage: absoluteUrl("/alternatives"),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-sm font-medium text-primary">
<Zap className="h-4 w-4" />
Comparison
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Vocalinux vs The Alternatives
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Looking for voice dictation on Linux? Compare Vocalinux with Dragon, Otter.ai, Google Voice
Typing, and other alternatives. See why Vocalinux is the best choice for Linux users.
</p>
</section>
<section className="mb-12 rounded-2xl border border-primary/20 bg-primary/5 p-6">
<h2 className="mb-4 text-xl font-bold">Why Vocalinux for Linux?</h2>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<div className="flex items-center gap-3">
<Lock className="h-5 w-5 text-primary" />
<span className="font-medium">100% Offline</span>
</div>
<div className="flex items-center gap-3">
<Shield className="h-5 w-5 text-primary" />
<span className="font-medium">Privacy First</span>
</div>
<div className="flex items-center gap-3">
<DollarSign className="h-5 w-5 text-primary" />
<span className="font-medium">Free Forever</span>
</div>
<div className="flex items-center gap-3">
<Server className="h-5 w-5 text-primary" />
<span className="font-medium">Linux Native</span>
</div>
</div>
</section>
<section className="mb-12 rounded-2xl border border-zinc-200 bg-white p-6 overflow-x-auto dark:border-zinc-700 dark:bg-zinc-800">
<h2 className="mb-6 text-2xl font-bold">Feature Comparison</h2>
<table className="w-full min-w-[600px] text-left">
<thead>
<tr className="border-b border-zinc-200 dark:border-zinc-700">
<th className="pb-3 text-sm font-semibold">Feature</th>
<th className="pb-3 text-sm font-semibold">Vocalinux</th>
<th className="pb-3 text-sm font-semibold">Dragon</th>
<th className="pb-3 text-sm font-semibold">Otter.ai</th>
<th className="pb-3 text-sm font-semibold">Google</th>
</tr>
</thead>
<tbody className="text-sm">
{comparisonTable.map((row) => (
<tr key={row.feature} className="border-b border-zinc-100 dark:border-zinc-700/70">
<td className="py-3 font-medium">{row.feature}</td>
<td className="py-3">
{row.vocalinux ? (
<CheckCircle2 className="h-5 w-5 text-green-500" />
) : (
<XCircle className="h-5 w-5 text-red-500" />
)}
</td>
<td className="py-3">
{row.dragon ? (
<CheckCircle2 className="h-5 w-5 text-green-500" />
) : (
<XCircle className="h-5 w-5 text-red-500" />
)}
</td>
<td className="py-3">
{row.otter ? (
<CheckCircle2 className="h-5 w-5 text-green-500" />
) : (
<XCircle className="h-5 w-5 text-red-500" />
)}
</td>
<td className="py-3">
{row.google ? (
<CheckCircle2 className="h-5 w-5 text-green-500" />
) : (
<XCircle className="h-5 w-5 text-red-500" />
)}
</td>
</tr>
))}
</tbody>
</table>
</section>
<section className="space-y-6">
<h2 className="text-2xl font-bold">Detailed Comparison</h2>
{alternatives.map((alt) => (
<article
key={alt.name}
className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800"
>
<div className="mb-4 flex flex-wrap items-center justify-between gap-4">
<div>
<h3 className="text-xl font-bold">{alt.name}</h3>
<p className="text-sm text-muted-foreground">{alt.type}</p>
</div>
<span className="rounded-full bg-zinc-100 px-3 py-1 text-sm font-medium dark:bg-zinc-700">
{alt.pricing}
</span>
</div>
<div className="grid gap-4 md:grid-cols-2">
<div className="rounded-lg bg-green-50 p-4 dark:bg-green-900/20">
<p className="mb-2 text-sm font-semibold text-green-700 dark:text-green-400">Pros</p>
<ul className="space-y-1">
{alt.pros.map((pro) => (
<li key={pro} className="flex items-center gap-2 text-sm text-green-600 dark:text-green-300">
<CheckCircle2 className="h-3.5 w-3.5" />
{pro}
</li>
))}
</ul>
</div>
<div className="rounded-lg bg-red-50 p-4 dark:bg-red-900/20">
<p className="mb-2 text-sm font-semibold text-red-700 dark:text-red-400">Cons</p>
<ul className="space-y-1">
{alt.cons.map((con) => (
<li key={con} className="flex items-center gap-2 text-sm text-red-600 dark:text-red-300">
<XCircle className="h-3.5 w-3.5" />
{con}
</li>
))}
</ul>
</div>
</div>
</article>
))}
</section>
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-4 text-2xl font-bold">The Bottom Line</h2>
<p className="mb-6 text-muted-foreground">
If you're on Linux and need voice dictation, Vocalinux is the only option that offers
offline processing, privacy, and full desktop integration at no cost.
</p>
<div className="flex flex-wrap gap-4">
<Link
href="/install/"
className="inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground hover:bg-primary/90"
>
Install Vocalinux
<ChevronRight className="h-4 w-4" />
</Link>
<Link
href="/privacy/"
className="inline-flex items-center gap-2 rounded-lg border border-zinc-300 bg-white px-4 py-2 text-sm font-semibold hover:bg-zinc-50 dark:border-zinc-600 dark:bg-zinc-800 dark:hover:bg-zinc-700"
>
<Lock className="h-4 w-4" />
Our Privacy Commitment
</Link>
</div>
</section>
</SeoSubpageShell>
);
}
+246
View File
@@ -0,0 +1,246 @@
import Link from "next/link";
import { type Metadata } from "next";
import { BookOpen, CheckCircle2, ChevronRight, Clock, Download, Sparkles, Tag, Zap } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const releases = [
{
version: "v0.6.3-beta",
date: "2026-02-19",
type: "beta",
highlights: [
"Fixed installer default tag pointing to correct version",
"Added missing psutil dependency for fresh installs",
"Process check and interactive prompts in install/uninstall",
"Removed leading space from first speech transcription",
],
},
{
version: "v0.6.2-beta",
date: "2026-02-18",
type: "beta",
highlights: [
"Interactive backend selection (GPU/CPU)",
"Enhanced welcome message",
"Simplified install commands",
"Better GPU support and Vulkan detection",
],
},
{
version: "v0.6.0-beta",
date: "2026-02-12",
type: "beta",
highlights: [
"whisper.cpp as default engine",
"Multi-language support with auto-detection",
"System tray indicator",
"Full Wayland support",
"IBus text injection engine",
],
},
{
version: "v0.5.0-beta",
date: "2026-02-06",
type: "beta",
highlights: [
"First beta release",
"Stable core functionality",
"Multiple speech engine support",
"Improved text injection",
],
},
{
version: "v0.4.1-alpha",
date: "2026-01-29",
type: "alpha",
highlights: [
"Language selector UI",
"App drawer launch fix",
"Better commit handling",
"Improved update mechanism",
],
},
{
version: "v0.4.0-alpha",
date: "2026-01-29",
type: "alpha",
highlights: [
"Multi-language support (French, German, Russian)",
"Debian 13+ compatibility",
"Python 3.12+ support",
"Tag-based version selection in installer",
],
},
{
version: "v0.3.0-alpha",
date: "2026-01-21",
type: "alpha",
highlights: [
"Initial public alpha",
"Basic speech recognition",
"X11 text injection",
"VOSK engine support",
],
},
];
const getTypeStyles = (type: string) => {
switch (type) {
case "stable":
return {
badge: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
label: "Stable",
};
case "beta":
return {
badge: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400",
label: "Beta",
};
case "alpha":
return {
badge: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",
label: "Alpha",
};
default:
return {
badge: "bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-400",
label: type,
};
}
};
export const metadata: Metadata = buildPageMetadata({
title: "Vocalinux Changelog - Release History",
description:
"Track Vocalinux release history and version updates. See what's new in each version of our Linux voice dictation software.",
path: "/changelog",
keywords: [
"vocalinux changelog",
"vocalinux release notes",
"voice dictation linux updates",
"speech to text linux versions",
],
});
export default function ChangelogPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Vocalinux Changelog - Release History",
description:
"Complete release history for Vocalinux, the offline voice dictation software for Linux.",
dateModified: "2026-02-19",
author: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
publisher: {
"@type": "Organization",
name: "Vocalinux",
logo: {
"@type": "ImageObject",
url: absoluteUrl("/vocalinux.png"),
},
},
mainEntityOfPage: absoluteUrl("/changelog"),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-sm font-medium text-primary">
<Clock className="h-4 w-4" />
Release History
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Vocalinux Changelog
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Track every release and see how Vocalinux has evolved. From initial alpha to stable
releases, follow the journey of Linux voice dictation.
</p>
</section>
<section className="space-y-6">
{releases.map((release, index) => {
const styles = getTypeStyles(release.type);
return (
<article
key={release.version}
className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800"
>
<div className="mb-4 flex flex-wrap items-center gap-3">
<div className="flex items-center gap-2">
<Tag className="h-5 w-5 text-primary" />
<span className="text-2xl font-bold">{release.version}</span>
</div>
<span
className={`rounded-full px-3 py-1 text-xs font-semibold ${styles.badge}`}
>
{styles.label}
</span>
{index === 0 && (
<span className="rounded-full bg-primary/10 px-3 py-1 text-xs font-semibold text-primary">
Latest
</span>
)}
<span className="text-sm text-muted-foreground">{release.date}</span>
</div>
<ul className="space-y-2">
{release.highlights.map((highlight) => (
<li key={highlight} className="inline-flex items-start gap-2 text-muted-foreground">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
{highlight}
</li>
))}
</ul>
<div className="mt-4 pt-4 border-t border-zinc-100 dark:border-zinc-700">
<a
href={`https://github.com/jatinkrmalik/vocalinux/releases/tag/${release.version}`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline"
>
<Download className="h-4 w-4" />
View release on GitHub
<ChevronRight className="h-4 w-4" />
</a>
</div>
</article>
);
})}
</section>
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-4 text-2xl font-bold">Stay Updated</h2>
<ul className="space-y-3 text-muted-foreground">
<li className="inline-flex items-center gap-2">
<Sparkles className="h-4 w-4 text-primary" />
Watch the repository on GitHub for release notifications
</li>
<li className="inline-flex items-center gap-2">
<Zap className="h-4 w-4 text-primary" />
Re-run the installer to update to the latest version
</li>
<li className="inline-flex items-center gap-2">
<BookOpen className="h-4 w-4 text-primary" />
Check the{" "}
<Link href="/install/" className="font-semibold text-primary hover:underline">
install guide
</Link>{" "}
for update instructions
</li>
</ul>
</section>
</SeoSubpageShell>
);
}
+223
View File
@@ -0,0 +1,223 @@
import Link from "next/link";
import { type Metadata } from "next";
import { BookOpen, ChevronRight, CircleHelp, Cpu, Laptop, Lock, Mic, Volume2, Zap } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const faqCategories = [
{
category: "Getting Started",
icon: Zap,
iconColor: "text-amber-500",
questions: [
{
q: "How do I install Vocalinux?",
a: "Run the one-liner installer: curl -fsSL https://raw.githubusercontent.com/jatinkrmalik/vocalinux/main/install.sh | bash. The installer handles all dependencies and configuration automatically.",
},
{
q: "Which Linux distributions are supported?",
a: "Vocalinux works on Ubuntu 22.04+, Fedora 39+, Arch Linux, Manjaro, Debian, and most other Linux distributions. See our install guides for distro-specific instructions.",
},
{
q: "What are the system requirements?",
a: "You need Python 3.8+, a working microphone, and about 500MB of disk space. For GPU acceleration with whisper.cpp, you need Vulkan support (AMD, Intel, or NVIDIA).",
},
],
},
{
category: "Privacy & Security",
icon: Lock,
iconColor: "text-green-500",
questions: [
{
q: "Is Vocalinux really 100% offline?",
a: "Yes. All speech recognition runs locally on your Linux machine. Your voice data never leaves your computer. No internet connection is required after installation.",
},
{
q: "Does Vocalinux send any data to external servers?",
a: "No. Vocalinux does not collect, transmit, or store any voice data externally. Everything is processed locally using open-source speech recognition engines.",
},
{
q: "Is my voice data stored anywhere?",
a: "Only temporarily during transcription. Audio is processed in real-time and discarded immediately. No voice recordings are saved to disk.",
},
],
},
{
category: "Speech Recognition",
icon: Mic,
iconColor: "text-blue-500",
questions: [
{
q: "Which speech recognition engines are available?",
a: "Vocalinux supports three engines: whisper.cpp (default, fastest), OpenAI Whisper (high accuracy), and VOSK (lightweight for older hardware).",
},
{
q: "How accurate is the transcription?",
a: "Accuracy depends on the engine and model size. whisper.cpp with medium or large models provides excellent accuracy for English and 99+ other languages.",
},
{
q: "Can I use Vocalinux in languages other than English?",
a: "Yes! whisper.cpp and Whisper support 99+ languages with automatic language detection. VOSK supports several languages with separate models.",
},
],
},
{
category: "Usage & Features",
icon: Volume2,
iconColor: "text-violet-500",
questions: [
{
q: "How do I start and stop dictation?",
a: "Double-tap the Ctrl key to toggle dictation on/off. You can customize this shortcut in the settings panel.",
},
{
q: "Does Vocalinux work with Wayland?",
a: "Yes! Vocalinux supports both X11 and Wayland through IBus text injection. The installer automatically configures the right backend for your system.",
},
{
q: "Can I use voice commands?",
a: "Yes. Vocalinux supports voice commands like 'new line', 'delete that', 'select all', and more. Commands are processed in real-time.",
},
],
},
{
category: "Performance",
icon: Cpu,
iconColor: "text-cyan-500",
questions: [
{
q: "How much RAM does Vocalinux need?",
a: "Minimum 4GB RAM for basic use. For larger models, 8GB+ recommended. VOSK is the most memory-efficient option for systems with limited RAM.",
},
{
q: "Can I use GPU acceleration?",
a: "Yes! whisper.cpp supports GPU acceleration via Vulkan, which works with AMD, Intel, and NVIDIA GPUs. The installer auto-detects your hardware.",
},
{
q: "What model size should I use?",
a: "Start with 'tiny' for fastest performance, 'base' or 'small' for good balance, or 'medium'/'large' for best accuracy. Larger models need more RAM.",
},
],
},
];
export const metadata: Metadata = buildPageMetadata({
title: "Frequently Asked Questions - Vocalinux Voice Dictation",
description:
"Get answers to common questions about Vocalinux Linux voice dictation. Learn about installation, privacy, features, and troubleshooting.",
path: "/faq",
keywords: [
"vocalinux faq",
"linux voice dictation help",
"speech to text linux questions",
"offline dictation faq",
],
});
export default function FaqPage() {
const faqJsonLd = {
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: faqCategories.flatMap((cat) =>
cat.questions.map((q) => ({
"@type": "Question",
name: q.q,
acceptedAnswer: {
"@type": "Answer",
text: q.a,
},
}))
),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-sm font-medium text-primary">
<CircleHelp className="h-4 w-4" />
Help Center
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Frequently Asked Questions
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Find answers to common questions about Vocalinux. From installation to advanced features,
we've got you covered.
</p>
</section>
<section className="space-y-8">
{faqCategories.map((category) => {
const Icon = category.icon;
return (
<article
key={category.category}
className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800"
>
<h2 className="mb-6 flex items-center gap-3 text-2xl font-bold">
<span className={`rounded-xl bg-zinc-100 p-2 dark:bg-zinc-700`}>
<Icon className={`h-5 w-5 ${category.iconColor}`} />
</span>
{category.category}
</h2>
<div className="space-y-6">
{category.questions.map((item, index) => (
<div key={index} className="border-b border-zinc-100 pb-6 last:border-0 last:pb-0 dark:border-zinc-700">
<h3 className="mb-2 text-lg font-semibold">{item.q}</h3>
<p className="text-muted-foreground">{item.a}</p>
</div>
))}
</div>
</article>
);
})}
</section>
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-4 text-2xl font-bold">Still have questions?</h2>
<ul className="space-y-3 text-muted-foreground">
<li>
<span className="inline-flex items-center gap-2">
<Laptop className="h-4 w-4 text-primary" />
Check the{" "}
<Link href="/install/" className="font-semibold text-primary hover:underline">
install guide
</Link>{" "}
for setup help
</span>
</li>
<li>
<span className="inline-flex items-center gap-2">
<BookOpen className="h-4 w-4 text-primary" />
See the{" "}
<Link href="/troubleshooting/" className="font-semibold text-primary hover:underline">
troubleshooting guide
</Link>{" "}
for common issues
</span>
</li>
<li>
<span className="inline-flex items-center gap-2">
<ChevronRight className="h-4 w-4 text-primary" />
<a
href="https://github.com/jatinkrmalik/vocalinux/issues"
target="_blank"
rel="noopener noreferrer"
className="font-semibold text-primary hover:underline"
>
Open an issue on GitHub
</a>
</span>
</li>
</ul>
</section>
</SeoSubpageShell>
);
}
+35 -10
View File
@@ -1211,12 +1211,47 @@ export default function HomePage() {
Engine Comparison
</Link>
</li>
<li>
<Link href="/use-cases/" className="text-zinc-400 hover:text-white transition-colors">
Use Cases
</Link>
</li>
<li>
<Link href="/alternatives/" className="text-zinc-400 hover:text-white transition-colors">
Alternatives
</Link>
</li>
</ul>
</div>
<div>
<h3 className="font-semibold mb-4">Resources</h3>
<ul className="space-y-2 text-sm">
<li>
<Link href="/faq/" className="text-zinc-400 hover:text-white transition-colors">
FAQ
</Link>
</li>
<li>
<Link href="/changelog/" className="text-zinc-400 hover:text-white transition-colors">
Changelog
</Link>
</li>
<li>
<Link href="/shortcuts/" className="text-zinc-400 hover:text-white transition-colors">
Keyboard Shortcuts
</Link>
</li>
<li>
<Link href="/troubleshooting/" className="text-zinc-400 hover:text-white transition-colors">
Troubleshooting
</Link>
</li>
<li>
<Link href="/privacy/" className="text-zinc-400 hover:text-white transition-colors">
Privacy Policy
</Link>
</li>
<li>
<a
href="https://github.com/jatinkrmalik/vocalinux"
@@ -1247,16 +1282,6 @@ export default function HomePage() {
Discussions
</a>
</li>
<li>
<Link href="/install/" className="text-zinc-400 hover:text-white transition-colors">
Setup by Distribution
</Link>
</li>
<li>
<Link href="/compare/" className="text-zinc-400 hover:text-white transition-colors">
whisper.cpp vs Whisper vs VOSK
</Link>
</li>
<li>
<a
href="https://github.com/jatinkrmalik/vocalinux/blob/main/CONTRIBUTING.md"
+263
View File
@@ -0,0 +1,263 @@
import Link from "next/link";
import { type Metadata } from "next";
import { CheckCircle2, Lock, Server, Shield, Eye, Database, ExternalLink } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
export const metadata: Metadata = buildPageMetadata({
title: "Privacy Policy - 100% Offline Voice Dictation",
description:
"Vocalinux is 100% offline. Your voice data never leaves your computer. Learn about our privacy-first approach to Linux voice dictation.",
path: "/privacy",
keywords: [
"vocalinux privacy",
"offline voice dictation privacy",
"speech to text data privacy",
"linux dictation security",
],
});
export default function PrivacyPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Vocalinux Privacy Policy - 100% Offline Voice Dictation",
description:
"Complete privacy policy for Vocalinux, the offline voice dictation software for Linux.",
dateModified: "2026-02-19",
author: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
publisher: {
"@type": "Organization",
name: "Vocalinux",
logo: {
"@type": "ImageObject",
url: absoluteUrl("/vocalinux.png"),
},
},
mainEntityOfPage: absoluteUrl("/privacy"),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-green-500/30 bg-green-500/10 px-4 py-1.5 text-sm font-medium text-green-600 dark:text-green-400">
<Shield className="h-4 w-4" />
Privacy First
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Your Voice Stays on Your Computer
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Vocalinux is built from the ground up for privacy. All speech recognition happens locally,
with zero cloud processing. Your voice data never leaves your machine.
</p>
</section>
{/* Key Privacy Points */}
<section className="mb-12 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<article className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<div className="mb-4 inline-flex rounded-xl bg-green-100 p-3 dark:bg-green-900/30">
<Lock className="h-6 w-6 text-green-600 dark:text-green-400" />
</div>
<h3 className="mb-2 text-xl font-semibold">100% Offline</h3>
<p className="text-sm text-muted-foreground">
No internet connection required after installation. All processing happens on your
device, period.
</p>
</article>
<article className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<div className="mb-4 inline-flex rounded-xl bg-blue-100 p-3 dark:bg-blue-900/30">
<Server className="h-6 w-6 text-blue-600 dark:text-blue-400" />
</div>
<h3 className="mb-2 text-xl font-semibold">No Cloud Processing</h3>
<p className="text-sm text-muted-foreground">
Unlike Dragon, Otter, or Google Dictation, we don't send your voice to any servers.
Everything stays local.
</p>
</article>
<article className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<div className="mb-4 inline-flex rounded-xl bg-violet-100 p-3 dark:bg-violet-900/30">
<Eye className="h-6 w-6 text-violet-600 dark:text-violet-400" />
</div>
<h3 className="mb-2 text-xl font-semibold">Open Source</h3>
<p className="text-sm text-muted-foreground">
Fully open source under GPL-3.0. Inspect the code yourself on GitHub. No hidden
telemetry or data collection.
</p>
</article>
</section>
{/* Detailed Privacy Sections */}
<section className="space-y-8">
<article className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<h2 className="mb-4 flex items-center gap-2 text-2xl font-bold">
<Database className="h-5 w-5 text-primary" />
Data Collection
</h2>
<div className="space-y-4 text-muted-foreground">
<p>
<strong className="text-foreground">We do not collect any personal data.</strong> This
includes:
</p>
<ul className="space-y-2">
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
No voice recordings or audio data
</li>
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
No transcribed text
</li>
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
No usage analytics or telemetry
</li>
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
No device fingerprints
</li>
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
No IP addresses or location data
</li>
</ul>
</div>
</article>
<article className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<h2 className="mb-4 flex items-center gap-2 text-2xl font-bold">
<Shield className="h-5 w-5 text-primary" />
How We Process Your Voice
</h2>
<div className="space-y-4 text-muted-foreground">
<p>When you dictate, here's exactly what happens:</p>
<ol className="space-y-3 pl-4">
<li className="border-l-2 border-primary pl-4">
<strong className="text-foreground">1. Audio Capture</strong> — Your microphone
records audio temporarily in RAM
</li>
<li className="border-l-2 border-primary pl-4">
<strong className="text-foreground">2. Local Processing</strong> — Audio is
processed by whisper.cpp, Whisper, or VOSK on your CPU/GPU
</li>
<li className="border-l-2 border-primary pl-4">
<strong className="text-foreground">3. Text Output</strong> — Transcribed text is
injected into your active application
</li>
<li className="border-l-2 border-primary pl-4">
<strong className="text-foreground">4. Immediate Deletion</strong> — Audio data is
discarded immediately after processing
</li>
</ol>
<p className="mt-4 rounded-lg bg-amber-50 p-4 text-sm dark:bg-amber-900/20">
<strong>Note:</strong> No audio is ever written to disk or transmitted over the
network.
</p>
</div>
</article>
<article className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<h2 className="mb-4 flex items-center gap-2 text-2xl font-bold">
<Lock className="h-5 w-5 text-primary" />
Configuration Data
</h2>
<div className="space-y-4 text-muted-foreground">
<p>
Vocalinux stores configuration locally at <code className="rounded bg-zinc-100 px-1.5 py-0.5 dark:bg-zinc-700">~/.config/vocalinux/</code>:
</p>
<ul className="space-y-2">
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
Settings like preferred engine, model size, and language
</li>
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
Custom keyboard shortcuts
</li>
<li className="inline-flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-green-500" />
Window and tray preferences
</li>
</ul>
<p>
This data is stored in plain text YAML format. You can view, edit, or delete it at
any time.
</p>
</div>
</article>
</section>
{/* Comparison with Cloud Services */}
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-6 text-2xl font-bold">Vocalinux vs Cloud Dictation Services</h2>
<div className="overflow-x-auto">
<table className="w-full min-w-[500px] text-left">
<thead>
<tr className="border-b border-zinc-200 dark:border-zinc-700">
<th className="pb-3 text-sm font-semibold">Feature</th>
<th className="pb-3 text-sm font-semibold">Vocalinux</th>
<th className="pb-3 text-sm font-semibold">Cloud Services</th>
</tr>
</thead>
<tbody className="text-sm text-muted-foreground">
<tr className="border-b border-zinc-100 dark:border-zinc-700/70">
<td className="py-3 font-medium text-foreground">Data leaves device</td>
<td className="py-3 text-green-600 dark:text-green-400">Never</td>
<td className="py-3 text-red-600 dark:text-red-400">Always</td>
</tr>
<tr className="border-b border-zinc-100 dark:border-zinc-700/70">
<td className="py-3 font-medium text-foreground">Internet required</td>
<td className="py-3 text-green-600 dark:text-green-400">No</td>
<td className="py-3 text-red-600 dark:text-red-400">Yes</td>
</tr>
<tr className="border-b border-zinc-100 dark:border-zinc-700/70">
<td className="py-3 font-medium text-foreground">Source code available</td>
<td className="py-3 text-green-600 dark:text-green-400">Yes (GPL-3.0)</td>
<td className="py-3 text-red-600 dark:text-red-400">No</td>
</tr>
<tr className="border-b border-zinc-100 dark:border-zinc-700/70">
<td className="py-3 font-medium text-foreground">Voice recordings stored</td>
<td className="py-3 text-green-600 dark:text-green-400">No</td>
<td className="py-3">Varies by service</td>
</tr>
<tr>
<td className="py-3 font-medium text-foreground">Cost</td>
<td className="py-3 text-green-600 dark:text-green-400">Free forever</td>
<td className="py-3">Subscription</td>
</tr>
</tbody>
</table>
</div>
</section>
{/* Contact */}
<section className="mt-12 rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<h2 className="mb-4 text-xl font-bold">Questions About Privacy?</h2>
<p className="mb-4 text-muted-foreground">
If you have any questions about our privacy practices or want to verify our claims,
please reach out:
</p>
<a
href="https://github.com/jatinkrmalik/vocalinux/issues"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-primary hover:underline"
>
Open an issue on GitHub
<ExternalLink className="h-4 w-4" />
</a>
</section>
</SeoSubpageShell>
);
}
+231
View File
@@ -0,0 +1,231 @@
import Link from "next/link";
import { type Metadata } from "next";
import { ChevronRight, Command, Keyboard, Mouse, Settings, Space, Zap } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const shortcutCategories = [
{
category: "Dictation Controls",
icon: Mic,
iconColor: "text-blue-500",
shortcuts: [
{ keys: ["Ctrl", "Ctrl"], action: "Toggle dictation on/off (double-tap)", note: "Primary activation" },
{ keys: ["Ctrl", "Ctrl"], action: "Start/stop recording", note: "Same as toggle" },
],
},
{
category: "Voice Commands",
icon: Zap,
iconColor: "text-amber-500",
shortcuts: [
{ keys: ["\"new line\""], action: "Insert a new line", note: "Say this phrase" },
{ keys: ["\"new paragraph\""], action: "Insert a new paragraph", note: "Say this phrase" },
{ keys: ["\"delete that\""], action: "Delete last phrase", note: "Also: \"scratch that\"" },
{ keys: ["\"select all\""], action: "Select all text", note: "Voice command" },
{ keys: ["\"copy this\""], action: "Copy selection", note: "Voice command" },
{ keys: ["\"paste here\""], action: "Paste clipboard", note: "Voice command" },
{ keys: ["\"undo\""], action: "Undo last action", note: "Voice command" },
{ keys: ["\"redo\""], action: "Redo last action", note: "Voice command" },
],
},
{
category: "Tray Icon Actions",
icon: Mouse,
iconColor: "text-green-500",
shortcuts: [
{ keys: ["Left Click"], action: "Toggle dictation", note: "On tray icon" },
{ keys: ["Right Click"], action: "Open context menu", note: "Settings, quit, etc." },
],
},
{
category: "Configuration",
icon: Settings,
iconColor: "text-violet-500",
shortcuts: [
{ keys: ["Config File"], action: "~/.config/vocalinux/config.yaml", note: "Manual editing" },
],
},
];
function Mic(props: { className?: string }) {
return (
<svg className={props.className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" />
<path d="M19 10v2a7 7 0 0 1-14 0v-2" />
<line x1="12" x2="12" y1="19" y2="22" />
</svg>
);
}
export const metadata: Metadata = buildPageMetadata({
title: "Keyboard Shortcuts & Voice Commands - Vocalinux",
description:
"Learn Vocalinux keyboard shortcuts and voice commands. Double-tap Ctrl to dictate, use voice commands for editing, and customize your workflow.",
path: "/shortcuts",
keywords: [
"vocalinux shortcuts",
"linux voice dictation commands",
"speech to text keyboard shortcuts",
"voice commands linux",
],
});
export default function ShortcutsPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Vocalinux Keyboard Shortcuts & Voice Commands",
description:
"Complete guide to Vocalinux keyboard shortcuts and voice commands for efficient Linux voice dictation.",
dateModified: "2026-02-19",
author: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
publisher: {
"@type": "Organization",
name: "Vocalinux",
logo: {
"@type": "ImageObject",
url: absoluteUrl("/vocalinux.png"),
},
},
mainEntityOfPage: absoluteUrl("/shortcuts"),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-sm font-medium text-primary">
<Keyboard className="h-4 w-4" />
Quick Reference
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Keyboard Shortcuts & Voice Commands
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Master Vocalinux with keyboard shortcuts and voice commands. Double-tap Ctrl to start
dictating, then use voice commands to edit and format.
</p>
</section>
{/* Quick Start */}
<section className="mb-12 rounded-2xl border border-primary/20 bg-primary/5 p-6">
<h2 className="mb-4 text-xl font-bold">Quick Start</h2>
<div className="flex flex-wrap items-center gap-4">
<div className="flex items-center gap-2">
<kbd className="rounded-lg border border-zinc-300 bg-zinc-100 px-3 py-1.5 font-mono text-sm font-semibold dark:border-zinc-600 dark:bg-zinc-800">
Ctrl
</kbd>
<span className="text-muted-foreground">+</span>
<kbd className="rounded-lg border border-zinc-300 bg-zinc-100 px-3 py-1.5 font-mono text-sm font-semibold dark:border-zinc-600 dark:bg-zinc-800">
Ctrl
</kbd>
</div>
<span className="text-muted-foreground">→</span>
<span className="font-medium">Start/Stop Dictation</span>
</div>
</section>
{/* Shortcut Categories */}
<section className="space-y-8">
{shortcutCategories.map((category) => {
const Icon = category.icon;
return (
<article
key={category.category}
className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800"
>
<h2 className="mb-6 flex items-center gap-3 text-2xl font-bold">
<span className={`rounded-xl bg-zinc-100 p-2 dark:bg-zinc-700`}>
<Icon className={`h-5 w-5 ${category.iconColor}`} />
</span>
{category.category}
</h2>
<div className="space-y-4">
{category.shortcuts.map((shortcut, index) => (
<div
key={index}
className="flex flex-wrap items-center justify-between gap-4 rounded-xl bg-zinc-50 p-4 dark:bg-zinc-900/50"
>
<div className="flex items-center gap-3">
{shortcut.keys.map((key, keyIndex) => (
<span key={keyIndex} className="flex items-center gap-2">
<kbd className="rounded-lg border border-zinc-300 bg-zinc-100 px-3 py-1.5 font-mono text-sm font-semibold shadow-sm dark:border-zinc-600 dark:bg-zinc-800">
{key}
</kbd>
{keyIndex < shortcut.keys.length - 1 && (
<span className="text-muted-foreground">+</span>
)}
</span>
))}
</div>
<div className="text-right">
<p className="font-medium">{shortcut.action}</p>
<p className="text-sm text-muted-foreground">{shortcut.note}</p>
</div>
</div>
))}
</div>
</article>
);
})}
</section>
{/* Customization */}
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-4 text-2xl font-bold">Customizing Shortcuts</h2>
<p className="mb-4 text-muted-foreground">
You can customize the activation shortcut in the settings panel or by editing the
configuration file directly:
</p>
<div className="rounded-lg bg-zinc-950 p-4">
<code className="text-sm text-green-400">~/.config/vocalinux/config.yaml</code>
</div>
<p className="mt-4 text-sm text-muted-foreground">
Open Vocalinux and access Settings from the tray icon to change keyboard shortcuts
through the GUI.
</p>
</section>
{/* Related Pages */}
<section className="mt-12 grid gap-6 md:grid-cols-2">
<Link
href="/faq/"
className="group rounded-2xl border border-zinc-200 bg-white p-6 transition-all hover:-translate-y-1 hover:shadow-lg dark:border-zinc-700 dark:bg-zinc-800"
>
<h3 className="mb-2 text-xl font-semibold">Frequently Asked Questions</h3>
<p className="text-sm text-muted-foreground">
Get answers to common questions about Vocalinux features and usage.
</p>
<span className="mt-4 inline-flex items-center gap-1 text-sm font-semibold text-primary">
View FAQ
<ChevronRight className="h-4 w-4" />
</span>
</Link>
<Link
href="/troubleshooting/"
className="group rounded-2xl border border-zinc-200 bg-white p-6 transition-all hover:-translate-y-1 hover:shadow-lg dark:border-zinc-700 dark:bg-zinc-800"
>
<h3 className="mb-2 text-xl font-semibold">Troubleshooting</h3>
<p className="text-sm text-muted-foreground">
Having issues? Find solutions to common problems and fixes.
</p>
<span className="mt-4 inline-flex items-center gap-1 text-sm font-semibold text-primary">
Get Help
<ChevronRight className="h-4 w-4" />
</span>
</Link>
</section>
</SeoSubpageShell>
);
}
+243
View File
@@ -0,0 +1,243 @@
import Link from "next/link";
import { type Metadata } from "next";
import { AlertTriangle, CheckCircle2, ChevronRight, ExternalLink, Lightbulb, Terminal, Wrench } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const troubleshootingItems = [
{
title: "Vocalinux won't start",
symptoms: ["Command not found", "Module import errors", "Application crashes on launch"],
solutions: [
"Ensure you ran the installer: curl -fsSL https://raw.githubusercontent.com/jatinkrmalik/vocalinux/main/install.sh | bash",
"Check if the virtual environment is activated: source ~/.local/share/vocalinux/venv/bin/activate",
"Verify Python version (3.8+ required): python3 --version",
"Try reinstalling: ./uninstall.sh && ./install.sh",
],
},
{
title: "No audio detected / microphone not working",
symptoms: ["Dictation shows no text", "Audio level indicator stays at zero"],
solutions: [
"Check microphone permissions in your system settings",
"Verify microphone is detected: arecord -l (Linux)",
"Test microphone recording: arecord -d 3 test.wav && aplay test.wav",
"Ensure no other application is using the microphone",
"Check PulseAudio/PipeWire settings: pavucontrol",
],
},
{
title: "Text not appearing in applications",
symptoms: ["Dictation works but text doesn't appear", "Text injection fails"],
solutions: [
"For Wayland: Ensure IBus is running and Vocalinux IBus is configured",
"For X11: Verify xdotool is installed: sudo apt install xdotool",
"Check if the target application has focus",
"Try a different application (terminal, text editor) to isolate the issue",
"Restart Vocalinux after changing display servers",
],
},
{
title: "High CPU/GPU usage",
symptoms: ["System slowdown during dictation", "Fan noise", "Laggy response"],
solutions: [
"Use a smaller model (tiny or base instead of medium/large)",
"Enable GPU acceleration if available (Vulkan for AMD/Intel, CUDA for NVIDIA)",
"Switch to VOSK engine for lower resource usage",
"Reduce audio sample rate in settings",
],
},
{
title: "Poor transcription accuracy",
symptoms: ["Many transcription errors", "Wrong words", "Garbled text"],
solutions: [
"Use a larger model (small → medium → large) for better accuracy",
"Ensure microphone is positioned correctly and not too far",
"Reduce background noise",
"Speak clearly and at a moderate pace",
"Try a different speech engine (whisper.cpp vs VOSK)",
"Set the correct language in settings",
],
},
{
title: "Installation fails",
symptoms: ["Dependency errors", "Package not found", "Permission denied"],
solutions: [
"Ensure you have internet connectivity for downloading dependencies",
"Run with sufficient permissions (don't use sudo unless specifically needed)",
"Check your distribution is supported (Ubuntu 22.04+, Fedora 39+, Arch)",
"Install system dependencies manually: sudo apt install python3-pip python3-gi python3-venv",
"Check disk space: df -h",
],
},
{
title: "Keyboard shortcut not working",
symptoms: ["Double-tap Ctrl doesn't start dictation", "Custom shortcuts ignored"],
solutions: [
"Check if another application is capturing the shortcut",
"Verify Vocalinux is running (check system tray)",
"Try changing the shortcut in Settings",
"On Wayland, ensure keyboard shortcuts are not blocked by compositor settings",
],
},
{
title: "Tray icon not appearing",
symptoms: ["No system tray icon", "Cannot access settings"],
solutions: [
"Ensure your desktop environment supports system trays (GNOME requires extension)",
"Install AppIndicator extension for GNOME: sudo apt install gnome-shell-extension-appindicator",
"Check if ayatana-appindicator is installed: sudo apt install libayatana-appindicator3-1",
"Try launching from terminal to see any errors: vocalinux --debug",
],
},
];
export const metadata: Metadata = buildPageMetadata({
title: "Troubleshooting Guide - Vocalinux Voice Dictation",
description:
"Fix common Vocalinux issues: microphone problems, text injection, installation errors, and performance. Step-by-step solutions for Linux voice dictation.",
path: "/troubleshooting",
keywords: [
"vocalinux troubleshooting",
"linux voice dictation problems",
"speech to text not working",
"microphone issues linux",
],
});
export default function TroubleshootingPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Vocalinux Troubleshooting Guide",
description:
"Complete troubleshooting guide for Vocalinux Linux voice dictation software.",
dateModified: "2026-02-19",
author: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
publisher: {
"@type": "Organization",
name: "Vocalinux",
logo: {
"@type": "ImageObject",
url: absoluteUrl("/vocalinux.png"),
},
},
mainEntityOfPage: absoluteUrl("/troubleshooting"),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-amber-500/30 bg-amber-500/10 px-4 py-1.5 text-sm font-medium text-amber-600 dark:text-amber-400">
<Wrench className="h-4 w-4" />
Support Guide
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Troubleshooting Guide
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Having issues with Vocalinux? Find solutions to common problems below. Can't find your
issue? Open a GitHub issue for help.
</p>
</section>
<section className="mb-12 rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800">
<h2 className="mb-4 flex items-center gap-2 text-xl font-bold">
<Terminal className="h-5 w-5 text-green-500" />
Quick Debug Command
</h2>
<p className="mb-4 text-sm text-muted-foreground">
Run Vocalinux with debug output to see detailed logs:
</p>
<div className="rounded-lg bg-zinc-950 p-4">
<code className="text-sm text-green-400">vocalinux --debug</code>
</div>
</section>
<section className="space-y-6">
{troubleshootingItems.map((item) => (
<article
key={item.title}
className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800"
>
<h2 className="mb-4 text-xl font-bold">{item.title}</h2>
<div className="mb-4 rounded-lg bg-amber-50 p-4 dark:bg-amber-900/20">
<p className="mb-2 flex items-center gap-2 text-sm font-semibold text-amber-700 dark:text-amber-400">
<AlertTriangle className="h-4 w-4" />
Symptoms
</p>
<ul className="ml-6 list-disc text-sm text-amber-600 dark:text-amber-300">
{item.symptoms.map((symptom) => (
<li key={symptom}>{symptom}</li>
))}
</ul>
</div>
<div className="rounded-lg bg-green-50 p-4 dark:bg-green-900/20">
<p className="mb-2 flex items-center gap-2 text-sm font-semibold text-green-700 dark:text-green-400">
<CheckCircle2 className="h-4 w-4" />
Solutions
</p>
<ul className="ml-6 list-disc text-sm text-green-600 dark:text-green-300">
{item.solutions.map((solution) => (
<li key={solution}>{solution}</li>
))}
</ul>
</div>
</article>
))}
</section>
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-4 flex items-center gap-2 text-2xl font-bold">
<Lightbulb className="h-5 w-5 text-amber-500" />
Still having issues?
</h2>
<ul className="space-y-3 text-muted-foreground">
<li className="inline-flex items-center gap-2">
<ChevronRight className="h-4 w-4 text-primary" />
Check the{" "}
<Link href="/faq/" className="font-semibold text-primary hover:underline">
FAQ page
</Link>{" "}
for common questions
</li>
<li className="inline-flex items-center gap-2">
<ChevronRight className="h-4 w-4 text-primary" />
<a
href="https://github.com/jatinkrmalik/vocalinux/issues"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
>
Search existing issues on GitHub
<ExternalLink className="h-3.5 w-3.5" />
</a>
</li>
<li className="inline-flex items-center gap-2">
<ChevronRight className="h-4 w-4 text-primary" />
<a
href="https://github.com/jatinkrmalik/vocalinux/issues/new"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
>
Open a new issue (include debug logs)
<ExternalLink className="h-3.5 w-3.5" />
</a>
</li>
</ul>
</section>
</SeoSubpageShell>
);
}
+225
View File
@@ -0,0 +1,225 @@
import Link from "next/link";
import { type Metadata } from "next";
import { Accessibility, BookOpen, Briefcase, ChevronRight, Code, Feather, GraduationCap, Heart, Users } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const useCases = [
{
title: "Developers",
icon: Code,
iconColor: "text-blue-500",
iconBg: "bg-blue-100 dark:bg-blue-900/30",
description: "Code faster with voice. Dictate comments, documentation, and even code snippets hands-free.",
benefits: [
"Dictate code comments while keeping hands on the keyboard",
"Write documentation at the speed of thought",
"Reduce RSI from constant typing",
"Multitask: review code while dictating notes",
],
commands: ["new line", "open parenthesis", "close parenthesis", "tab"],
},
{
title: "Writers & Authors",
icon: Feather,
iconColor: "text-violet-500",
iconBg: "bg-violet-100 dark:bg-violet-900/30",
description: "Capture ideas as fast as you can think them. Perfect for drafts, articles, and creative writing.",
benefits: [
"Write at natural speaking speed (100+ WPM)",
"Overcome writer's block by speaking freely",
"Maintain creative flow without keyboard interruptions",
"Dictate while walking or pacing",
],
commands: ["new paragraph", "quote", "delete that", "undo"],
},
{
title: "Students",
icon: GraduationCap,
iconColor: "text-emerald-500",
iconBg: "bg-emerald-100 dark:bg-emerald-900/30",
description: "Take notes during lectures, transcribe recordings, and write essays faster.",
benefits: [
"Take lecture notes at speaking speed",
"Transcribe audio recordings for study",
"Write essays and papers hands-free",
"Multi-language support for language learners",
],
commands: ["select all", "copy", "paste", "new line"],
},
{
title: "Accessibility Users",
icon: Accessibility,
iconColor: "text-rose-500",
iconBg: "bg-rose-100 dark:bg-rose-900/30",
description: "Full voice control for users with mobility impairments, RSI, or carpal tunnel.",
benefits: [
"Type without using hands",
"Reduce strain from repetitive typing",
"Independence for users with physical disabilities",
"100% offline - no cloud dependency",
],
commands: ["select all", "delete that", "undo", "redo"],
},
{
title: "Professionals",
icon: Briefcase,
iconColor: "text-amber-500",
iconBg: "bg-amber-100 dark:bg-amber-900/30",
description: "Dictate emails, reports, and meeting notes. Boost productivity in any profession.",
benefits: [
"Draft emails quickly with natural speech",
"Create meeting minutes in real-time",
"Write reports hands-free",
"Private - no data leaves your machine",
],
commands: ["new paragraph", "comma", "period", "send"],
},
{
title: "Content Creators",
icon: Heart,
iconColor: "text-pink-500",
iconBg: "bg-pink-100 dark:bg-pink-900/30",
description: "Create YouTube scripts, podcast notes, and social media content at speaking speed.",
benefits: [
"Write scripts as fast as you can speak",
"Transcribe video/audio content",
"Draft social media posts hands-free",
"Create captions and subtitles",
],
commands: ["new line", "quote", "colon", "hashtag"],
},
];
export const metadata: Metadata = buildPageMetadata({
title: "Use Cases - Who Uses Vocalinux Voice Dictation",
description:
"Discover how developers, writers, students, and professionals use Vocalinux for Linux voice dictation. Find your use case and boost productivity.",
path: "/use-cases",
keywords: [
"voice dictation for developers",
"speech to text for writers",
"linux accessibility voice typing",
"dictation software for students",
],
});
export default function UseCasesPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Vocalinux Use Cases - Voice Dictation for Every Workflow",
description:
"Discover how different professionals use Vocalinux for Linux voice dictation.",
dateModified: "2026-02-19",
author: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
publisher: {
"@type": "Organization",
name: "Vocalinux",
logo: {
"@type": "ImageObject",
url: absoluteUrl("/vocalinux.png"),
},
},
mainEntityOfPage: absoluteUrl("/use-cases"),
};
return (
<SeoSubpageShell>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleJsonLd) }}
/>
<section>
<p className="mb-4 inline-flex items-center gap-2 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-sm font-medium text-primary">
<Users className="h-4 w-4" />
For Everyone
</p>
<h1 className="mb-5 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl">
Voice Dictation for Every Workflow
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Whether you're coding, writing, studying, or need accessibility support, Vocalinux adapts
to your needs. See how different professionals use voice dictation to boost productivity.
</p>
</section>
<section className="space-y-8">
{useCases.map((useCase) => {
const Icon = useCase.icon;
return (
<article
key={useCase.title}
className="rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-700 dark:bg-zinc-800"
>
<div className="mb-6 flex flex-wrap items-start gap-4">
<div className={`rounded-xl p-3 ${useCase.iconBg}`}>
<Icon className={`h-6 w-6 ${useCase.iconColor}`} />
</div>
<div className="flex-1">
<h2 className="mb-2 text-2xl font-bold">{useCase.title}</h2>
<p className="text-muted-foreground">{useCase.description}</p>
</div>
</div>
<div className="grid gap-6 md:grid-cols-2">
<div>
<h3 className="mb-3 font-semibold">Key Benefits</h3>
<ul className="space-y-2">
{useCase.benefits.map((benefit) => (
<li key={benefit} className="inline-flex items-start gap-2 text-sm text-muted-foreground">
<ChevronRight className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
{benefit}
</li>
))}
</ul>
</div>
<div>
<h3 className="mb-3 font-semibold">Helpful Voice Commands</h3>
<div className="flex flex-wrap gap-2">
{useCase.commands.map((cmd) => (
<kbd
key={cmd}
className="rounded-lg border border-zinc-300 bg-zinc-100 px-2 py-1 text-xs font-mono dark:border-zinc-600 dark:bg-zinc-900"
>
"{cmd}"
</kbd>
))}
</div>
</div>
</div>
</article>
);
})}
</section>
<section className="mt-12 rounded-2xl border border-zinc-200 bg-zinc-50 p-8 dark:border-zinc-700 dark:bg-zinc-900/60">
<h2 className="mb-4 text-2xl font-bold">Ready to Get Started?</h2>
<p className="mb-6 text-muted-foreground">
Install Vocalinux in minutes and start dictating in any application on Linux.
</p>
<div className="flex flex-wrap gap-4">
<Link
href="/install/"
className="inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground hover:bg-primary/90"
>
Install Now
<ChevronRight className="h-4 w-4" />
</Link>
<Link
href="/shortcuts/"
className="inline-flex items-center gap-2 rounded-lg border border-zinc-300 bg-white px-4 py-2 text-sm font-semibold hover:bg-zinc-50 dark:border-zinc-600 dark:bg-zinc-800 dark:hover:bg-zinc-700"
>
View Voice Commands
</Link>
</div>
</section>
</SeoSubpageShell>
);
}
+26 -1
View File
@@ -1,6 +1,6 @@
import React from "react";
import Link from "next/link";
import { BookOpen, ChevronRight, Cpu, Home } from "lucide-react";
import { BookOpen, ChevronRight, Cpu, HelpCircle, Home, Map, Rss, Shield, Users } from "lucide-react";
import { VocalinuxLogo } from "@/components/optimized-image";
interface SeoSubpageShellProps {
@@ -23,6 +23,31 @@ const navLinks = [
label: "Engine Compare",
icon: Cpu,
},
{
href: "/use-cases/",
label: "Use Cases",
icon: Users,
},
{
href: "/faq/",
label: "FAQ",
icon: HelpCircle,
},
{
href: "/changelog/",
label: "Changelog",
icon: Rss,
},
{
href: "/privacy/",
label: "Privacy",
icon: Shield,
},
{
href: "/alternatives/",
label: "Alternatives",
icon: Map,
},
];
export function SeoSubpageShell({ children }: SeoSubpageShellProps) {