Merge feature/24 into integration/spec16 (ticket #24: web rebrand to Voculinux)
@@ -1,4 +1,4 @@
|
||||
"""Ticket #18: offline naming-sweep — no old-name strings on user-visible surfaces.
|
||||
"""Ticket #18 + #24: offline naming-sweep — no old-name strings on surfaces.
|
||||
|
||||
The fork takes its own name everywhere a user can see it. Anything still
|
||||
spelling the old name must be on the allowlist below:
|
||||
@@ -10,8 +10,9 @@ spelling the old name must be on the allowlist below:
|
||||
- one-time-legacy import sources (old config/dictionary/bus literals),
|
||||
- generated or historical files (``uv.lock``, ``requirements/*.txt``,
|
||||
``CHANGELOG.md``),
|
||||
- the rest of ``web/`` (owned by ticket #24; only ``page.tsx`` and
|
||||
``package.json`` belong to this ticket).
|
||||
- web upstream surfaces (ticket #24): upstream GitHub/raw/nix flake URLs,
|
||||
nix flake API identifiers, and the nixos-page fork-status note that names
|
||||
the upstream flake as installing Vocalinux rather than Voculinux.
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -21,7 +22,7 @@ REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
OLD_NAME = re.compile(r"vocalinux", re.IGNORECASE)
|
||||
|
||||
SKIP_DIRS = {".git", "__pycache__", ".venv", "venv", "node_modules", ".next", "build", "dist"}
|
||||
SKIP_DIRS = {".git", "__pycache__", ".venv", "venv", "node_modules", ".next", "build", "dist", "out"}
|
||||
SKIP_SUFFIXES = (".egg-info",)
|
||||
SKIP_FILES = {"uv.lock", "CHANGELOG.md"}
|
||||
SKIP_PREFIXES = ("requirements/",)
|
||||
@@ -45,7 +46,8 @@ BINARY_EXTS = (
|
||||
".pyc",
|
||||
)
|
||||
|
||||
#: web/ belongs to ticket #24 except the two rename-inventory files.
|
||||
#: web/ was fully rebranded in ticket #24; only upstream-provenance lines
|
||||
#: (matched in _allowed) may still spell the old name there.
|
||||
WEB_OWNED = {"web/src/app/page.tsx", "web/package.json"}
|
||||
|
||||
|
||||
@@ -57,6 +59,10 @@ def _allowed(path: str, line: str) -> bool:
|
||||
if "vocalinux" in low and "voculinux" in low:
|
||||
# Migration-compat shims that name both installs at once.
|
||||
return True
|
||||
if "upstream" in low:
|
||||
# Upstream-provenance mentions that explicitly label the old name
|
||||
# as upstream (fork-status notes, provenance cards).
|
||||
return True
|
||||
if "/{name}/vocalinux" in line:
|
||||
# Upstream repo-name template (retained provenance).
|
||||
return True
|
||||
@@ -101,6 +107,12 @@ def _allowed(path: str, line: str) -> bool:
|
||||
if '"src"' in line and '"vocalinux"' in line:
|
||||
# Retained module-dir path segments in tests and tooling.
|
||||
return True
|
||||
if path == "web/src/app/install/nixos/page.tsx":
|
||||
# The Nix flake is upstream's: flake URL, input/output names, module
|
||||
# paths, and programs.* options spell the retained upstream API.
|
||||
# The page carries a fork-status note stating those snippets install
|
||||
# Vocalinux (upstream), not Voculinux.
|
||||
return True
|
||||
if path == "tests/test_rename_sweep.py":
|
||||
return True
|
||||
if path == "pyproject.toml" and re.search(r'"vocalinux[."\'\]]', line):
|
||||
@@ -126,8 +138,6 @@ def _iter_files():
|
||||
rel = os.path.relpath(full, REPO_ROOT)
|
||||
if rel.startswith(SKIP_PREFIXES):
|
||||
continue
|
||||
if rel.startswith("web/") and rel not in WEB_OWNED:
|
||||
continue
|
||||
yield rel, full
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# AGENTS.md — vocalinux.com (`web/`)
|
||||
# AGENTS.md — voculinux.com (`web/`)
|
||||
|
||||
Guidelines for agents working on the marketing site only. For the Python desktop app, git worktrees, and PR rules, see the repo root [`AGENTS.md`](../AGENTS.md). Do not create branches, commits, or pull requests in the primary checkout.
|
||||
|
||||
## What this package is
|
||||
|
||||
Next.js (App Router) static marketing + SEO guides for Vocalinux. Source lives here; production deploys from `web/` (static export to `out/`).
|
||||
Next.js (App Router) static marketing + SEO guides for Voculinux. Source lives here; production deploys from `web/` (static export to `out/`).
|
||||
|
||||
## Product and design authority
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Vocalinux website
|
||||
description: Linux voice dictation marketing site in the Voca family workbench language
|
||||
name: Voculinux website
|
||||
description: Linux voice dictation marketing site in the Carbon-mapped house-palette language
|
||||
colors:
|
||||
paper: "#f4f1e8"
|
||||
paper-deep: "#ebe5d8"
|
||||
@@ -31,13 +31,13 @@ spacing:
|
||||
section-y: "5.5rem"
|
||||
---
|
||||
|
||||
# Design system: vocalinux.com
|
||||
# Design system: voculinux.com
|
||||
|
||||
## Overview
|
||||
|
||||
**Creative north star: the Linux desk in the Voca family**
|
||||
**Creative north star: the Linux desk, Carbon-mapped to the house palette**
|
||||
|
||||
Vocalinux.com is a Voca product site. It should feel related to VocaHQ, VocaMac, VocaPhone, and VocaGateway before anyone reads the logo: warm paper, deep green ink, one teal accent, editorial type, flat surfaces, and real product proof.
|
||||
Voculinux.com is the fork site. It adopts Carbon's spacing, type-role, motion, and contrast discipline remapped to the house palette — warm paper, deep green ink, one teal accent, editorial type, flat surfaces, and real product proof. Carbon blue and Carbon typefaces are not adopted; system stacks only. Bongbetic appears only as attribution chrome in the header and footer, linking hosted assets.
|
||||
|
||||
The Linux-specific job is to show local desktop dictation with distribution and display-server truth. Pair a GTK-style window (not macOS traffic lights) with a terminal. Explain the user outcome before the install command.
|
||||
|
||||
@@ -82,7 +82,7 @@ Warm paper with one product teal. No second chromatic brand color.
|
||||
|
||||
## Typography
|
||||
|
||||
System-first, same stacks as VocaHQ / VocaMac.
|
||||
System-first, system stacks only; no remote webfonts.
|
||||
|
||||
- **Display:** Avenir Next / Helvetica Neue / Segoe UI / Arial
|
||||
- **Body:** system UI sans
|
||||
@@ -119,7 +119,7 @@ Flat fills, 1px borders, paper-window shadows. Small rotations only on decorativ
|
||||
|
||||
### Buttons
|
||||
- Primary: brand teal, paper-bright text, 44px min height
|
||||
- Homepage / closing CTA: "Install Vocalinux", jumps to `#install`
|
||||
- Homepage / closing CTA: "Install Voculinux", jumps to `#install`
|
||||
- Secondary: transparent with a 3:1 control outline
|
||||
- Hover: 2px lift, no bounce scale as the only affordance
|
||||
- Focus: 3px sun outline, 3px offset
|
||||
@@ -137,7 +137,7 @@ Flat fills, 1px borders, paper-window shadows. Small rotations only on decorativ
|
||||
|
||||
### Navigation
|
||||
- Sticky paper bar, mark + name, 3–5 text links, GitHub stars on desktop
|
||||
- Mobile menu keeps Install Vocalinux as the conversion action
|
||||
- Mobile menu keeps Install Voculinux as the conversion action
|
||||
- Real mobile disclosure with `aria-expanded`
|
||||
- Resource-rich footer, not a second mega-menu in the header
|
||||
|
||||
@@ -159,4 +159,4 @@ Flat fills, 1px borders, paper-window shadows. Small rotations only on decorativ
|
||||
- macOS traffic-light chrome on Linux surfaces
|
||||
- Tracked uppercase eyebrows on every section
|
||||
- Invent metrics, testimonials, or "AI-powered" claims
|
||||
- Recolor the Vocalinux mark
|
||||
- Recolor the Voculinux mark
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Product (vocalinux.com)
|
||||
# Product (voculinux.com)
|
||||
|
||||
## Platform
|
||||
|
||||
@@ -10,7 +10,7 @@ Linux desktop users who want voice dictation that stays on their machine: develo
|
||||
|
||||
## Product purpose
|
||||
|
||||
Vocalinux is free, open-source offline voice dictation for Linux. It turns speech into typed text in whatever app has focus, using local engines (whisper.cpp default, Faster Whisper, Whisper, VOSK, Parakeet) or an optional user-configured remote API. Success is: install once, dictate in any app, without cloud transcription or telemetry.
|
||||
Voculinux is free, open-source offline voice dictation for Linux. It turns speech into typed text in whatever app has focus, using local engines (whisper.cpp default, Faster Whisper, Whisper, VOSK, Parakeet) or an optional user-configured remote API. Success is: install once, dictate in any app, without cloud transcription or telemetry.
|
||||
|
||||
## Positioning
|
||||
|
||||
@@ -22,7 +22,7 @@ Offline-first Linux voice typing with real desktop integration (system tray, X11
|
||||
- System tray indicator and settings GUI (GTK) with searchable sidebar navigation and an always-visible sidebar footer for dictation status / Test Dictation / Close
|
||||
- Dictation into terminals, browsers, IDEs, office apps
|
||||
- Engines and models chosen for hardware (CPU, optional Vulkan GPU with discrete-device preference)
|
||||
- Guides and comparison pages on vocalinux.com; source on GitHub
|
||||
- Guides and comparison pages on voculinux.com; source on GitHub
|
||||
|
||||
## Capabilities and constraints
|
||||
|
||||
@@ -44,9 +44,9 @@ Offline-first Linux voice typing with real desktop integration (system tray, X11
|
||||
- Settings Proxy page: outbound SOCKS5 or HTTP CONNECT proxy (optional auth) for model downloads and update checks
|
||||
- Speech Model Advanced pickers stage engine/size/variant/language changes until Download is confirmed
|
||||
- In-app update checker (stable/nightly) with tray notification when a newer GitHub release is available
|
||||
- Settings About page groups this app, VocaHQ family sites, and talk-to-us links (GitHub, Discord, X, email)
|
||||
- Settings About page groups this app, upstream project links retained as provenance, and talk-to-us links (GitHub, Discord, X, email)
|
||||
- Optional disable of the missing-tray warning dialog
|
||||
- Settings → Audio family tone picker (Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off) with Preview; new installs default to Voca; catalog files are the family preview WAVs
|
||||
- Settings → Audio tone picker (Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off) with Preview; new installs default to Voca; catalog files are the preview WAVs
|
||||
- Vulkan discrete GPU auto-select with manual device override in Advanced settings
|
||||
- Native GTK installs follow the OS dark/light preference unless `GTK_THEME` is already set
|
||||
- Wayland: IBus when `ibus-wayland` is running, including on compositors previously treated as unbridged
|
||||
@@ -57,9 +57,10 @@ Offline-first Linux voice typing with real desktop integration (system tray, X11
|
||||
|
||||
## Brand commitments
|
||||
|
||||
- Name: Vocalinux (part of [VocaHQ](https://vocahq.com) with VocaMac / VocaWin)
|
||||
- Mark: shared Voca family mic for the app icon, tray states, and site favicons (`public/`)
|
||||
- Warm paper surfaces and Voca teal, matching the family web standard
|
||||
- Name: Voculinux, a hard fork of Vocalinux for Void Linux (glibc, Wayland-primary under niri). Upstream project links are retained as provenance; the fork site carries the new name everywhere a user looks
|
||||
- Mark: fork mic for the app icon, tray states, and site favicons (`public/`); Bongbetic appears only as attribution chrome in the site header and footer, linking the hosted brand assets at `https://bongbetic.com/branding/` — no brand binaries are vendored into the repository
|
||||
- Visual system: Carbon-mapped — Carbon spacing, type-role, motion, and contrast discipline remapped to the house palette (warm paper canvas, teal interactive colour, system type stacks only, red reserved for recording/destructive); no Carbon blue, no remote webfonts
|
||||
- Engine promise: whisper.cpp is the guaranteed default engine (packaged, checksum-pinned, budgeted); Faster Whisper, Whisper, VOSK, and Parakeet are best-effort installable extras; the Remote API engine is user-configured and audio leaves the machine — stated plainly wherever remote is described
|
||||
- Voice: practical, specific, Linux-native; not hype-first SaaS copy
|
||||
|
||||
## Evidence on hand
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Vocalinux website
|
||||
# Voculinux website
|
||||
|
||||
Marketing site for [vocalinux.com](https://vocalinux.com), built with Next.js and deployed as a static export (GitHub Pages).
|
||||
Marketing site for [voculinux.com](https://voculinux.com), built with Next.js and deployed as a static export (GitHub Pages).
|
||||
|
||||
Product claims and design constraints: [PRODUCT.md](PRODUCT.md), [DESIGN.md](DESIGN.md). Agent notes: [AGENTS.md](AGENTS.md).
|
||||
|
||||
@@ -41,7 +41,7 @@ Open `http://localhost:3000`.
|
||||
|
||||
## Deployment
|
||||
|
||||
Push to `main` triggers the site workflow. Production host: **vocalinux.com**.
|
||||
Push to `main` triggers the site workflow. Production host: **voculinux.com**.
|
||||
|
||||
Manual path:
|
||||
|
||||
@@ -51,7 +51,7 @@ npm install
|
||||
npm run deploy
|
||||
```
|
||||
|
||||
That produces `out/` with `.nojekyll` and a `CNAME` for vocalinux.com.
|
||||
That produces `out/` with `.nojekyll` and a `CNAME` for voculinux.com.
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -87,4 +87,4 @@ web/
|
||||
|
||||
## License
|
||||
|
||||
Same as the main Vocalinux project ([AGPL-3.0](../LICENSE)).
|
||||
Same as the main Voculinux project ([AGPL-3.0](../LICENSE)).
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "vocalinux-website",
|
||||
"name": "voculinux-website",
|
||||
"version": "0.18.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "vocalinux-website",
|
||||
"name": "voculinux-website",
|
||||
"version": "0.18.5",
|
||||
"dependencies": {
|
||||
"@types/node": "^20.14.10",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Linux mascot used on the Open Graph card.
|
||||
|
||||
`tux.svg` is a flat derivative of Larry Ewing's Tux: the original
|
||||
silhouette, filled with Vocalinux tokens (ink, paper-bright, sun).
|
||||
silhouette, filled with Voculinux tokens (ink, paper-bright, sun).
|
||||
No gradients, blurs, or glares. `tux-classic.svg` is the unaltered
|
||||
Wikimedia vector.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Vocalinux">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Voculinux">
|
||||
<circle cx="229" cy="231.5" r="221.5" fill="#0F6B57"/>
|
||||
<path d="M 164 127 A 65 65 0 0 1 294 127 L 294 224 A 65 65 0 0 1 164 224 Z" fill="#F2F6F2"/>
|
||||
<path d="M 144.87 202.02 A 87 87 0 1 0 312.13 202.02" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
|
Before Width: | Height: | Size: 887 B After Width: | Height: | Size: 887 B |
@@ -1,5 +1,5 @@
|
||||
# Robots.txt for Vocalinux
|
||||
# https://vocalinux.com
|
||||
# Robots.txt for Voculinux
|
||||
# https://voculinux.com
|
||||
#
|
||||
# Intentionally permissive for marketing pages. Do not blanket-block
|
||||
# query-string URLs or /_next/static — those caused Google Search Console
|
||||
@@ -12,4 +12,4 @@ Disallow: /api/
|
||||
Disallow: /out/
|
||||
|
||||
# Sitemap location
|
||||
Sitemap: https://vocalinux.com/sitemap.xml
|
||||
Sitemap: https://voculinux.com/sitemap.xml
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Vocalinux",
|
||||
"short_name": "Vocalinux",
|
||||
"name": "Voculinux",
|
||||
"short_name": "Voculinux",
|
||||
"description": "Voice dictation for Linux with local engines and an optional Remote API.",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
@@ -8,7 +8,7 @@
|
||||
"theme_color": "#0f6b57",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/brand/vocalinux-mark-circle.svg",
|
||||
"src": "/brand/voculinux-mark-circle.svg",
|
||||
"sizes": "any",
|
||||
"type": "image/svg+xml",
|
||||
"purpose": "any"
|
||||
|
||||
@@ -1,284 +1,284 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://vocalinux.com/</loc>
|
||||
<loc>https://voculinux.com/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/</loc>
|
||||
<loc>https://voculinux.com/install/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/ubuntu/</loc>
|
||||
<loc>https://voculinux.com/install/ubuntu/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/fedora/</loc>
|
||||
<loc>https://voculinux.com/install/fedora/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/arch/</loc>
|
||||
<loc>https://voculinux.com/install/arch/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/compare/</loc>
|
||||
<loc>https://voculinux.com/compare/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/changelog/</loc>
|
||||
<loc>https://voculinux.com/changelog/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/screenshots/</loc>
|
||||
<loc>https://voculinux.com/screenshots/</loc>
|
||||
<lastmod>2026-07-14</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/faq/</loc>
|
||||
<loc>https://voculinux.com/faq/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/privacy/</loc>
|
||||
<loc>https://voculinux.com/privacy/</loc>
|
||||
<lastmod>2026-02-22</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/shortcuts/</loc>
|
||||
<loc>https://voculinux.com/shortcuts/</loc>
|
||||
<lastmod>2026-02-22</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/troubleshooting/</loc>
|
||||
<loc>https://voculinux.com/troubleshooting/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/use-cases/</loc>
|
||||
<loc>https://voculinux.com/use-cases/</loc>
|
||||
<lastmod>2026-02-22</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/alternatives/</loc>
|
||||
<loc>https://voculinux.com/alternatives/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<!-- New SEO pages -->
|
||||
<url>
|
||||
<loc>https://vocalinux.com/languages/</loc>
|
||||
<loc>https://voculinux.com/languages/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/wayland/</loc>
|
||||
<loc>https://voculinux.com/wayland/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/remote-api/</loc>
|
||||
<loc>https://voculinux.com/remote-api/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/voice-activity-detection/</loc>
|
||||
<loc>https://voculinux.com/voice-activity-detection/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/advanced-settings/</loc>
|
||||
<loc>https://voculinux.com/advanced-settings/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/desktop-reliability/</loc>
|
||||
<loc>https://voculinux.com/desktop-reliability/</loc>
|
||||
<lastmod>2026-06-11</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/rsi-prevention/</loc>
|
||||
<loc>https://voculinux.com/rsi-prevention/</loc>
|
||||
<lastmod>2026-02-22</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/gpu-acceleration/</loc>
|
||||
<loc>https://voculinux.com/gpu-acceleration/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/open-source/</loc>
|
||||
<loc>https://voculinux.com/open-source/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/autostart/</loc>
|
||||
<loc>https://voculinux.com/autostart/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/for-developers/</loc>
|
||||
<loc>https://voculinux.com/for-developers/</loc>
|
||||
<lastmod>2026-02-22</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/offline/</loc>
|
||||
<loc>https://voculinux.com/offline/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/vs-nerd-dictation/</loc>
|
||||
<loc>https://voculinux.com/vs-nerd-dictation/</loc>
|
||||
<lastmod>2026-03-30</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/whisper-model-guide/</loc>
|
||||
<loc>https://voculinux.com/whisper-model-guide/</loc>
|
||||
<lastmod>2026-03-30</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/voice-typing-vscode/</loc>
|
||||
<loc>https://voculinux.com/voice-typing-vscode/</loc>
|
||||
<lastmod>2026-03-30</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/writers/</loc>
|
||||
<loc>https://voculinux.com/writers/</loc>
|
||||
<lastmod>2026-03-30</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/gnome-kde/</loc>
|
||||
<loc>https://voculinux.com/gnome-kde/</loc>
|
||||
<lastmod>2026-03-30</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/parakeet/</loc>
|
||||
<loc>https://voculinux.com/parakeet/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/faster-whisper/</loc>
|
||||
<loc>https://voculinux.com/faster-whisper/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/dictation-pad/</loc>
|
||||
<loc>https://voculinux.com/dictation-pad/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/transcribe-audio-files/</loc>
|
||||
<loc>https://voculinux.com/transcribe-audio-files/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/custom-dictionary/</loc>
|
||||
<loc>https://voculinux.com/custom-dictionary/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/multilingual-dictation/</loc>
|
||||
<loc>https://voculinux.com/multilingual-dictation/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/pipewire/</loc>
|
||||
<loc>https://voculinux.com/pipewire/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/global-shortcuts/</loc>
|
||||
<loc>https://voculinux.com/global-shortcuts/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/hyprland-sway/</loc>
|
||||
<loc>https://voculinux.com/hyprland-sway/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/local-gateway/</loc>
|
||||
<loc>https://voculinux.com/local-gateway/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/flatpak/</loc>
|
||||
<loc>https://voculinux.com/flatpak/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/nixos/</loc>
|
||||
<loc>https://voculinux.com/install/nixos/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/debian/</loc>
|
||||
<loc>https://voculinux.com/install/debian/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/opensuse/</loc>
|
||||
<loc>https://voculinux.com/install/opensuse/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/linux-mint/</loc>
|
||||
<loc>https://voculinux.com/install/linux-mint/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://vocalinux.com/install/pop-os/</loc>
|
||||
<loc>https://voculinux.com/install/pop-os/</loc>
|
||||
<lastmod>2026-11-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 648 B After Width: | Height: | Size: 648 B |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Vocalinux idle">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Voculinux idle">
|
||||
<!-- Opaque disc for StatusNotifier trays (~22px) -->
|
||||
<circle cx="512" cy="512" r="480" fill="#0B1A15"/>
|
||||
<g transform="translate(28.386 32.619) scale(2.116474)">
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Vocalinux processing">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Voculinux processing">
|
||||
<!-- Opaque disc for StatusNotifier trays (~22px) -->
|
||||
<circle cx="512" cy="512" r="480" fill="#A86108"/>
|
||||
<g transform="translate(28.386 32.619) scale(2.116474)">
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Vocalinux recording">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Voculinux recording">
|
||||
<!-- Opaque disc for StatusNotifier trays (~22px) -->
|
||||
<circle cx="512" cy="512" r="480" fill="#C73D38"/>
|
||||
<g transform="translate(28.386 32.619) scale(2.116474)">
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 959 B After Width: | Height: | Size: 959 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -10,7 +10,7 @@ import { chromium } from "playwright-core";
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const pub = join(root, "public");
|
||||
const mark = join(pub, "brand/vocalinux-mark-circle.svg");
|
||||
const mark = join(pub, "brand/voculinux-mark-circle.svg");
|
||||
const chrome =
|
||||
process.env.CHROME_PATH ||
|
||||
["/usr/bin/chromium-browser", "/usr/bin/chromium"].find(Boolean);
|
||||
@@ -33,15 +33,15 @@ const skipIcons = process.env.OG_ONLY === "1";
|
||||
const sizes = [
|
||||
[16, join(pub, "favicon-16x16.png")],
|
||||
[32, join(pub, "favicon-32x32.png")],
|
||||
[32, join(pub, "vocalinux-32x32.png")],
|
||||
[64, join(pub, "vocalinux-64x64.png")],
|
||||
[32, join(pub, "voculinux-32x32.png")],
|
||||
[64, join(pub, "voculinux-64x64.png")],
|
||||
[96, join(pub, "favicon-96x96.png")],
|
||||
[96, join(pub, "vocalinux-96x96.png")],
|
||||
[192, join(pub, "vocalinux-192x192.png")],
|
||||
[96, join(pub, "voculinux-96x96.png")],
|
||||
[192, join(pub, "voculinux-192x192.png")],
|
||||
[192, join(pub, "icon-192x192.png")],
|
||||
[512, join(pub, "vocalinux-512x512.png")],
|
||||
[512, join(pub, "voculinux-512x512.png")],
|
||||
[512, join(pub, "icon-512x512.png")],
|
||||
[512, join(pub, "vocalinux.png")],
|
||||
[512, join(pub, "voculinux.png")],
|
||||
];
|
||||
|
||||
if (!skipIcons) {
|
||||
@@ -50,8 +50,8 @@ if (!skipIcons) {
|
||||
if (dest.endsWith(".png") && !dest.includes("favicon-")) {
|
||||
const webp = dest.replace(/\.png$/i, ".webp");
|
||||
if (
|
||||
dest.includes("vocalinux-") ||
|
||||
dest.endsWith("/vocalinux.png")
|
||||
dest.includes("voculinux-") ||
|
||||
dest.endsWith("/voculinux.png")
|
||||
) {
|
||||
toWebp(dest, webp);
|
||||
}
|
||||
@@ -119,7 +119,7 @@ const ogHtml = `<!doctype html>
|
||||
<div class="copy">
|
||||
<div class="brand">
|
||||
<img src="${markData}" alt="" />
|
||||
Vocalinux
|
||||
Voculinux
|
||||
</div>
|
||||
<h1>Dictate locally.<br><em>In any app.</em></h1>
|
||||
<p class="lede">Hold Right Alt. Text lands in the focused window. Local engines by default.</p>
|
||||
@@ -128,11 +128,11 @@ const ogHtml = `<!doctype html>
|
||||
<span>No telemetry</span>
|
||||
<span>AGPL-3.0</span>
|
||||
</div>
|
||||
<p class="url">vocalinux.com</p>
|
||||
<p class="url">voculinux.com</p>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="workbench">
|
||||
<div class="panel"><span>Vocalinux</span><span><i class="rec"></i>listening</span></div>
|
||||
<div class="panel"><span>Voculinux</span><span><i class="rec"></i>listening</span></div>
|
||||
<div class="window">
|
||||
<div class="titlebar"><span>notes.txt</span><span class="dots" aria-hidden="true"><i></i><i></i><i class="close"></i></span></div>
|
||||
<div class="body">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Viewport QA for the Vocalinux marketing home page.
|
||||
* Viewport QA for the Voculinux marketing home page.
|
||||
* Uses system Google Chrome via playwright-core (no browser download).
|
||||
*
|
||||
* Usage:
|
||||
@@ -74,7 +74,7 @@ try {
|
||||
scrollWidth: de.scrollWidth,
|
||||
clientWidth: de.clientWidth,
|
||||
overflowX,
|
||||
hasVocalinux: bodyText.includes("Vocalinux"),
|
||||
hasVoculinux: bodyText.includes("Voculinux"),
|
||||
hasInstallCta: !!document.querySelector('a[href="#install"]'),
|
||||
hasGradientText: !!document.querySelector('[class*="bg-clip-text"]'),
|
||||
h1: hero ? hero.innerText.trim() : null,
|
||||
@@ -128,7 +128,7 @@ try {
|
||||
|
||||
const ok =
|
||||
!metrics.overflowX &&
|
||||
metrics.hasVocalinux &&
|
||||
metrics.hasVoculinux &&
|
||||
metrics.hasInstallCta &&
|
||||
!metrics.hasGradientText &&
|
||||
metrics.heroInBounds &&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { OptimizedImage, VocalinuxLogo } from '../../components/optimized-image';
|
||||
import { OptimizedImage, VoculinuxLogo } from '../../components/optimized-image';
|
||||
|
||||
// Mock Next.js Image component to capture loading behavior
|
||||
const mockImage = jest.fn();
|
||||
@@ -61,17 +61,17 @@ describe('Lazy Loading Behavior', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('VocalinuxLogo Component', () => {
|
||||
describe('VoculinuxLogo Component', () => {
|
||||
it('lazy loads the circular mark by default', () => {
|
||||
render(<VocalinuxLogo />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
expect(img).toHaveAttribute('src', '/brand/vocalinux-mark-circle.svg');
|
||||
render(<VoculinuxLogo />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('src', '/brand/voculinux-mark-circle.svg');
|
||||
expect(img).toHaveAttribute('loading', 'lazy');
|
||||
});
|
||||
|
||||
it('eager loads the mark when priority is set', () => {
|
||||
render(<VocalinuxLogo priority />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo priority />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('loading', 'eager');
|
||||
});
|
||||
});
|
||||
@@ -86,8 +86,8 @@ describe('Lazy Loading Behavior', () => {
|
||||
});
|
||||
|
||||
it('prevents layout shift with explicit dimensions', () => {
|
||||
render(<VocalinuxLogo width={64} height={64} />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo width={64} height={64} />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('width', '64');
|
||||
expect(img).toHaveAttribute('height', '64');
|
||||
});
|
||||
@@ -106,9 +106,9 @@ describe('Lazy Loading Behavior', () => {
|
||||
});
|
||||
|
||||
it('ships the circular mark as an SVG', () => {
|
||||
render(<VocalinuxLogo width={32} height={32} />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
expect(img).toHaveAttribute('src', '/brand/vocalinux-mark-circle.svg');
|
||||
render(<VoculinuxLogo width={32} height={32} />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('src', '/brand/voculinux-mark-circle.svg');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,7 +41,7 @@ describe("Screenshots page and assets", () => {
|
||||
expect(fs.existsSync(pagePath)).toBe(true);
|
||||
expect(pageSource).toMatch(/export default function ScreenshotsPage/);
|
||||
expect(pageSource).toContain('path: "/screenshots"');
|
||||
expect(pageSource).toContain("Vocalinux Screenshots");
|
||||
expect(pageSource).toContain("Voculinux Screenshots");
|
||||
expect(pageSource).toContain("ScreenshotGallery");
|
||||
const galleryPath = path.join(
|
||||
webRoot,
|
||||
|
||||
@@ -15,7 +15,7 @@ describe("SEO Assets", () => {
|
||||
|
||||
it("contains sitemap reference in robots.txt", () => {
|
||||
expect(robotsContent).toContain(
|
||||
"Sitemap: https://vocalinux.com/sitemap.xml",
|
||||
"Sitemap: https://voculinux.com/sitemap.xml",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -39,33 +39,33 @@ describe("SEO Assets", () => {
|
||||
|
||||
it("includes core landing pages in sitemap", () => {
|
||||
const expectedUrls = [
|
||||
"https://vocalinux.com/",
|
||||
"https://vocalinux.com/install/",
|
||||
"https://vocalinux.com/install/ubuntu/",
|
||||
"https://vocalinux.com/install/fedora/",
|
||||
"https://vocalinux.com/install/arch/",
|
||||
"https://vocalinux.com/compare/",
|
||||
"https://vocalinux.com/remote-api/",
|
||||
"https://vocalinux.com/voice-activity-detection/",
|
||||
"https://vocalinux.com/advanced-settings/",
|
||||
"https://vocalinux.com/desktop-reliability/",
|
||||
"https://vocalinux.com/screenshots/",
|
||||
"https://vocalinux.com/parakeet/",
|
||||
"https://vocalinux.com/faster-whisper/",
|
||||
"https://vocalinux.com/dictation-pad/",
|
||||
"https://vocalinux.com/transcribe-audio-files/",
|
||||
"https://vocalinux.com/custom-dictionary/",
|
||||
"https://vocalinux.com/multilingual-dictation/",
|
||||
"https://vocalinux.com/pipewire/",
|
||||
"https://vocalinux.com/global-shortcuts/",
|
||||
"https://vocalinux.com/hyprland-sway/",
|
||||
"https://vocalinux.com/local-gateway/",
|
||||
"https://vocalinux.com/flatpak/",
|
||||
"https://vocalinux.com/install/nixos/",
|
||||
"https://vocalinux.com/install/debian/",
|
||||
"https://vocalinux.com/install/opensuse/",
|
||||
"https://vocalinux.com/install/linux-mint/",
|
||||
"https://vocalinux.com/install/pop-os/",
|
||||
"https://voculinux.com/",
|
||||
"https://voculinux.com/install/",
|
||||
"https://voculinux.com/install/ubuntu/",
|
||||
"https://voculinux.com/install/fedora/",
|
||||
"https://voculinux.com/install/arch/",
|
||||
"https://voculinux.com/compare/",
|
||||
"https://voculinux.com/remote-api/",
|
||||
"https://voculinux.com/voice-activity-detection/",
|
||||
"https://voculinux.com/advanced-settings/",
|
||||
"https://voculinux.com/desktop-reliability/",
|
||||
"https://voculinux.com/screenshots/",
|
||||
"https://voculinux.com/parakeet/",
|
||||
"https://voculinux.com/faster-whisper/",
|
||||
"https://voculinux.com/dictation-pad/",
|
||||
"https://voculinux.com/transcribe-audio-files/",
|
||||
"https://voculinux.com/custom-dictionary/",
|
||||
"https://voculinux.com/multilingual-dictation/",
|
||||
"https://voculinux.com/pipewire/",
|
||||
"https://voculinux.com/global-shortcuts/",
|
||||
"https://voculinux.com/hyprland-sway/",
|
||||
"https://voculinux.com/local-gateway/",
|
||||
"https://voculinux.com/flatpak/",
|
||||
"https://voculinux.com/install/nixos/",
|
||||
"https://voculinux.com/install/debian/",
|
||||
"https://voculinux.com/install/opensuse/",
|
||||
"https://voculinux.com/install/linux-mint/",
|
||||
"https://voculinux.com/install/pop-os/",
|
||||
];
|
||||
|
||||
expectedUrls.forEach((url) => {
|
||||
@@ -87,7 +87,7 @@ describe("SEO Assets", () => {
|
||||
}
|
||||
const routePath = `${prefix}/${entry.name}`;
|
||||
if (fs.existsSync(path.join(dir, entry.name, "page.tsx"))) {
|
||||
routes.push(`https://vocalinux.com${routePath}/`);
|
||||
routes.push(`https://voculinux.com${routePath}/`);
|
||||
}
|
||||
walk(path.join(dir, entry.name), routePath);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ describe("marketing home three-viewport overflow (live browser)", () => {
|
||||
heroInBounds: inBounds(heroRect),
|
||||
terminalInBounds: inBounds(termRect),
|
||||
hasGradientText: !!document.querySelector('[class*="bg-clip-text"]'),
|
||||
hasVocalinux: document.body.innerText.includes("Vocalinux"),
|
||||
hasVoculinux: document.body.innerText.includes("Voculinux"),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -137,7 +137,7 @@ describe("marketing home three-viewport overflow (live browser)", () => {
|
||||
heroInBounds: true,
|
||||
terminalInBounds: true,
|
||||
hasGradientText: false,
|
||||
hasVocalinux: true,
|
||||
hasVoculinux: true,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -64,12 +64,12 @@ const useCases = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Advanced Whisper.cpp Settings for Linux Dictation",
|
||||
description:
|
||||
"Tune Vocalinux advanced whisper.cpp settings for anti-hallucination, decoding thresholds, initial prompts, and Remote API configuration.",
|
||||
"Tune Voculinux advanced whisper.cpp settings for anti-hallucination, decoding thresholds, initial prompts, and Remote API configuration.",
|
||||
path: "/advanced-settings",
|
||||
keywords: [
|
||||
"whisper.cpp advanced settings",
|
||||
"whisper anti hallucination linux dictation",
|
||||
"vocalinux advanced settings",
|
||||
"voculinux advanced settings",
|
||||
"whisper.cpp no speech threshold",
|
||||
],
|
||||
});
|
||||
@@ -80,7 +80,7 @@ export default function AdvancedSettingsPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Advanced Whisper.cpp Settings for Linux Dictation",
|
||||
description:
|
||||
"Guide to Vocalinux advanced settings for whisper.cpp decoding, anti-hallucination controls, and Remote API configuration.",
|
||||
"Guide to Voculinux advanced settings for whisper.cpp decoding, anti-hallucination controls, and Remote API configuration.",
|
||||
dateModified: "2026-06-11",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -89,10 +89,10 @@ export default function AdvancedSettingsPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/advanced-settings"),
|
||||
@@ -114,7 +114,7 @@ export default function AdvancedSettingsPage() {
|
||||
Advanced Whisper.cpp Settings for Linux Dictation
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux keeps the default setup simple, but power users can unlock
|
||||
Voculinux keeps the default setup simple, but power users can unlock
|
||||
advanced whisper.cpp decoding controls for anti-hallucination tuning,
|
||||
initial prompts, Remote API server configuration, Vulkan GPU device
|
||||
selection, and optional model keep-alive unload.
|
||||
|
||||
@@ -43,25 +43,25 @@ const alternatives = [
|
||||
];
|
||||
|
||||
const comparisonTable = [
|
||||
{ feature: "Linux Support", vocalinux: true, dragon: false, otter: false, google: true },
|
||||
{ feature: "Local engines", 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 },
|
||||
{ feature: "Linux Support", voculinux: true, dragon: false, otter: false, google: true },
|
||||
{ feature: "Local engines", voculinux: true, dragon: false, otter: false, google: false },
|
||||
{ feature: "Open Source", voculinux: true, dragon: false, otter: false, google: false },
|
||||
{ feature: "Free Forever", voculinux: true, dragon: false, otter: false, google: true },
|
||||
{ feature: "Desktop Integration", voculinux: true, dragon: true, otter: false, google: false },
|
||||
{ feature: "Wayland Support", voculinux: true, dragon: false, otter: false, google: false },
|
||||
{ feature: "Custom Shortcuts", voculinux: true, dragon: true, otter: false, google: false },
|
||||
{ feature: "Voice Commands", voculinux: true, dragon: true, otter: true, google: true },
|
||||
{ feature: "Multi-language", voculinux: true, dragon: true, otter: true, google: true },
|
||||
{ feature: "GPU Acceleration", voculinux: true, dragon: false, otter: false, google: false },
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Linux Alternatives to Dragon, Otter.ai and Speechnotes",
|
||||
description:
|
||||
"Looking for Dragon NaturallySpeaking, Otter.ai or Google Voice Typing on Linux? Compare offline Linux dictation options, including Vocalinux and Nerd Dictation.",
|
||||
"Looking for Dragon NaturallySpeaking, Otter.ai or Google Voice Typing on Linux? Compare offline Linux dictation options, including Voculinux and Nerd Dictation.",
|
||||
path: "/alternatives",
|
||||
keywords: [
|
||||
"vocalinux alternatives",
|
||||
"voculinux alternatives",
|
||||
"dragon naturally speaking linux alternative",
|
||||
"otter.ai alternative",
|
||||
"linux speech to text comparison",
|
||||
@@ -73,9 +73,9 @@ export default function AlternativesPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux vs Dragon, Otter, Google - Voice Dictation Comparison",
|
||||
headline: "Voculinux vs Dragon, Otter, Google - Voice Dictation Comparison",
|
||||
description:
|
||||
"Comprehensive comparison of Vocalinux with other voice dictation solutions for Linux users.",
|
||||
"Comprehensive comparison of Voculinux with other voice dictation solutions for Linux users.",
|
||||
dateModified: "2026-02-19",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -84,10 +84,10 @@ export default function AlternativesPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/alternatives"),
|
||||
@@ -106,16 +106,16 @@ export default function AlternativesPage() {
|
||||
Comparison
|
||||
</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Vocalinux vs The Alternatives
|
||||
Voculinux 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.
|
||||
Looking for voice dictation on Linux? Compare Voculinux with Dragon, Otter.ai, Google Voice
|
||||
Typing, and other alternatives. See why Voculinux is the best choice for Linux users.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="mb-12 rounded-[12px] border border-primary/20 bg-primary/5 p-6">
|
||||
<h2 className="mb-4 text-xl font-semibold">Why Vocalinux for Linux?</h2>
|
||||
<h2 className="mb-4 text-xl font-semibold">Why Voculinux 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" />
|
||||
@@ -142,7 +142,7 @@ export default function AlternativesPage() {
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<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">Voculinux</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>
|
||||
@@ -153,7 +153,7 @@ export default function AlternativesPage() {
|
||||
<tr key={row.feature} className="border-b border-border">
|
||||
<td className="py-3 font-medium">{row.feature}</td>
|
||||
<td className="py-3">
|
||||
{row.vocalinux ? (
|
||||
{row.voculinux ? (
|
||||
<CheckCircle2 className="h-5 w-5 text-primary" aria-label="Yes" />
|
||||
) : (
|
||||
<XCircle
|
||||
@@ -278,7 +278,7 @@ export default function AlternativesPage() {
|
||||
<section className="mt-12 rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">The Bottom Line</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
If you are on Linux and need voice dictation, Vocalinux is a strong option: local
|
||||
If you are on Linux and need voice dictation, Voculinux is a strong option: local
|
||||
engines, no usage telemetry, and desktop integration, at no cost. See the{" "}
|
||||
<Link href="/vs-nerd-dictation/" className="font-semibold hover:underline">
|
||||
nerd-dictation comparison
|
||||
@@ -290,7 +290,7 @@ export default function AlternativesPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -58,7 +58,7 @@ const desktopEnvironments = [
|
||||
const howItWorks = [
|
||||
{
|
||||
step: 1,
|
||||
title: "Enable in Vocalinux",
|
||||
title: "Enable in Voculinux",
|
||||
description:
|
||||
"Answer yes on the first-run prompt, or open Settings → General and turn on 'Start on Login'.",
|
||||
code: null,
|
||||
@@ -66,13 +66,13 @@ const howItWorks = [
|
||||
{
|
||||
step: 2,
|
||||
title: "Desktop Entry Created",
|
||||
description: "Vocalinux creates a .desktop file in your autostart directory:",
|
||||
code: "~/.config/autostart/vocalinux.desktop",
|
||||
description: "Voculinux creates a .desktop file in your autostart directory:",
|
||||
code: "~/.config/autostart/voculinux.desktop",
|
||||
},
|
||||
{
|
||||
step: 3,
|
||||
title: "Auto-launch on Login",
|
||||
description: "Your desktop environment reads this file and launches Vocalinux when you log in.",
|
||||
description: "Your desktop environment reads this file and launches Voculinux when you log in.",
|
||||
code: null,
|
||||
},
|
||||
];
|
||||
@@ -96,9 +96,9 @@ const managementMethods = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Autostart Voice Dictation on Linux Login | Vocalinux",
|
||||
title: "Autostart Voice Dictation on Linux Login | Voculinux",
|
||||
description:
|
||||
"Configure Vocalinux to start automatically when you log in to Linux. XDG autostart support for GNOME, KDE, Xfce, and all major desktop environments.",
|
||||
"Configure Voculinux to start automatically when you log in to Linux. XDG autostart support for GNOME, KDE, Xfce, and all major desktop environments.",
|
||||
path: "/autostart",
|
||||
keywords: [
|
||||
"Linux autostart voice dictation",
|
||||
@@ -117,7 +117,7 @@ export default function AutostartPage() {
|
||||
"@type": "Article",
|
||||
headline: "Autostart Voice Dictation on Linux Login",
|
||||
description:
|
||||
"How to configure Vocalinux to start automatically on Linux login. XDG autostart guide for all desktop environments.",
|
||||
"How to configure Voculinux to start automatically on Linux login. XDG autostart guide for all desktop environments.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -126,10 +126,10 @@ export default function AutostartPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/autostart"),
|
||||
@@ -151,7 +151,7 @@ export default function AutostartPage() {
|
||||
Autostart Voice Dictation on Login
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Have Vocalinux ready to go the moment you log in. Uses the Linux-standard XDG autostart
|
||||
Have Voculinux ready to go the moment you log in. Uses the Linux-standard XDG autostart
|
||||
mechanism - works with GNOME, KDE, Xfce, and all major desktop environments.
|
||||
</p>
|
||||
</section>
|
||||
@@ -200,7 +200,7 @@ export default function AutostartPage() {
|
||||
<section className="mb-12 rounded-[12px] border border-border bg-background p-6">
|
||||
<h2 className="mb-6 font-display text-2xl font-semibold">Desktop Environment Compatibility</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Vocalinux uses the XDG Autostart specification, which is supported by virtually all Linux
|
||||
Voculinux uses the XDG Autostart specification, which is supported by virtually all Linux
|
||||
desktop environments:
|
||||
</p>
|
||||
<div className="overflow-x-auto">
|
||||
@@ -250,7 +250,7 @@ export default function AutostartPage() {
|
||||
Not a systemd Service
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Vocalinux autostart uses <strong>XDG desktop entries</strong>, not systemd services. This
|
||||
Voculinux autostart uses <strong>XDG desktop entries</strong>, not systemd services. This
|
||||
means it starts as a regular desktop application in your graphical session - which is the
|
||||
correct way to launch GUI apps. No background services, no root required.
|
||||
</p>
|
||||
@@ -266,7 +266,7 @@ export default function AutostartPage() {
|
||||
<p className="mb-1 text-sm font-medium">Enable autostart:</p>
|
||||
<div className="rounded-lg bg-[color:var(--terminal)] p-3">
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">
|
||||
mkdir -p ~/.config/autostart && cp /usr/share/applications/vocalinux.desktop
|
||||
mkdir -p ~/.config/autostart && cp /usr/share/applications/voculinux.desktop
|
||||
~/.config/autostart/
|
||||
</code>
|
||||
</div>
|
||||
@@ -274,14 +274,14 @@ export default function AutostartPage() {
|
||||
<div>
|
||||
<p className="mb-1 text-sm font-medium">Disable autostart:</p>
|
||||
<div className="rounded-lg bg-[color:var(--terminal)] p-3">
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">rm ~/.config/autostart/vocalinux.desktop</code>
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">rm ~/.config/autostart/voculinux.desktop</code>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="mb-1 text-sm font-medium">Start minimized (skip welcome dialog):</p>
|
||||
<div className="rounded-lg bg-[color:var(--terminal)] p-3">
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">
|
||||
vocalinux --start-minimized
|
||||
voculinux --start-minimized
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -291,7 +291,7 @@ export default function AutostartPage() {
|
||||
<section className="rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Ready to Automate?</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux and enable autostart. Your voice dictation will be ready the moment you
|
||||
Install Voculinux and enable autostart. Your voice dictation will be ready the moment you
|
||||
log in.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
|
||||
@@ -113,7 +113,7 @@ const releases = [
|
||||
"Model downloads cancel stalled fetches; the download dialog shows verifying instead of a stalled 100% (PR #888, #864, fixes #679, #863)",
|
||||
"Update checker falls back when GitHub API rate-limits (PR #846, fixes #845)",
|
||||
"Settings: scrollable category list, Dictation Tone grayed while sounds are off, Test Dictation artifact and missing transcription fixed (PR #886, #877, #853, fixes #678, #849, #847, #720)",
|
||||
"AUR vocalinux-bin ships the AppImage with per-arch digests; releases publish a signed self-hosted Flatpak remote; snap-promote workflow gates stable promotion; snap gains hardware-observe (PR #879, #875, #881, #858, fixes #817, #785, #783, #857)",
|
||||
"AUR voculinux-bin ships the AppImage with per-arch digests; releases publish a signed self-hosted Flatpak remote; snap-promote workflow gates stable promotion; snap gains hardware-observe (PR #879, #875, #881, #858, fixes #817, #785, #783, #857)",
|
||||
"Installer: hash-pinned dependencies and build tools, sourced modules, generated distro package map (PR #856, #862, #872)",
|
||||
"Optional verified Orukeet model for Parakeet; VocaGateway runs locally from Settings > Advanced (PR #840, #774)",
|
||||
],
|
||||
@@ -132,7 +132,7 @@ const releases = [
|
||||
"Localized punctuation voice commands for it/fr/de/es/pt/nl/pl/ru (PR #642, #640)",
|
||||
"Bare F1–F24 push-to-talk shortcuts (PR #815)",
|
||||
"Snap packaging with ydotool and uinput for native Wayland; the Store denied the uinput grant, so later revisions drop the plug and type via the RemoteDesktop portal (PR #519, #823, #822)",
|
||||
"Release workflow attaches Vocalinux-<version>-{x86_64,aarch64}.flatpak (PR #786, #784)",
|
||||
"Release workflow attaches Voculinux-<version>-{x86_64,aarch64}.flatpak (PR #786, #784)",
|
||||
"XWayland clipboard paste instead of layout-garbled xdotool type (PR #680, #657)",
|
||||
"Layout-aware Ctrl+V paste; ydotool releases Ctrl after a timed-out paste (PR #788, #675, #658)",
|
||||
"Read WM_CLASS with xprop so xdotool stops dumping core on KDE Plasma Wayland (PR #807)",
|
||||
@@ -160,7 +160,7 @@ const releases = [
|
||||
"CI: gate AUR PKGBUILD builds on every PR; test the distros the docs promise and fix docs drift (PR #772, #773)",
|
||||
"Site: VocaGateway family card is Beta; README logo, badges, and privacy copy (PR #765, #764)",
|
||||
"Deps: bump the github-actions group (PR #766)",
|
||||
"Snap 0.16.2 edge (rev 7) has no uinput plug: snap connect vocalinux:uinput fails, and dictation only reaches XWayland apps. Later revisions ship the RemoteDesktop portal instead; the Store denied the uinput grant (PR #823)",
|
||||
"Snap 0.16.2 edge (rev 7) has no uinput plug: snap connect voculinux:uinput fails, and dictation only reaches XWayland apps. Later revisions ship the RemoteDesktop portal instead; the Store denied the uinput grant (PR #823)",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -194,7 +194,7 @@ const releases = [
|
||||
"IBus/X11 reliability: restorable scoped injection, engine restore after teardown, XKB layout restore (PR #623, #643, #665)",
|
||||
"Audio, clipboard, and AppImage/GPU packaging fixes (PR #629, #673, #588, #646, #674, #637)",
|
||||
"Settings About page groups this app, the VocaHQ family, and talk-to-us links (PR #718)",
|
||||
"vocalinux.com restyled to the Voca family workbench; Discord and X links point at VocaHQ (PR #728, #729, #722, #717)",
|
||||
"voculinux.com restyled to the Voca family workbench; Discord and X links point at VocaHQ (PR #728, #729, #722, #717)",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -213,7 +213,7 @@ const releases = [
|
||||
"Vulkan: auto-select discrete GPU and pick a device in Advanced settings (PR #590, closes #589)",
|
||||
"Wayland: use IBus on previously unbridged compositors when ibus-wayland is running (PR #614, closes #607)",
|
||||
"IBus: keep engine teardown correct when parent destroy fails (PR #613, fixes #606)",
|
||||
"CLI: vocalinux --version (PR #563, closes #555)",
|
||||
"CLI: voculinux --version (PR #563, closes #555)",
|
||||
"Settings info notices flattened; Bluetooth mic heap-corruption fix; KDE unbridged-IBus skip when ibus-wayland is absent; xdotool focus preserve; installer/AUR fixes (PR #615, #599, #577, #564, #583, #569, #597, #579, #586)",
|
||||
"Marketing site redesign; languages page per-engine badges; robots.txt indexing fix (PR #582, #616, #610)",
|
||||
],
|
||||
@@ -265,8 +265,8 @@ const releases = [
|
||||
highlights: [
|
||||
"Guided whisper.cpp model selection: pick a size plus a specialization (English-only, quantized Q5/Q8, or Large v3 Turbo) through split Model Size and Specialization dropdowns with in-app guidance; the --model flag also accepts exact IDs like medium.en-q5_0 and large-v3-turbo (PR #465)",
|
||||
"Dictation now keeps a space between segments spoken with a pause in between, so words no longer run together after a silence (PR #464)",
|
||||
"Keyboard shortcuts now work on keyboards hotplugged after Vocalinux starts, with the evdev backend rescanning for new devices and recovering from disconnects (PR #467)",
|
||||
"Vocalinux now detects KDE Plasma Wayland sessions and points you to enable IBus Wayland for reliable text injection, surfaced during install and when wtype injection fails (PR #466)",
|
||||
"Keyboard shortcuts now work on keyboards hotplugged after Voculinux starts, with the evdev backend rescanning for new devices and recovering from disconnects (PR #467)",
|
||||
"Voculinux now detects KDE Plasma Wayland sessions and points you to enable IBus Wayland for reliable text injection, surfaced during install and when wtype injection fails (PR #466)",
|
||||
"Wayland: fixed garbled text on non-US keyboard layouts (AZERTY/QWERTZ/Dvorak) and a clipboard-copy hang; ydotool now pastes through the clipboard, which is layout-independent (PR #480)",
|
||||
"Wayland: use wtype/ydotool instead of IBus on compositors that don't bridge it to native apps like COSMIC, Sway, and Hyprland, fixing silent text drops (PR #486)",
|
||||
"Wayland/IBus: require a real IM engine before using IBus, so a bare xkb layout no longer causes silent text drops on GNOME/Mutter and other compositors (#478)",
|
||||
@@ -329,7 +329,7 @@ const releases = [
|
||||
"Add missing dependencies for Pop!_OS and Ubuntu 24.04+ including cmake, libcairo2-dev, libgirepository (PR #379)",
|
||||
"Systematic code quality refactor across 20 dimensions (PR #377)",
|
||||
"Clarify missing GNOME AppIndicator support on Debian (PR #385)",
|
||||
"Redesigned OG image for vocalinux.com - cleaner, professional, text-based layout (PR #392)",
|
||||
"Redesigned OG image for voculinux.com - cleaner, professional, text-based layout (PR #392)",
|
||||
"Test coverage improvements: mock Notify module, tray degraded-startup, IBus socket-readiness branches (PR #384, #386, #390)",
|
||||
],
|
||||
},
|
||||
@@ -341,7 +341,7 @@ const releases = [
|
||||
"Bundled package resources to prevent missing system tray icons (fixes #349, PR #354)",
|
||||
"Stopped recognition before engine switches to prevent segfaults (fixes #350, PR #355)",
|
||||
"Added a dedicated Close button in Settings for better WM compatibility (fixes #323, PR #356)",
|
||||
"Preserved XKB layout state during Vocalinux IBus activation (fixes #292, PR #343)",
|
||||
"Preserved XKB layout state during Voculinux IBus activation (fixes #292, PR #343)",
|
||||
"Auto-recover speech recognition after system suspend/resume via new D-Bus handler (fixes #367, PR #369)",
|
||||
"Restart keyboard shortcut backend after resume to keep shortcuts working (PR #371)",
|
||||
"Delayed keyboard restart to allow USB re-enumeration after resume (PR #372)",
|
||||
@@ -402,7 +402,7 @@ const releases = [
|
||||
"Autostart on login support (XDG autostart)",
|
||||
"Tabbed settings dialog (Speech Engine, Recognition, Text Injection, Audio Feedback, General)",
|
||||
"Intel GPU compatibility detection - auto fallback to CPU for incompatible GPUs",
|
||||
"Single instance prevention - prevents multiple Vocalinux running",
|
||||
"Single instance prevention - prevents multiple Voculinux running",
|
||||
"Evdev device management - removes disconnected devices to prevent CPU spin",
|
||||
"Improved GPU detection - avoids false positives on systems without dev libraries",
|
||||
"IBus fallback - skip setup when daemon not running",
|
||||
@@ -521,11 +521,11 @@ const getTypeStyles = (type: string) => {
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Changelog and Release Notes",
|
||||
description:
|
||||
"Track Vocalinux release history and version updates. See what's new in each version of our Linux voice dictation software.",
|
||||
"Track Voculinux 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",
|
||||
"voculinux changelog",
|
||||
"voculinux release notes",
|
||||
"voice dictation linux updates",
|
||||
"speech to text linux versions",
|
||||
],
|
||||
@@ -535,9 +535,9 @@ export default function ChangelogPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux Changelog - Release History",
|
||||
headline: "Voculinux Changelog - Release History",
|
||||
description:
|
||||
"Complete release history for Vocalinux, the offline voice dictation software for Linux.",
|
||||
"Complete release history for Voculinux, the offline voice dictation software for Linux.",
|
||||
dateModified: "2026-10-27",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -546,10 +546,10 @@ export default function ChangelogPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/changelog"),
|
||||
@@ -568,10 +568,10 @@ export default function ChangelogPage() {
|
||||
Release History
|
||||
</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Vocalinux Changelog
|
||||
Voculinux 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
|
||||
Track every release and see how Voculinux has evolved. From initial
|
||||
alpha to stable releases, follow the journey of Linux voice dictation.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const engineTable = [
|
||||
{
|
||||
engine: "whisper.cpp",
|
||||
support: "Guaranteed default",
|
||||
speed: "Fastest startup + low latency",
|
||||
hardware: "CPU + AMD/Intel/NVIDIA GPU",
|
||||
accuracy: "High (best overall balance)",
|
||||
@@ -25,6 +26,7 @@ const engineTable = [
|
||||
},
|
||||
{
|
||||
engine: "Whisper (OpenAI)",
|
||||
support: "Best-effort extra",
|
||||
speed: "Slower install and startup",
|
||||
hardware: "CPU or NVIDIA CUDA",
|
||||
accuracy: "High",
|
||||
@@ -36,6 +38,7 @@ const engineTable = [
|
||||
},
|
||||
{
|
||||
engine: "Faster Whisper",
|
||||
support: "Best-effort extra",
|
||||
speed: "Fast CPU inference (CTranslate2 / INT8)",
|
||||
hardware: "CPU",
|
||||
accuracy: "High (Whisper-class)",
|
||||
@@ -47,6 +50,7 @@ const engineTable = [
|
||||
},
|
||||
{
|
||||
engine: "VOSK",
|
||||
support: "Best-effort extra",
|
||||
speed: "Very fast realtime on low-end systems",
|
||||
hardware: "CPU",
|
||||
accuracy: "Good for lightweight use",
|
||||
@@ -58,6 +62,7 @@ const engineTable = [
|
||||
},
|
||||
{
|
||||
engine: "Parakeet",
|
||||
support: "Best-effort extra",
|
||||
speed: "Fast CPU (sherpa-onnx TDT 0.6B)",
|
||||
hardware: "CPU",
|
||||
accuracy: "High on bundled English / European languages",
|
||||
@@ -69,6 +74,7 @@ const engineTable = [
|
||||
},
|
||||
{
|
||||
engine: "Remote API",
|
||||
support: "User-configured (audio leaves the machine)",
|
||||
speed: "Depends on server + network latency",
|
||||
hardware: "Client CPU + remote Whisper server",
|
||||
accuracy: "Depends on remote model",
|
||||
@@ -110,10 +116,10 @@ export default function CompareEnginesPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/compare"),
|
||||
@@ -138,6 +144,9 @@ export default function CompareEnginesPage() {
|
||||
If you are choosing a Linux speech-to-text engine, this page gives a
|
||||
practical side-by-side comparison focused on latency, hardware
|
||||
support, install footprint, privacy boundary, and real desktop usage.
|
||||
whisper.cpp is the guaranteed default engine; every other local
|
||||
engine is a best-effort extra. Remote API is user-configured: audio
|
||||
leaves the machine for a server you choose.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -157,6 +166,7 @@ export default function CompareEnginesPage() {
|
||||
</div>
|
||||
<dl className="grid gap-3 text-sm">
|
||||
{[
|
||||
["Support", row.support],
|
||||
["Speed", row.speed],
|
||||
["Hardware", row.hardware],
|
||||
["Accuracy", row.accuracy],
|
||||
@@ -181,6 +191,7 @@ export default function CompareEnginesPage() {
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<th className="px-4 py-3 text-sm font-semibold">Engine</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Support</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Speed</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Hardware</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Accuracy</th>
|
||||
@@ -206,6 +217,9 @@ export default function CompareEnginesPage() {
|
||||
{row.engine}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-4 text-sm text-muted-foreground">
|
||||
{row.support}
|
||||
</td>
|
||||
<td className="px-4 py-4 text-sm text-muted-foreground">
|
||||
{row.speed}
|
||||
</td>
|
||||
@@ -247,7 +261,7 @@ export default function CompareEnginesPage() {
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Choose whisper.cpp when you want the best speed-to-accuracy ratio
|
||||
and broad hardware support. It is the default in Vocalinux for a
|
||||
and broad hardware support. It is the default in Voculinux for a
|
||||
reason. Safe engine switching - v0.10.1+ stops recognition before
|
||||
switching to prevent crashes.
|
||||
</p>
|
||||
|
||||
@@ -14,7 +14,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const PAGE_PATH = "/custom-dictionary";
|
||||
|
||||
const dictionaryFileCommand =
|
||||
"vocalinux --dictionary-file /path/to/dictionary.txt";
|
||||
"voculinux --dictionary-file /path/to/dictionary.txt";
|
||||
|
||||
const howToSteps = [
|
||||
{
|
||||
@@ -62,18 +62,18 @@ const faqs = [
|
||||
},
|
||||
{
|
||||
q: "My post-processing script runs but nothing changes. What should I check?",
|
||||
a: "Vocalinux falls back to the original text when the script exits non-zero, cannot be started, or runs longer than 10 seconds. Make sure the file is executable, the path is absolute, and the script writes to standard output. The Vocalinux log records the exit code and standard error.",
|
||||
a: "Voculinux falls back to the original text when the script exits non-zero, cannot be started, or runs longer than 10 seconds. Make sure the file is executable, the path is absolute, and the script writes to standard output. The Voculinux log records the exit code and standard error.",
|
||||
},
|
||||
{
|
||||
q: "Why did a segment disappear after I added a script?",
|
||||
a: "If the script exits successfully but prints nothing, Vocalinux types nothing for that segment. Make sure every code path writes the text back out.",
|
||||
a: "If the script exits successfully but prints nothing, Voculinux types nothing for that segment. Make sure every code path writes the text back out.",
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Custom Dictionary, Corrections and Post-Processing | Vocalinux",
|
||||
title: "Custom Dictionary, Corrections and Post-Processing | Voculinux",
|
||||
description:
|
||||
"Teach Vocalinux your jargon: custom terms that bias Whisper, transcript corrections for every engine, and a stdin/stdout post-processing script hook.",
|
||||
"Teach Voculinux your jargon: custom terms that bias Whisper, transcript corrections for every engine, and a stdin/stdout post-processing script hook.",
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"custom dictionary voice dictation Linux",
|
||||
@@ -81,7 +81,7 @@ export const metadata: Metadata = buildPageMetadata({
|
||||
"whisper.cpp initial prompt terms",
|
||||
"speech to text corrections",
|
||||
"dictation post-processing script",
|
||||
"Vocalinux custom dictionary",
|
||||
"Voculinux custom dictionary",
|
||||
],
|
||||
});
|
||||
|
||||
@@ -90,9 +90,9 @@ export default function CustomDictionaryPage() {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
headline:
|
||||
"Custom Dictionary, Transcript Corrections and Post-Processing in Vocalinux",
|
||||
"Custom Dictionary, Transcript Corrections and Post-Processing in Voculinux",
|
||||
description:
|
||||
"How Vocalinux custom terms, transcript corrections and the post-processing script hook work, with exact file formats and safe example scripts.",
|
||||
"How Voculinux custom terms, transcript corrections and the post-processing script hook work, with exact file formats and safe example scripts.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -101,10 +101,10 @@ export default function CustomDictionaryPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
@@ -113,7 +113,7 @@ export default function CustomDictionaryPage() {
|
||||
const howToJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Set up a custom dictionary in Vocalinux",
|
||||
name: "Set up a custom dictionary in Voculinux",
|
||||
step: howToSteps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -154,7 +154,7 @@ export default function CustomDictionaryPage() {
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Speech models stumble on product names, colleagues' names and
|
||||
project jargon. Vocalinux gives you three tools for that: custom terms
|
||||
project jargon. Voculinux gives you three tools for that: custom terms
|
||||
that steer Whisper-family engines toward your vocabulary, transcript
|
||||
corrections that fix known mishearings on every engine, and a script
|
||||
hook that can rewrite each result before it is typed.
|
||||
@@ -233,14 +233,14 @@ export default function CustomDictionaryPage() {
|
||||
Custom terms file
|
||||
</h2>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
Terms live in <code>~/.config/vocalinux/dictionary.txt</code> by
|
||||
Terms live in <code>~/.config/voculinux/dictionary.txt</code> by
|
||||
default: UTF-8, one term per line. Blank lines and lines starting with{" "}
|
||||
<code>#</code> are skipped, and duplicates are ignored regardless of
|
||||
case. The plain line format is deliberate, so accessibility tools and
|
||||
scripts can maintain the same file.
|
||||
</p>
|
||||
<pre className="subpage-terminal mb-4 overflow-x-auto p-4">
|
||||
<code>{`# ~/.config/vocalinux/dictionary.txt
|
||||
<code>{`# ~/.config/voculinux/dictionary.txt
|
||||
Supabase
|
||||
Kubernetes
|
||||
PipeWire
|
||||
@@ -267,7 +267,7 @@ Okonkwo`}</code>
|
||||
<h3 className="mb-2 font-semibold">Session-only terms file</h3>
|
||||
<p className="mb-3 text-muted-foreground">
|
||||
To try a different list without touching saved settings, start
|
||||
Vocalinux with:
|
||||
Voculinux with:
|
||||
</p>
|
||||
<TerminalBlock
|
||||
command={dictionaryFileCommand}
|
||||
@@ -286,7 +286,7 @@ Okonkwo`}</code>
|
||||
</h2>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
Corrections are stored separately in{" "}
|
||||
<code>~/.config/vocalinux/custom-dictionary-corrections.json</code>,
|
||||
<code>~/.config/voculinux/custom-dictionary-corrections.json</code>,
|
||||
always in the config directory, whatever terms file you use. The
|
||||
format is versioned:
|
||||
</p>
|
||||
@@ -328,7 +328,7 @@ Okonkwo`}</code>
|
||||
</h2>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
The path is saved as <code>post_processing.script_path</code> (empty
|
||||
means off). For each completed segment, Vocalinux runs the file like
|
||||
means off). For each completed segment, Voculinux runs the file like
|
||||
this:
|
||||
</p>
|
||||
<div className="mb-4 overflow-x-auto rounded-[12px] border border-border bg-background p-6">
|
||||
@@ -349,7 +349,7 @@ Okonkwo`}</code>
|
||||
],
|
||||
[
|
||||
"Environment",
|
||||
"Inherits Vocalinux's environment. When Vocalinux runs from the AppImage, the bundle's library paths are removed first.",
|
||||
"Inherits Voculinux's environment. When Voculinux runs from the AppImage, the bundle's library paths are removed first.",
|
||||
],
|
||||
["Timeout", "10 seconds."],
|
||||
[
|
||||
@@ -374,7 +374,7 @@ Okonkwo`}</code>
|
||||
</div>
|
||||
<h3 className="mb-2 font-semibold">Example: uppercase everything</h3>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
The example from the Vocalinux user guide. Make it executable with{" "}
|
||||
The example from the Voculinux user guide. Make it executable with{" "}
|
||||
<code>chmod +x</code> before setting the path.
|
||||
</p>
|
||||
<pre className="subpage-terminal mb-4 overflow-x-auto p-4">
|
||||
@@ -386,7 +386,7 @@ tr '[:lower:]' '[:upper:]'`}</code>
|
||||
</h3>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Reads everything from stdin and writes it back without adding a
|
||||
newline. Any exception exits non-zero, so Vocalinux falls back to the
|
||||
newline. Any exception exits non-zero, so Voculinux falls back to the
|
||||
original text.
|
||||
</p>
|
||||
<pre className="subpage-terminal mb-4 overflow-x-auto p-4">
|
||||
@@ -397,7 +397,7 @@ text = sys.stdin.read()
|
||||
sys.stdout.write(text.replace("'", "\\u2019"))`}</code>
|
||||
</pre>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Before pointing Vocalinux at a script, pipe a sample sentence into it
|
||||
Before pointing Voculinux at a script, pipe a sample sentence into it
|
||||
from a terminal and check that it prints the text back. Output is not
|
||||
written to the log, but anything your script does with the text
|
||||
(files, network calls) is up to the script.
|
||||
@@ -435,7 +435,7 @@ sys.stdout.write(text.replace("'", "\\u2019"))`}</code>
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -18,7 +18,7 @@ const reliabilityFeatures = [
|
||||
{
|
||||
title: "Suspend and resume recovery",
|
||||
description:
|
||||
"Vocalinux restarts recognition and shortcut backends after wake so laptop sleep cycles do not require a manual app restart.",
|
||||
"Voculinux restarts recognition and shortcut backends after wake so laptop sleep cycles do not require a manual app restart.",
|
||||
icon: Power,
|
||||
},
|
||||
{
|
||||
@@ -109,12 +109,12 @@ const releaseMap = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Linux Desktop Dictation Reliability - IBus, Wayland, Suspend",
|
||||
description:
|
||||
"See how Vocalinux handles Linux desktop reliability across IBus, Wayland, suspend/resume recovery, keyboard layouts, tray resources, and non-ASCII text injection.",
|
||||
"See how Voculinux handles Linux desktop reliability across IBus, Wayland, suspend/resume recovery, keyboard layouts, tray resources, and non-ASCII text injection.",
|
||||
path: "/desktop-reliability",
|
||||
keywords: [
|
||||
"linux dictation reliability",
|
||||
"ibus voice dictation wayland",
|
||||
"vocalinux suspend resume",
|
||||
"voculinux suspend resume",
|
||||
"wayland text injection reliability",
|
||||
],
|
||||
});
|
||||
@@ -125,7 +125,7 @@ export default function DesktopReliabilityPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Linux Desktop Dictation Reliability",
|
||||
description:
|
||||
"Reliability improvements in Vocalinux for IBus, Wayland, suspend/resume, keyboard layout preservation, and text injection.",
|
||||
"Reliability improvements in Voculinux for IBus, Wayland, suspend/resume, keyboard layout preservation, and text injection.",
|
||||
dateModified: "2026-10-02",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -134,10 +134,10 @@ export default function DesktopReliabilityPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/desktop-reliability"),
|
||||
@@ -159,7 +159,7 @@ export default function DesktopReliabilityPage() {
|
||||
Reliable Voice Dictation on Real Linux Desktops
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Recent Vocalinux beta releases focused heavily on the hard parts of
|
||||
Recent Voculinux beta releases focused heavily on the hard parts of
|
||||
Linux desktop dictation: Wayland text injection, IBus lifecycle
|
||||
behavior, suspend/resume recovery, keyboard layouts, non-ASCII text,
|
||||
and settings compatibility.
|
||||
|
||||
@@ -19,7 +19,7 @@ const howToSteps = [
|
||||
},
|
||||
{
|
||||
name: "Open the pad",
|
||||
text: "Click Open on the Open Dictation Pad row, or choose Dictation Pad from the tray menu. A window titled Vocalinux Dictation Pad appears.",
|
||||
text: "Click Open on the Open Dictation Pad row, or choose Dictation Pad from the tray menu. A window titled Voculinux Dictation Pad appears.",
|
||||
},
|
||||
{
|
||||
name: "Dictate as usual",
|
||||
@@ -65,15 +65,15 @@ const settingsRows = [
|
||||
const faqs = [
|
||||
{
|
||||
q: "Does the Dictation Pad save my text to disk?",
|
||||
a: "No. The pad keeps its text for the current session only. Closing the window hides it and keeps the text, but quitting Vocalinux discards it. Copy anything you want to keep before you quit.",
|
||||
a: "No. The pad keeps its text for the current session only. Closing the window hides it and keeps the text, but quitting Voculinux discards it. Copy anything you want to keep before you quit.",
|
||||
},
|
||||
{
|
||||
q: "Why does the pad not stay on top of my other windows on Wayland?",
|
||||
a: "Vocalinux asks for the pad to float above other windows and appear on every workspace, which works on X11. Wayland has no always-on-top protocol for normal apps, so the compositor decides. If a covered pad stops drawing, choose Dictation Pad from the tray menu again and Vocalinux recreates the window.",
|
||||
a: "Voculinux asks for the pad to float above other windows and appear on every workspace, which works on X11. Wayland has no always-on-top protocol for normal apps, so the compositor decides. If a covered pad stops drawing, choose Dictation Pad from the tray menu again and Voculinux recreates the window.",
|
||||
},
|
||||
{
|
||||
q: "Do I still need IBus, ydotool or wtype?",
|
||||
a: "Not for getting text out. Pad capture skips cross-application text injection entirely. You still need a working dictation shortcut, which on Wayland means the built-in listener with access to input devices, or External Activation (Desktop Shortcut) with a desktop shortcut that runs vocalinux --toggle.",
|
||||
a: "Not for getting text out. Pad capture skips cross-application text injection entirely. You still need a working dictation shortcut, which on Wayland means the built-in listener with access to input devices, or External Activation (Desktop Shortcut) with a desktop shortcut that runs voculinux --toggle.",
|
||||
},
|
||||
{
|
||||
q: "Can I edit text inside the pad?",
|
||||
@@ -86,16 +86,16 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Dictation Pad: Wayland-Safe Voice Typing on Linux | Vocalinux",
|
||||
title: "Dictation Pad: Wayland-Safe Voice Typing on Linux | Voculinux",
|
||||
description:
|
||||
"Dictate into the Vocalinux Dictation Pad, then copy text out by hand. The Wayland-safe path that skips text injection. Setup, settings, limits and FAQ.",
|
||||
"Dictate into the Voculinux Dictation Pad, then copy text out by hand. The Wayland-safe path that skips text injection. Setup, settings, limits and FAQ.",
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"Wayland voice typing",
|
||||
"Wayland dictation workaround",
|
||||
"Linux dictation pad",
|
||||
"voice typing without text injection",
|
||||
"Vocalinux Dictation Pad",
|
||||
"Voculinux Dictation Pad",
|
||||
"speech to text window Linux",
|
||||
],
|
||||
});
|
||||
@@ -106,7 +106,7 @@ export default function DictationPadPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Dictation Pad: Wayland-Safe Voice Typing on Linux",
|
||||
description:
|
||||
"How the Vocalinux Dictation Pad receives dictation in its own window so text never depends on cross-application injection, and how to copy it out.",
|
||||
"How the Voculinux Dictation Pad receives dictation in its own window so text never depends on cross-application injection, and how to copy it out.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -115,10 +115,10 @@ export default function DictationPadPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
@@ -127,7 +127,7 @@ export default function DictationPadPage() {
|
||||
const howToJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Dictate into the Vocalinux Dictation Pad",
|
||||
name: "Dictate into the Voculinux Dictation Pad",
|
||||
step: howToSteps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -167,7 +167,7 @@ export default function DictationPadPage() {
|
||||
Dictation Pad: voice typing that skips text injection
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
The Dictation Pad is a small Vocalinux window with an editable text
|
||||
The Dictation Pad is a small Voculinux window with an editable text
|
||||
box. When pad capture is on, everything you dictate lands there
|
||||
instead of being typed into another app. You copy the text out
|
||||
yourself. Because nothing is injected into other windows, the
|
||||
@@ -209,16 +209,16 @@ export default function DictationPadPage() {
|
||||
Why the Dictation Pad exists
|
||||
</h2>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
On X11, Vocalinux types into the focused window with xdotool. Wayland
|
||||
On X11, Voculinux types into the focused window with xdotool. Wayland
|
||||
deliberately stops apps from sending keystrokes to each other, so
|
||||
Vocalinux has to go through IBus, the RemoteDesktop portal, ydotool or
|
||||
Voculinux has to go through IBus, the RemoteDesktop portal, ydotool or
|
||||
wtype, and which of those works depends on your desktop. Most setups
|
||||
are covered (see the <Link href="/wayland/">Wayland guide</Link>), but
|
||||
some compositor and app combinations still drop or mangle text.
|
||||
</p>
|
||||
<p className="text-muted-foreground">
|
||||
The pad is the explicit fallback for those cases. Dictation is written
|
||||
straight into a Vocalinux window, so there is no injection step left
|
||||
straight into a Voculinux window, so there is no injection step left
|
||||
to fail. Text bound for the pad also lands there even if you switched
|
||||
to another app while it was being transcribed.
|
||||
</p>
|
||||
@@ -283,7 +283,7 @@ export default function DictationPadPage() {
|
||||
</table>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
The switch is stored in <code>~/.config/vocalinux/config.json</code>.
|
||||
The switch is stored in <code>~/.config/voculinux/config.json</code>.
|
||||
Flipping it in Settings applies to the next dictated segment without a
|
||||
restart. The saved value looks like this:
|
||||
</p>
|
||||
@@ -377,7 +377,7 @@ export default function DictationPadPage() {
|
||||
The pad solves text output, not hotkeys. On Wayland the built-in
|
||||
listener needs access to <code>/dev/input</code>, or you can turn
|
||||
on External Activation (Desktop Shortcut) and bind{" "}
|
||||
<code>vocalinux --toggle</code> to a desktop shortcut (toggle
|
||||
<code>voculinux --toggle</code> to a desktop shortcut (toggle
|
||||
only, no push-to-talk). See{" "}
|
||||
<Link href="/global-shortcuts/">global shortcuts</Link> and{" "}
|
||||
<Link href="/hyprland-sway/">Hyprland and sway</Link>.
|
||||
@@ -406,7 +406,7 @@ export default function DictationPadPage() {
|
||||
Try the Dictation Pad
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux, open Settings → Dictation and switch on Dictate
|
||||
Install Voculinux, open Settings → Dictation and switch on Dictate
|
||||
into Dictation Pad. If injection already works on your desktop, the{" "}
|
||||
<Link href="/troubleshooting/">troubleshooting guide</Link> covers the
|
||||
other paths.
|
||||
@@ -416,7 +416,7 @@ export default function DictationPadPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -21,12 +21,12 @@ const faqCategories = [
|
||||
iconColor: "text-primary",
|
||||
questions: [
|
||||
{
|
||||
q: "How do I install Vocalinux?",
|
||||
q: "How do I install Voculinux?",
|
||||
a: "Run the one-liner installer: curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh | bash. The installer handles dependencies and configuration. You can also download an AppImage from GitHub Releases if you prefer a no-root portable binary (host xdotool/wtype/ydotool still required for text injection), or grab a .deb, .rpm, Snap, or Flatpak package for your distro.",
|
||||
},
|
||||
{
|
||||
q: "Which Linux distributions are supported?",
|
||||
a: "Vocalinux works on Ubuntu 24.04+, Debian 12+, Fedora 39+, Arch Linux, Manjaro, and most other Linux distributions. See our install guides for distro-specific instructions.",
|
||||
a: "Voculinux works on Ubuntu 24.04+, Debian 12+, Fedora 39+, Arch Linux, Manjaro, and most other Linux distributions. See our install guides for distro-specific instructions.",
|
||||
},
|
||||
{
|
||||
q: "What are the system requirements?",
|
||||
@@ -40,11 +40,11 @@ const faqCategories = [
|
||||
iconColor: "text-primary",
|
||||
questions: [
|
||||
{
|
||||
q: "Does Vocalinux work offline?",
|
||||
q: "Does Voculinux work offline?",
|
||||
a: "Local engines (whisper.cpp, Whisper, and VOSK) run on your Linux machine. Remote API is optional and only talks to a server you configure.",
|
||||
},
|
||||
{
|
||||
q: "Does Vocalinux send any data to external servers?",
|
||||
q: "Does Voculinux send any data to external servers?",
|
||||
a: "Local engines do not send voice data externally. Remote API mode sends audio only to the transcription server URL you configure.",
|
||||
},
|
||||
{
|
||||
@@ -60,19 +60,19 @@ const faqCategories = [
|
||||
questions: [
|
||||
{
|
||||
q: "Which speech recognition engines are available?",
|
||||
a: "Vocalinux supports whisper.cpp (default), OpenAI Whisper, VOSK, and Remote API for compatible self-hosted or trusted transcription servers.",
|
||||
a: "Voculinux supports whisper.cpp (default), OpenAI Whisper, VOSK, and Remote API for compatible self-hosted or trusted transcription servers.",
|
||||
},
|
||||
{
|
||||
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?",
|
||||
q: "Can I use Voculinux 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.",
|
||||
},
|
||||
{
|
||||
q: "What is Silero VAD?",
|
||||
a: "Silero VAD is neural voice activity detection. Vocalinux uses it when ONNX Runtime support is available to drop silence-only buffers before recognition.",
|
||||
a: "Silero VAD is neural voice activity detection. Voculinux uses it when ONNX Runtime support is available to drop silence-only buffers before recognition.",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -86,20 +86,20 @@ const faqCategories = [
|
||||
a: "By default, hold Right Alt (Option on Mac-layout keyboards) to speak and release to stop (push-to-talk). You can switch to toggle mode (double-tap a key to start/stop) or change the key in Settings.",
|
||||
},
|
||||
{
|
||||
q: "Does Vocalinux work with Wayland?",
|
||||
a: "Yes. Vocalinux supports both X11 and Wayland, including IBus-based flows on Wayland with improved active-method detection for more reliable text injection.",
|
||||
q: "Does Voculinux work with Wayland?",
|
||||
a: "Yes. Voculinux supports both X11 and Wayland, including IBus-based flows on Wayland with improved active-method detection for more reliable text injection.",
|
||||
},
|
||||
{
|
||||
q: "What happens when I close my laptop lid?",
|
||||
a: "Vocalinux v0.10.1+ automatically recovers speech recognition after system suspend/resume. The app detects when your system wakes up and restarts the recognition engine and keyboard shortcuts. No manual restart needed - just start dictating as usual.",
|
||||
a: "Voculinux v0.10.1+ automatically recovers speech recognition after system suspend/resume. The app detects when your system wakes up and restarts the recognition engine and keyboard shortcuts. No manual restart needed - just start dictating as usual.",
|
||||
},
|
||||
{
|
||||
q: "Does Vocalinux preserve my keyboard layout?",
|
||||
a: "Yes! v0.10.1+ preserves your XKB keyboard layout when activating IBus for text injection. Unlike other tools that switch to US layout, Vocalinux keeps your configured layout so you can dictate without unexpected character changes.",
|
||||
q: "Does Voculinux preserve my keyboard layout?",
|
||||
a: "Yes! v0.10.1+ preserves your XKB keyboard layout when activating IBus for text injection. Unlike other tools that switch to US layout, Voculinux keeps your configured layout so you can dictate without unexpected character changes.",
|
||||
},
|
||||
{
|
||||
q: "Can I use voice commands?",
|
||||
a: "Yes. Vocalinux supports commands like 'new line', 'delete that', 'select all', and more. Voice commands are optional and can be enabled or disabled in Settings.",
|
||||
a: "Yes. Voculinux supports commands like 'new line', 'delete that', 'select all', and more. Voice commands are optional and can be enabled or disabled in Settings.",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -109,12 +109,12 @@ const faqCategories = [
|
||||
iconColor: "text-primary",
|
||||
questions: [
|
||||
{
|
||||
q: "How much RAM does Vocalinux need?",
|
||||
q: "How much RAM does Voculinux 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 on AMD, Intel, and NVIDIA. On multi-GPU machines Vocalinux prefers a discrete device when possible; you can pick a device under Advanced settings.",
|
||||
a: "Yes. whisper.cpp supports GPU acceleration via Vulkan on AMD, Intel, and NVIDIA. On multi-GPU machines Voculinux prefers a discrete device when possible; you can pick a device under Advanced settings.",
|
||||
},
|
||||
{
|
||||
q: "What model size should I use?",
|
||||
@@ -127,10 +127,10 @@ const faqCategories = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Linux Dictation FAQ: Offline, Wayland, GPU and Privacy",
|
||||
description:
|
||||
"Does Vocalinux work offline or on Wayland? How much RAM does it need, and which engines and languages does it support? Answers on install, privacy and GPU use.",
|
||||
"Does Voculinux work offline or on Wayland? How much RAM does it need, and which engines and languages does it support? Answers on install, privacy and GPU use.",
|
||||
path: "/faq",
|
||||
keywords: [
|
||||
"vocalinux faq",
|
||||
"voculinux faq",
|
||||
"linux voice dictation help",
|
||||
"speech to text linux questions",
|
||||
"offline dictation faq",
|
||||
@@ -170,7 +170,7 @@ export default function FaqPage() {
|
||||
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
|
||||
Find answers to common questions about Voculinux. From installation to
|
||||
advanced features, we've got you covered.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -80,12 +80,12 @@ const packages = [
|
||||
note: "Menu option or --engine=faster_whisper",
|
||||
},
|
||||
{
|
||||
name: "AUR (vocalinux)",
|
||||
name: "AUR (voculinux)",
|
||||
included: true,
|
||||
note: "Listed as an optional dependency: python-faster-whisper",
|
||||
},
|
||||
{
|
||||
name: "AppImage (and AUR vocalinux-bin)",
|
||||
name: "AppImage (and AUR voculinux-bin)",
|
||||
included: false,
|
||||
note: "Ships whisper.cpp only",
|
||||
},
|
||||
@@ -126,17 +126,17 @@ const faqs = [
|
||||
{
|
||||
question: "Is Faster Whisper the same model as Whisper?",
|
||||
answer:
|
||||
"It runs the same Whisper model family converted to the CTranslate2 format. Vocalinux downloads those conversions from pinned Hugging Face revisions. The sizes and English-only variants match the Whisper names you already know.",
|
||||
"It runs the same Whisper model family converted to the CTranslate2 format. Voculinux downloads those conversions from pinned Hugging Face revisions. The sizes and English-only variants match the Whisper names you already know.",
|
||||
},
|
||||
{
|
||||
question: "Does Faster Whisper use my GPU?",
|
||||
answer:
|
||||
"On a typical install it runs on the CPU with int8. Vocalinux switches to CUDA with float16 only when PyTorch is installed and reports a CUDA GPU. The installer's Faster Whisper option does not install CUDA. For Vulkan GPU acceleration on AMD, Intel or NVIDIA, use whisper.cpp.",
|
||||
"On a typical install it runs on the CPU with int8. Voculinux switches to CUDA with float16 only when PyTorch is installed and reports a CUDA GPU. The installer's Faster Whisper option does not install CUDA. For Vulkan GPU acceleration on AMD, Intel or NVIDIA, use whisper.cpp.",
|
||||
},
|
||||
{
|
||||
question: "Can I change the compute type?",
|
||||
answer:
|
||||
"There is no setting for it. Vocalinux picks int8 on the CPU and float16 on CUDA automatically.",
|
||||
"There is no setting for it. Voculinux picks int8 on the CPU and float16 on CUDA automatically.",
|
||||
},
|
||||
{
|
||||
question: "Does audio leave my machine?",
|
||||
@@ -151,9 +151,9 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Faster Whisper on Linux: Offline Voice Typing | Vocalinux",
|
||||
title: "Faster Whisper on Linux: Offline Voice Typing | Voculinux",
|
||||
description:
|
||||
"Use Faster Whisper (CTranslate2, int8 on CPU) for offline voice typing on Linux with Vocalinux: install, model sizes, GPU and compute options, and fixes.",
|
||||
"Use Faster Whisper (CTranslate2, int8 on CPU) for offline voice typing on Linux with Voculinux: install, model sizes, GPU and compute options, and fixes.",
|
||||
path: "/faster-whisper",
|
||||
keywords: [
|
||||
"Faster Whisper Linux",
|
||||
@@ -173,7 +173,7 @@ export default function FasterWhisperPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Faster Whisper on Linux",
|
||||
description:
|
||||
"How to install and use the Faster Whisper speech engine in Vocalinux on Linux, including model sizes, compute options, package availability and troubleshooting.",
|
||||
"How to install and use the Faster Whisper speech engine in Voculinux on Linux, including model sizes, compute options, package availability and troubleshooting.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -182,10 +182,10 @@ export default function FasterWhisperPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/faster-whisper"),
|
||||
@@ -193,7 +193,7 @@ export default function FasterWhisperPage() {
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Set up the Faster Whisper engine in Vocalinux",
|
||||
name: "Set up the Faster Whisper engine in Voculinux",
|
||||
step: setupSteps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -228,11 +228,13 @@ export default function FasterWhisperPage() {
|
||||
Faster Whisper on Linux
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Faster Whisper is an optional local speech engine in Vocalinux. It
|
||||
Faster Whisper is an optional local speech engine in Voculinux. It
|
||||
runs Whisper models through CTranslate2 with int8 quantization on your
|
||||
CPU and types what you say into the focused app. It is for people who
|
||||
want Whisper models and the full language catalog on a machine without
|
||||
a GPU, using a different runtime from the default whisper.cpp.
|
||||
Faster Whisper is a best-effort extra: installable and selectable,
|
||||
outside the performance budgets.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -281,11 +283,11 @@ export default function FasterWhisperPage() {
|
||||
int8, which lowers memory use on the CPU.
|
||||
</p>
|
||||
<p>
|
||||
Vocalinux added Faster Whisper as an optional engine in v0.17.0,
|
||||
together with Parakeet. whisper.cpp remains the default. Vocalinux
|
||||
Voculinux added Faster Whisper as an optional engine in v0.17.0,
|
||||
together with Parakeet. whisper.cpp remains the default. Voculinux
|
||||
stores Faster Whisper models under{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
~/.local/share/vocalinux/models/
|
||||
~/.local/share/voculinux/models/
|
||||
</code>{" "}
|
||||
and checks each file against a pinned checksum before loading it.
|
||||
</p>
|
||||
@@ -325,7 +327,7 @@ export default function FasterWhisperPage() {
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
To start once with Faster Whisper from a terminal, run{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
vocalinux --engine faster_whisper
|
||||
voculinux --engine faster_whisper
|
||||
</code>
|
||||
.
|
||||
</p>
|
||||
@@ -391,7 +393,7 @@ export default function FasterWhisperPage() {
|
||||
</h2>
|
||||
<div className="max-w-4xl space-y-4 text-muted-foreground">
|
||||
<p>
|
||||
Vocalinux chooses the device and precision for you; there is no
|
||||
Voculinux chooses the device and precision for you; there is no
|
||||
compute-type setting. On the CPU it loads the model with{" "}
|
||||
<code className="rounded bg-muted px-1">int8</code>. If PyTorch is
|
||||
installed and reports a CUDA GPU, it loads the model on CUDA with{" "}
|
||||
@@ -480,7 +482,7 @@ export default function FasterWhisperPage() {
|
||||
</h2>
|
||||
<p className="mb-4 max-w-4xl text-muted-foreground">
|
||||
All four are local engines. Choose by hardware and by how you
|
||||
installed Vocalinux. For the full table, see the{" "}
|
||||
installed Voculinux. For the full table, see the{" "}
|
||||
<Link href="/compare/" className="text-primary underline">
|
||||
engine comparison
|
||||
</Link>{" "}
|
||||
@@ -556,10 +558,10 @@ export default function FasterWhisperPage() {
|
||||
</h3>
|
||||
<p>
|
||||
Run{" "}
|
||||
<code className="rounded bg-muted px-1">vocalinux --debug</code>{" "}
|
||||
<code className="rounded bg-muted px-1">voculinux --debug</code>{" "}
|
||||
and check{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
~/.local/share/vocalinux/vocalinux.log
|
||||
~/.local/share/voculinux/voculinux.log
|
||||
</code>
|
||||
, then see the{" "}
|
||||
<Link href="/troubleshooting/" className="text-primary underline">
|
||||
@@ -593,7 +595,7 @@ export default function FasterWhisperPage() {
|
||||
Try Faster Whisper
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux with the Faster Whisper engine, or keep whisper.cpp
|
||||
Install Voculinux with the Faster Whisper engine, or keep whisper.cpp
|
||||
and switch later from Settings → Speech Model.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
@@ -601,7 +603,7 @@ export default function FasterWhisperPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -15,24 +15,24 @@ import { SeoSubpageShell } from "@/components/seo-subpage-shell";
|
||||
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
|
||||
const PAGE_PATH = "/flatpak";
|
||||
const PAGE_TITLE = "Install Vocalinux via Flatpak (VocaHQ Remote) | Vocalinux";
|
||||
const PAGE_TITLE = "Install Voculinux via Flatpak (VocaHQ Remote) | Voculinux";
|
||||
const PAGE_DESCRIPTION =
|
||||
"Install Vocalinux from the signed VocaHQ Flatpak remote (not Flathub): exact commands, updates, sandbox and Wayland notes, what is included, and uninstall.";
|
||||
"Install Voculinux from the signed VocaHQ Flatpak remote (not Flathub): exact commands, updates, sandbox and Wayland notes, what is included, and uninstall.";
|
||||
|
||||
const FLATPAKREF_COMMAND =
|
||||
"flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref";
|
||||
"flatpak install https://vocahq.github.io/voculinux-flatpak/com.voculinux.Voculinux.flatpakref";
|
||||
|
||||
const MANUAL_COMMANDS = `flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak install vocahq com.vocalinux.Vocalinux`;
|
||||
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak install vocahq com.voculinux.Voculinux`;
|
||||
|
||||
const DBUS_TOGGLE_COMMAND =
|
||||
"gdbus call --session --dest com.vocalinux.Vocalinux --object-path /com/vocalinux/Vocalinux --method com.vocalinux.Vocalinux.Toggle";
|
||||
"gdbus call --session --dest com.voculinux.Voculinux --object-path /com/voculinux/Voculinux --method com.voculinux.Voculinux.Toggle";
|
||||
|
||||
const OVERRIDE_COMMAND =
|
||||
"flatpak override --user --nodevice=all --device=dri com.vocalinux.Vocalinux";
|
||||
"flatpak override --user --nodevice=all --device=dri com.voculinux.Voculinux";
|
||||
|
||||
const RUN_COMMAND = "flatpak run com.vocalinux.Vocalinux";
|
||||
const RUN_COMMAND = "flatpak run com.voculinux.Voculinux";
|
||||
|
||||
const installSteps = [
|
||||
{
|
||||
@@ -41,21 +41,21 @@ const installSteps = [
|
||||
},
|
||||
{
|
||||
name: "Or add the remotes by hand",
|
||||
text: "If you prefer explicit remotes, add flathub, add vocahq, then install com.vocalinux.Vocalinux from vocahq with the three commands below.",
|
||||
text: "If you prefer explicit remotes, add flathub, add vocahq, then install com.voculinux.Voculinux from vocahq with the three commands below.",
|
||||
},
|
||||
{
|
||||
name: "Start Vocalinux",
|
||||
text: `Launch Vocalinux from your app menu or run ${RUN_COMMAND}.`,
|
||||
name: "Start Voculinux",
|
||||
text: `Launch Voculinux from your app menu or run ${RUN_COMMAND}.`,
|
||||
},
|
||||
{
|
||||
name: "Download a speech model",
|
||||
text: "Pick a model in Settings → Speech Model. Since v0.18.4 Vocalinux shows the download size and asks before downloading anything.",
|
||||
text: "Pick a model in Settings → Speech Model. Since v0.18.4 Voculinux shows the download size and asks before downloading anything.",
|
||||
},
|
||||
];
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
question: "Is Vocalinux on Flathub?",
|
||||
question: "Is Voculinux on Flathub?",
|
||||
answer:
|
||||
"No. The Flathub submission was closed on policy grounds in July 2026 and the project is not re-submitting. The app comes from the self-hosted vocahq remote; only the GNOME runtime is pulled from Flathub.",
|
||||
},
|
||||
@@ -77,7 +77,7 @@ const faqs = [
|
||||
{
|
||||
question: "Can I start a local VocaGateway from the Flatpak?",
|
||||
answer:
|
||||
"No. The sandbox cannot reach the host podman or docker socket. Start VocaGateway on the host yourself and point Settings → Remote Server at it, or use the installer or AppImage. Either way, audio leaves Vocalinux for the endpoint you configured, and leaves the machine if that endpoint is elsewhere. VocaGateway is not on-device, so keep it on localhost, a trusted LAN, an encrypted private network such as Tailscale, or HTTPS.",
|
||||
"No. The sandbox cannot reach the host podman or docker socket. Start VocaGateway on the host yourself and point Settings → Remote Server at it, or use the installer or AppImage. Either way, audio leaves Voculinux for the endpoint you configured, and leaves the machine if that endpoint is elsewhere. VocaGateway is not on-device, so keep it on localhost, a trusted LAN, an encrypted private network such as Tailscale, or HTTPS.",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -86,11 +86,11 @@ export const metadata: Metadata = buildPageMetadata({
|
||||
description: PAGE_DESCRIPTION,
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"vocalinux flatpak",
|
||||
"voculinux flatpak",
|
||||
"linux voice dictation flatpak",
|
||||
"flatpak speech to text",
|
||||
"vocahq flatpak remote",
|
||||
"com.vocalinux.Vocalinux",
|
||||
"com.voculinux.Voculinux",
|
||||
"flatpak dictation wayland",
|
||||
],
|
||||
});
|
||||
@@ -109,7 +109,7 @@ export default function FlatpakPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
headline: "Install Vocalinux with Flatpak from the VocaHQ remote",
|
||||
headline: "Install Voculinux with Flatpak from the VocaHQ remote",
|
||||
description: PAGE_DESCRIPTION,
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
@@ -119,10 +119,10 @@ export default function FlatpakPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
@@ -131,7 +131,7 @@ export default function FlatpakPage() {
|
||||
const howToJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Install Vocalinux from the VocaHQ Flatpak remote",
|
||||
name: "Install Voculinux from the VocaHQ Flatpak remote",
|
||||
description: PAGE_DESCRIPTION,
|
||||
tool: [{ "@type": "HowToTool", name: "Flatpak" }],
|
||||
step: installSteps.map((step) => ({
|
||||
@@ -170,10 +170,10 @@ export default function FlatpakPage() {
|
||||
<section>
|
||||
<p className="subpage-kicker">Flatpak remote added in v0.18.0</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Install Vocalinux with Flatpak
|
||||
Install Voculinux with Flatpak
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux publishes a signed, self-hosted Flatpak remote called{" "}
|
||||
Voculinux publishes a signed, self-hosted Flatpak remote called{" "}
|
||||
<code>vocahq</code> on every stable release. It is{" "}
|
||||
<strong>not on Flathub</strong>: the app comes from VocaHQ, and only
|
||||
the GNOME runtime comes from Flathub. Install once, and{" "}
|
||||
@@ -219,21 +219,21 @@ export default function FlatpakPage() {
|
||||
<h3 className="font-semibold">2. {installSteps[1].name}</h3>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
If you prefer explicit remotes, add flathub, add vocahq, then
|
||||
install <code>com.vocalinux.Vocalinux</code> from vocahq:
|
||||
install <code>com.voculinux.Voculinux</code> from vocahq:
|
||||
</p>
|
||||
<Commands>{MANUAL_COMMANDS}</Commands>
|
||||
</li>
|
||||
<li className="rounded-[12px] border border-border bg-background p-5">
|
||||
<h3 className="font-semibold">3. {installSteps[2].name}</h3>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
Launch Vocalinux from your app menu, or run:
|
||||
Launch Voculinux from your app menu, or run:
|
||||
</p>
|
||||
<Commands>{RUN_COMMAND}</Commands>
|
||||
</li>
|
||||
<li className="rounded-[12px] border border-border bg-background p-5">
|
||||
<h3 className="font-semibold">4. {installSteps[3].name}</h3>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
Pick a model in Settings → Speech Model. Since v0.18.4 Vocalinux
|
||||
Pick a model in Settings → Speech Model. Since v0.18.4 Voculinux
|
||||
shows the download size and asks before downloading anything.
|
||||
After that one download, the whisper.cpp engine transcribes on
|
||||
your machine. Then hold Right Alt and speak.
|
||||
@@ -260,7 +260,7 @@ export default function FlatpakPage() {
|
||||
</li>
|
||||
<li>
|
||||
Release bundles (
|
||||
<code>Vocalinux-<version>-x86_64.flatpak</code> or{" "}
|
||||
<code>Voculinux-<version>-x86_64.flatpak</code> or{" "}
|
||||
<code>-aarch64.flatpak</code>) do not auto-update. Switch to the
|
||||
remote if you installed one.
|
||||
</li>
|
||||
@@ -277,7 +277,7 @@ export default function FlatpakPage() {
|
||||
public key. Re-running <code>remote-add</code> does not replace it.
|
||||
The documented fix:
|
||||
</p>
|
||||
<Commands>{`curl -fsSL https://vocahq.github.io/vocalinux-flatpak/vocahq.gpg -o /tmp/vocahq.gpg
|
||||
<Commands>{`curl -fsSL https://vocahq.github.io/voculinux-flatpak/vocahq.gpg -o /tmp/vocahq.gpg
|
||||
flatpak remote-modify --gpg-import=/tmp/vocahq.gpg vocahq
|
||||
flatpak update`}</Commands>
|
||||
</section>
|
||||
@@ -341,8 +341,8 @@ flatpak update`}</Commands>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
Config and models live under{" "}
|
||||
<code>~/.var/app/com.vocalinux.Vocalinux/</code>, not{" "}
|
||||
<code>~/.config/vocalinux</code>.
|
||||
<code>~/.var/app/com.voculinux.Voculinux/</code>, not{" "}
|
||||
<code>~/.config/voculinux</code>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -406,10 +406,10 @@ flatpak update`}</Commands>
|
||||
The <code>uninstall.sh</code> script is for script and source
|
||||
installs. For the Flatpak, use Flatpak itself. Remove the app:
|
||||
</p>
|
||||
<Commands>flatpak uninstall com.vocalinux.Vocalinux</Commands>
|
||||
<Commands>flatpak uninstall com.voculinux.Voculinux</Commands>
|
||||
<p className="mt-3 text-sm text-muted-foreground">
|
||||
Add <code>--delete-data</code> to also remove settings and downloaded
|
||||
models under <code>~/.var/app/com.vocalinux.Vocalinux/</code>. If no
|
||||
models under <code>~/.var/app/com.voculinux.Voculinux/</code>. If no
|
||||
other app uses the remote, drop it too:
|
||||
</p>
|
||||
<Commands>flatpak remote-delete vocahq</Commands>
|
||||
|
||||
@@ -112,7 +112,7 @@ const benefits = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Voice Dictation for Developers & Coders | Vocalinux",
|
||||
title: "Voice Dictation for Developers & Coders | Voculinux",
|
||||
description:
|
||||
"Dictate code comments, documentation, and commit messages hands-free. Voice dictation for Linux developers - works in VS Code, JetBrains, terminal, and all apps.",
|
||||
path: "/for-developers",
|
||||
@@ -134,7 +134,7 @@ export default function ForDevelopersPage() {
|
||||
"@type": "Article",
|
||||
headline: "Voice Dictation for Developers & Coders",
|
||||
description:
|
||||
"How Linux developers use Vocalinux for code comments, documentation, and commit messages.",
|
||||
"How Linux developers use Voculinux for code comments, documentation, and commit messages.",
|
||||
dateModified: "2026-02-22",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -143,10 +143,10 @@ export default function ForDevelopersPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/for-developers"),
|
||||
@@ -239,7 +239,7 @@ export default function ForDevelopersPage() {
|
||||
Not Voice Coding - Voice Documentation
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Vocalinux is designed for <strong>dictating text</strong>, not writing code syntax. For
|
||||
Voculinux is designed for <strong>dictating text</strong>, not writing code syntax. For
|
||||
actual code, your keyboard is still faster. But for comments, docs, messages, and
|
||||
notes - voice is a game-changer. Use both together for maximum productivity.
|
||||
</p>
|
||||
@@ -269,14 +269,14 @@ export default function ForDevelopersPage() {
|
||||
))}
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
Vocalinux works system-wide. If the app accepts text input, Vocalinux can dictate into it.
|
||||
Voculinux works system-wide. If the app accepts text input, Voculinux can dictate into it.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Start Dictating Your Docs</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux and start writing better documentation with less effort. Your future
|
||||
Install Voculinux and start writing better documentation with less effort. Your future
|
||||
self (and your team) will thank you.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
|
||||
@@ -15,32 +15,32 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const PAGE_PATH = "/global-shortcuts";
|
||||
const PAGE_TITLE = "Global Shortcuts for Voice Dictation via D-Bus";
|
||||
const PAGE_DESCRIPTION =
|
||||
"Start and stop Vocalinux dictation from GNOME, KDE, sway or Hyprland shortcuts and scripts using its D-Bus service and the --toggle, --start and --stop flags.";
|
||||
"Start and stop Voculinux dictation from GNOME, KDE, sway or Hyprland shortcuts and scripts using its D-Bus service and the --toggle, --start and --stop flags.";
|
||||
|
||||
const GDBUS_TOGGLE =
|
||||
"gdbus call --session --dest com.vocalinux.Vocalinux --object-path /com/vocalinux/Vocalinux --method com.vocalinux.Vocalinux.Toggle";
|
||||
"gdbus call --session --dest com.voculinux.Voculinux --object-path /com/voculinux/Voculinux --method com.voculinux.Voculinux.Toggle";
|
||||
|
||||
const dbusRows = [
|
||||
{ item: "Bus", value: "Session bus" },
|
||||
{ item: "Bus name", value: "com.vocalinux.Vocalinux" },
|
||||
{ item: "Object path", value: "/com/vocalinux/Vocalinux" },
|
||||
{ item: "Interface", value: "com.vocalinux.Vocalinux" },
|
||||
{ item: "Bus name", value: "com.voculinux.Voculinux" },
|
||||
{ item: "Object path", value: "/com/voculinux/Voculinux" },
|
||||
{ item: "Interface", value: "com.voculinux.Voculinux" },
|
||||
{ item: "Methods", value: "Toggle, Start, Stop (no arguments)" },
|
||||
];
|
||||
|
||||
const commandRows = [
|
||||
{
|
||||
cli: "vocalinux --toggle",
|
||||
cli: "voculinux --toggle",
|
||||
method: "Toggle",
|
||||
effect: "Start if idle, stop if active",
|
||||
},
|
||||
{
|
||||
cli: "vocalinux --start",
|
||||
cli: "voculinux --start",
|
||||
method: "Start",
|
||||
effect: "Start voice typing; does nothing if already running",
|
||||
},
|
||||
{
|
||||
cli: "vocalinux --stop",
|
||||
cli: "voculinux --stop",
|
||||
method: "Stop",
|
||||
effect: "Stop voice typing; does nothing if already idle",
|
||||
},
|
||||
@@ -53,7 +53,7 @@ const steps = [
|
||||
},
|
||||
{
|
||||
name: "Pick the command",
|
||||
text: "On a native install, use vocalinux --toggle. On Flatpak, use the gdbus call shown below, because vocalinux --toggle is not on the host PATH.",
|
||||
text: "On a native install, use voculinux --toggle. On Flatpak, use the gdbus call shown below, because voculinux --toggle is not on the host PATH.",
|
||||
},
|
||||
{
|
||||
name: "Bind it in your desktop",
|
||||
@@ -72,19 +72,19 @@ const faqs = [
|
||||
"No. A desktop shortcut only sends the key press and never the release, so it can toggle dictation but cannot hold-to-talk. Use the built-in listener if you need push-to-talk.",
|
||||
},
|
||||
{
|
||||
question: "Will vocalinux --toggle launch Vocalinux if it is not running?",
|
||||
question: "Will voculinux --toggle launch Voculinux if it is not running?",
|
||||
answer:
|
||||
"No. It forwards the command to a running instance over D-Bus and exits. If no instance answers, it logs that it could not reach a running Vocalinux and exits with status 1.",
|
||||
"No. It forwards the command to a running instance over D-Bus and exits. If no instance answers, it logs that it could not reach a running Voculinux and exits with status 1.",
|
||||
},
|
||||
{
|
||||
question: "Do I still need the input group?",
|
||||
answer:
|
||||
"Not for starting and stopping dictation. With External Activation on, Vocalinux does not read /dev/input for the hotkey. Text injection is unaffected and keeps its own requirements.",
|
||||
"Not for starting and stopping dictation. With External Activation on, Voculinux does not read /dev/input for the hotkey. Text injection is unaffected and keeps its own requirements.",
|
||||
},
|
||||
{
|
||||
question: "What happens if the D-Bus service cannot start?",
|
||||
answer:
|
||||
"Vocalinux shows an External activation unavailable notification and falls back to the internal keyboard shortcut, so you are never left without a way to start or stop dictation.",
|
||||
"Voculinux shows an External activation unavailable notification and falls back to the internal keyboard shortcut, so you are never left without a way to start or stop dictation.",
|
||||
},
|
||||
{
|
||||
question: "Do per-language shortcuts work with External Activation?",
|
||||
@@ -94,13 +94,13 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: `${PAGE_TITLE} | Vocalinux`,
|
||||
title: `${PAGE_TITLE} | Voculinux`,
|
||||
description: PAGE_DESCRIPTION,
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"linux dictation global shortcut",
|
||||
"vocalinux d-bus",
|
||||
"vocalinux --toggle",
|
||||
"voculinux d-bus",
|
||||
"voculinux --toggle",
|
||||
"sway voice typing keybind",
|
||||
"hyprland dictation keybind",
|
||||
"kde global shortcut dictation",
|
||||
@@ -143,17 +143,17 @@ export default function GlobalShortcutsPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
},
|
||||
{
|
||||
"@type": "HowTo",
|
||||
name: "Start Vocalinux dictation from a desktop shortcut",
|
||||
name: "Start Voculinux dictation from a desktop shortcut",
|
||||
step: steps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -185,10 +185,10 @@ export default function GlobalShortcutsPage() {
|
||||
Start dictation from desktop shortcuts and scripts
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux can hand hotkey duty to your desktop. A running instance
|
||||
Voculinux can hand hotkey duty to your desktop. A running instance
|
||||
answers on the session D-Bus, so a GNOME or KDE custom shortcut, a
|
||||
sway or Hyprland bind, or any script can start and stop voice typing
|
||||
without Vocalinux reading your keyboard.
|
||||
without Voculinux reading your keyboard.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -230,7 +230,7 @@ export default function GlobalShortcutsPage() {
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
These names come from <InlineCode>dbus_service.py</InlineCode> in the
|
||||
Vocalinux source.
|
||||
Voculinux source.
|
||||
</p>
|
||||
<div className="mb-6 overflow-x-auto">
|
||||
<table className="w-full text-left text-sm">
|
||||
@@ -309,8 +309,8 @@ export default function GlobalShortcutsPage() {
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
The same switch is stored as{" "}
|
||||
<InlineCode>shortcuts.disable_internal_hotkey</InlineCode> in{" "}
|
||||
<InlineCode>~/.config/vocalinux/config.json</InlineCode>. Quit
|
||||
Vocalinux before editing that file by hand, or the running app can
|
||||
<InlineCode>~/.config/voculinux/config.json</InlineCode>. Quit
|
||||
Voculinux before editing that file by hand, or the running app can
|
||||
overwrite your change.
|
||||
</p>
|
||||
</section>
|
||||
@@ -321,13 +321,13 @@ export default function GlobalShortcutsPage() {
|
||||
</h2>
|
||||
<p className="mb-6 text-sm text-muted-foreground">
|
||||
The key combination is your choice; the examples use Super+Shift+D.
|
||||
Only the command matters to Vocalinux. Menu names and config syntax
|
||||
Only the command matters to Voculinux. Menu names and config syntax
|
||||
belong to each desktop and can differ between versions.
|
||||
</p>
|
||||
<h3 className="mb-2 font-semibold">GNOME</h3>
|
||||
<p className="mb-6 text-sm text-muted-foreground">
|
||||
In Settings → Keyboard, open the custom shortcuts list, add a
|
||||
shortcut, enter <InlineCode>vocalinux --toggle</InlineCode> as the
|
||||
shortcut, enter <InlineCode>voculinux --toggle</InlineCode> as the
|
||||
command and record your key combination.
|
||||
</p>
|
||||
<h3 className="mb-2 font-semibold">KDE Plasma</h3>
|
||||
@@ -335,21 +335,21 @@ export default function GlobalShortcutsPage() {
|
||||
Open System Settings → Keyboard → Shortcuts → Add New → Command or
|
||||
Script (older Plasma: System Settings → Shortcuts → Custom Shortcuts →
|
||||
Edit → New → Global Shortcut → Command/URL) and bind your keys to{" "}
|
||||
<InlineCode>vocalinux --toggle</InlineCode>.
|
||||
<InlineCode>voculinux --toggle</InlineCode>.
|
||||
</p>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<ConfigBlock label="sway (~/.config/sway/config)">
|
||||
{"bindsym $mod+Shift+d exec vocalinux --toggle"}
|
||||
{"bindsym $mod+Shift+d exec voculinux --toggle"}
|
||||
</ConfigBlock>
|
||||
<ConfigBlock label="Hyprland (hyprland.conf)">
|
||||
{"bind = SUPER SHIFT, D, exec, vocalinux --toggle"}
|
||||
{"bind = SUPER SHIFT, D, exec, voculinux --toggle"}
|
||||
</ConfigBlock>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
If your compositor cannot find <InlineCode>vocalinux</InlineCode>, its
|
||||
If your compositor cannot find <InlineCode>voculinux</InlineCode>, its
|
||||
PATH may not include <InlineCode>~/.local/bin</InlineCode>. Use the
|
||||
full path{" "}
|
||||
<InlineCode>~/.local/share/vocalinux/venv/bin/vocalinux</InlineCode>{" "}
|
||||
<InlineCode>~/.local/share/voculinux/venv/bin/voculinux</InlineCode>{" "}
|
||||
for an installer setup, or the <InlineCode>gdbus</InlineCode> command
|
||||
above. More on tiling compositors in{" "}
|
||||
<Link href="/hyprland-sway/" className="text-primary underline">
|
||||
@@ -381,7 +381,7 @@ export default function GlobalShortcutsPage() {
|
||||
<li>
|
||||
On Flatpak,{" "}
|
||||
<InlineCode>
|
||||
flatpak run com.vocalinux.Vocalinux --toggle
|
||||
flatpak run com.voculinux.Voculinux --toggle
|
||||
</InlineCode>{" "}
|
||||
also works but starts a sandbox on each press; prefer{" "}
|
||||
<InlineCode>gdbus</InlineCode>.
|
||||
@@ -436,7 +436,7 @@ export default function GlobalShortcutsPage() {
|
||||
Bind your dictation key
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux, turn on External Activation, and let your desktop
|
||||
Install Voculinux, turn on External Activation, and let your desktop
|
||||
own the shortcut.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
@@ -444,7 +444,7 @@ export default function GlobalShortcutsPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -73,10 +73,10 @@ export default function GnomeVsKdePage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/gnome-kde"),
|
||||
@@ -243,14 +243,14 @@ export default function GnomeVsKdePage() {
|
||||
<section className="rounded-[12px] border border-primary/20 bg-primary/5 p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Ready to set up voice typing on your desktop?</h2>
|
||||
<p className="mb-6 max-w-3xl text-muted-foreground">
|
||||
Install Vocalinux and get reliable offline voice dictation on GNOME or KDE Plasma, with the
|
||||
Install Voculinux and get reliable offline voice dictation on GNOME or KDE Plasma, with the
|
||||
right text injection path for your session type.
|
||||
</p>
|
||||
<Link
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</section>
|
||||
|
||||
@@ -152,7 +152,7 @@ export default function GpuAccelerationPage() {
|
||||
"@type": "Article",
|
||||
headline: "GPU Accelerated Voice Dictation for Linux",
|
||||
description:
|
||||
"Complete guide to GPU acceleration in Vocalinux. Vulkan support for AMD, Intel, and NVIDIA GPUs.",
|
||||
"Complete guide to GPU acceleration in Voculinux. Vulkan support for AMD, Intel, and NVIDIA GPUs.",
|
||||
dateModified: "2026-02-22",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -161,10 +161,10 @@ export default function GpuAccelerationPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/gpu-acceleration"),
|
||||
@@ -186,7 +186,7 @@ export default function GpuAccelerationPage() {
|
||||
GPU Accelerated Voice Dictation
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Leverage your GPU for faster speech recognition. Vocalinux supports AMD, Intel, and NVIDIA
|
||||
Leverage your GPU for faster speech recognition. Voculinux supports AMD, Intel, and NVIDIA
|
||||
GPUs via Vulkan - with automatic fallback to CPU when needed.
|
||||
</p>
|
||||
</section>
|
||||
@@ -201,7 +201,7 @@ export default function GpuAccelerationPage() {
|
||||
</div>
|
||||
<p className="mt-3 text-sm text-muted-foreground">
|
||||
If you see your GPU name, you're ready for accelerated dictation!
|
||||
On multi-GPU machines Vocalinux prefers a discrete Vulkan device when
|
||||
On multi-GPU machines Voculinux prefers a discrete Vulkan device when
|
||||
one is present; pick a specific device under Advanced settings if you
|
||||
need to override auto-select.
|
||||
</p>
|
||||
@@ -324,7 +324,7 @@ export default function GpuAccelerationPage() {
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Some Intel integrated GPUs don't fully support the compute features needed for
|
||||
whisper.cpp GPU acceleration. Vocalinux v0.7.0+ automatically detects incompatible
|
||||
whisper.cpp GPU acceleration. Voculinux v0.7.0+ automatically detects incompatible
|
||||
Intel GPUs and falls back to CPU processing for reliability.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const PAGE_PATH = "/hyprland-sway";
|
||||
const PAGE_TITLE = "Voice Typing on Hyprland, Sway and i3 for Linux";
|
||||
const PAGE_DESCRIPTION =
|
||||
"Set up Vocalinux voice typing on sway, i3 and Hyprland: pick wtype, ydotool, IBus or the RemoteDesktop portal, bind keys over D-Bus, and use the Dictation Pad.";
|
||||
"Set up Voculinux voice typing on sway, i3 and Hyprland: pick wtype, ydotool, IBus or the RemoteDesktop portal, bind keys over D-Bus, and use the Dictation Pad.";
|
||||
|
||||
const supportRows = [
|
||||
{
|
||||
@@ -39,7 +39,7 @@ const backendRows = [
|
||||
where:
|
||||
"Desktops that bridge IBus; on sway and Hyprland only with ibus-wayland running",
|
||||
needs:
|
||||
"IBus. On sway and Hyprland, Vocalinux skips IBus unless the ibus-wayland bridge is running",
|
||||
"IBus. On sway and Hyprland, Voculinux skips IBus unless the ibus-wayland bridge is running",
|
||||
},
|
||||
{
|
||||
backend: "RemoteDesktop portal (portal)",
|
||||
@@ -66,20 +66,20 @@ const backendRows = [
|
||||
|
||||
const steps = [
|
||||
{
|
||||
name: "Install Vocalinux and the typing tools",
|
||||
text: "Install Vocalinux, then make sure wtype and wl-clipboard are installed on sway or Hyprland, or xdotool on i3.",
|
||||
name: "Install Voculinux and the typing tools",
|
||||
text: "Install Voculinux, then make sure wtype and wl-clipboard are installed on sway or Hyprland, or xdotool on i3.",
|
||||
},
|
||||
{
|
||||
name: "Check that the tool can type",
|
||||
text: 'Focus a text field and run wtype "hello" on Wayland or xdotool type "hello" on X11. If nothing appears, Vocalinux cannot type there either.',
|
||||
text: 'Focus a text field and run wtype "hello" on Wayland or xdotool type "hello" on X11. If nothing appears, Voculinux cannot type there either.',
|
||||
},
|
||||
{
|
||||
name: "Choose how dictation starts",
|
||||
text: "Either add yourself to the input group for the built-in hotkey, or turn on External Activation and bind vocalinux --toggle in your compositor config.",
|
||||
text: "Either add yourself to the input group for the built-in hotkey, or turn on External Activation and bind voculinux --toggle in your compositor config.",
|
||||
},
|
||||
{
|
||||
name: "Pin a backend if autodetection guesses wrong",
|
||||
text: "Set text_injection.backend in ~/.config/vocalinux/config.json, for example to wtype, then restart Vocalinux.",
|
||||
text: "Set text_injection.backend in ~/.config/voculinux/config.json, for example to wtype, then restart Voculinux.",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -88,12 +88,12 @@ const faqs = [
|
||||
question:
|
||||
"Why does dictation work in my browser but not in native Wayland apps?",
|
||||
answer:
|
||||
"That is the classic IBus symptom: the compositor does not relay IBus commits to native Wayland clients, so IBus reports success while nothing appears. Pin the wtype backend and restart Vocalinux.",
|
||||
"That is the classic IBus symptom: the compositor does not relay IBus commits to native Wayland clients, so IBus reports success while nothing appears. Pin the wtype backend and restart Voculinux.",
|
||||
},
|
||||
{
|
||||
question: "Does the RemoteDesktop portal work on sway or Hyprland?",
|
||||
answer:
|
||||
"Only if your portal backend implements org.freedesktop.portal.RemoteDesktop. GNOME and KDE Plasma do and most wlroots compositors do not. When it is missing, Vocalinux moves on to ydotool and then wtype.",
|
||||
"Only if your portal backend implements org.freedesktop.portal.RemoteDesktop. GNOME and KDE Plasma do and most wlroots compositors do not. When it is missing, Voculinux moves on to ydotool and then wtype.",
|
||||
},
|
||||
{
|
||||
question: "Can I use push-to-talk on a tiling compositor?",
|
||||
@@ -108,7 +108,7 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: `${PAGE_TITLE} | Vocalinux`,
|
||||
title: `${PAGE_TITLE} | Voculinux`,
|
||||
description: PAGE_DESCRIPTION,
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
@@ -157,17 +157,17 @@ export default function HyprlandSwayPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
},
|
||||
{
|
||||
"@type": "HowTo",
|
||||
name: "Set up Vocalinux voice typing on sway, i3 or Hyprland",
|
||||
name: "Set up Voculinux voice typing on sway, i3 or Hyprland",
|
||||
step: steps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -199,7 +199,7 @@ export default function HyprlandSwayPage() {
|
||||
Voice typing on Hyprland, sway and i3
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Tiling setups are hand-built, so Vocalinux cannot assume the pieces a
|
||||
Tiling setups are hand-built, so Voculinux cannot assume the pieces a
|
||||
full desktop provides. This guide covers which text injection backend
|
||||
applies on each compositor, how to bind dictation to a key in your
|
||||
config, and the fallback that works when typing into other windows
|
||||
@@ -261,7 +261,7 @@ export default function HyprlandSwayPage() {
|
||||
Text injection options
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Vocalinux picks a backend automatically. On Wayland, when IBus is not
|
||||
Voculinux picks a backend automatically. On Wayland, when IBus is not
|
||||
selected, it tries the RemoteDesktop portal first, then ydotool, then
|
||||
wtype, and finally xdotool for XWayland windows. sway and Hyprland are
|
||||
on its list of compositors that do not bridge IBus to native Wayland
|
||||
@@ -304,9 +304,9 @@ export default function HyprlandSwayPage() {
|
||||
</div>
|
||||
<h3 className="mb-2 mt-6 font-semibold">Pin a backend</h3>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Edit <InlineCode>~/.config/vocalinux/config.json</InlineCode> and
|
||||
restart Vocalinux. An explicit non-IBus value skips IBus selection. If
|
||||
the pinned tool is missing, Vocalinux warns and falls back to its
|
||||
Edit <InlineCode>~/.config/voculinux/config.json</InlineCode> and
|
||||
restart Voculinux. An explicit non-IBus value skips IBus selection. If
|
||||
the pinned tool is missing, Voculinux warns and falls back to its
|
||||
normal order.
|
||||
</p>
|
||||
<ConfigBlock label="config.json">
|
||||
@@ -320,12 +320,12 @@ export default function HyprlandSwayPage() {
|
||||
To try a backend for one run without saving it:
|
||||
</p>
|
||||
<TerminalBlock
|
||||
command="VOCALINUX_FORCE_BACKEND=wtype vocalinux --debug"
|
||||
displayCommand="VOCALINUX_FORCE_BACKEND=wtype vocalinux --debug"
|
||||
command="VOCULINUX_FORCE_BACKEND=wtype voculinux --debug"
|
||||
displayCommand="VOCULINUX_FORCE_BACKEND=wtype voculinux --debug"
|
||||
/>
|
||||
<h3 className="mb-2 mt-6 font-semibold">Terminals</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
When text goes in through the clipboard, Vocalinux sends Ctrl+V in
|
||||
When text goes in through the clipboard, Voculinux sends Ctrl+V in
|
||||
normal fields and Ctrl+Shift+V in terminal windows. Terminal detection
|
||||
works on Hyprland, sway and niri.
|
||||
</p>
|
||||
@@ -369,10 +369,10 @@ export default function HyprlandSwayPage() {
|
||||
</p>
|
||||
<div className="mb-4 grid gap-4 md:grid-cols-2">
|
||||
<ConfigBlock label="sway or i3 config">
|
||||
{"bindsym $mod+Shift+d exec vocalinux --toggle"}
|
||||
{"bindsym $mod+Shift+d exec voculinux --toggle"}
|
||||
</ConfigBlock>
|
||||
<ConfigBlock label="hyprland.conf">
|
||||
{"bind = SUPER SHIFT, D, exec, vocalinux --toggle"}
|
||||
{"bind = SUPER SHIFT, D, exec, voculinux --toggle"}
|
||||
</ConfigBlock>
|
||||
</div>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
@@ -425,7 +425,7 @@ export default function HyprlandSwayPage() {
|
||||
</h2>
|
||||
<h3 className="mb-2 font-semibold">Nothing is typed anywhere</h3>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Install the Wayland tools and test them by hand, then run Vocalinux
|
||||
Install the Wayland tools and test them by hand, then run Voculinux
|
||||
with debug logging and check which backend it reports. The startup log
|
||||
records a pin request; a live test in the target app is the real
|
||||
confirmation.
|
||||
@@ -489,7 +489,7 @@ export default function HyprlandSwayPage() {
|
||||
Dictate on your tiling setup
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux, check that wtype or xdotool can type, and bind
|
||||
Install Voculinux, check that wtype or xdotool can type, and bind
|
||||
dictation to a key in your compositor config.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
@@ -497,7 +497,7 @@ export default function HyprlandSwayPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -52,27 +52,27 @@ bash /tmp/vl.sh`;
|
||||
const DEB_OPTION: InstallOption = {
|
||||
label: "Native .deb package",
|
||||
note: "Download the .deb for your CPU from GitHub Releases (arm64 files are attached too). It is a thin package: Python and GTK come from the distro, whisper.cpp runs on the CPU, and there is no auto-update. On Wayland, add yourself to the input group (sudo usermod -aG input $USER, then log out and back in) or the default hotkey stays off.",
|
||||
command: "sudo apt install ./vocalinux_*_amd64.deb",
|
||||
command: "sudo apt install ./voculinux_*_amd64.deb",
|
||||
};
|
||||
|
||||
const RPM_OPTION: InstallOption = {
|
||||
label: "Native .rpm package",
|
||||
note: "Download the .rpm for your CPU from GitHub Releases (aarch64 files are attached too). It is a thin package: Python and GTK come from Fedora, whisper.cpp runs on the CPU, and there is no auto-update or COPR yet. On Wayland, add yourself to the input group (sudo usermod -aG input $USER, then log out and back in) or the default hotkey stays off.",
|
||||
command: "sudo dnf install ./vocalinux-*.x86_64.rpm",
|
||||
command: "sudo dnf install ./voculinux-*.x86_64.rpm",
|
||||
};
|
||||
|
||||
const FLATPAK_OPTION: InstallOption = {
|
||||
label: "Flatpak from the VocaHQ remote",
|
||||
note: "Not on Flathub. The self-hosted vocahq remote updates with flatpak update and ships whisper.cpp only.",
|
||||
command:
|
||||
"flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref",
|
||||
"flatpak install https://vocahq.github.io/voculinux-flatpak/com.voculinux.Voculinux.flatpakref",
|
||||
};
|
||||
|
||||
const COMMON_CHECKS = [
|
||||
"Run vocalinux --version to confirm the installed release.",
|
||||
"Launch vocalinux and confirm the tray icon appears. On GNOME, the tray needs the AppIndicator extension.",
|
||||
"Run voculinux --version to confirm the installed release.",
|
||||
"Launch voculinux and confirm the tray icon appears. On GNOME, the tray needs the AppIndicator extension.",
|
||||
"Hold Right Alt (Option) to dictate, or switch to toggle mode in Settings → Shortcuts, and confirm text lands in a terminal and a browser.",
|
||||
"If anything misbehaves, run vocalinux --debug and check the troubleshooting guide.",
|
||||
"If anything misbehaves, run voculinux --debug and check the troubleshooting guide.",
|
||||
];
|
||||
|
||||
const distroConfig: Record<DistroSlug, DistroConfig> = {
|
||||
@@ -110,9 +110,9 @@ const distroConfig: Record<DistroSlug, DistroConfig> = {
|
||||
name: "Debian",
|
||||
title: "Install Voice Dictation on Debian",
|
||||
description:
|
||||
"Install Vocalinux offline voice dictation on Debian 12, 13 and Testing with the install script or the native .deb. Covers AppIndicator, ydotool and Wayland.",
|
||||
"Install Voculinux offline voice dictation on Debian 12, 13 and Testing with the install script or the native .deb. Covers AppIndicator, ydotool and Wayland.",
|
||||
intro:
|
||||
"Debian 12 and newer are a primary target for Vocalinux. The install script detects Debian, installs the system packages it needs, and sets up whisper.cpp with a checksum-verified tiny model.",
|
||||
"Debian 12 and newer are a primary target for Voculinux. The install script detects Debian, installs the system packages it needs, and sets up whisper.cpp with a checksum-verified tiny model.",
|
||||
prerequisites: [
|
||||
"Debian 12 or newer, including Testing (Debian 11 and earlier are below the Python 3.11 floor)",
|
||||
"Python 3.11+ with the distro's python3-gi (the installer handles this)",
|
||||
@@ -128,7 +128,7 @@ const distroConfig: Record<DistroSlug, DistroConfig> = {
|
||||
setupNotes: [
|
||||
"Debian uses the Ayatana AppIndicator for the tray (gir1.2-ayatanaappindicator3-0.1); the installer picks it.",
|
||||
"Clean Debian installs lack some build tools for compiling pywhispercpp (libssl-dev, autoconf, automake, libtool, patchelf). The installer adds them; add them yourself before a manual rebuild.",
|
||||
"ydotool is not in Debian's standard repositories. Vocalinux falls back to IBus or wtype for most Wayland compositors.",
|
||||
"ydotool is not in Debian's standard repositories. Voculinux falls back to IBus or wtype for most Wayland compositors.",
|
||||
"On KDE Plasma Wayland, set System Settings → Keyboard → Virtual Keyboard to IBus Wayland.",
|
||||
],
|
||||
postInstallChecks: [
|
||||
@@ -140,9 +140,9 @@ const distroConfig: Record<DistroSlug, DistroConfig> = {
|
||||
name: "Fedora",
|
||||
title: "Install Voice Dictation on Fedora",
|
||||
description:
|
||||
"Fedora speech-to-text installation guide for Vocalinux. Set up offline Linux voice typing on Fedora 42+ with the install script or .rpm, on Wayland or X11.",
|
||||
"Fedora speech-to-text installation guide for Voculinux. Set up offline Linux voice typing on Fedora 42+ with the install script or .rpm, on Wayland or X11.",
|
||||
intro:
|
||||
"Fedora 42 and newer ship the Python and GTK stack Vocalinux needs, and Fedora 42 is the release in the project's CI matrix. This guide focuses on reliable setup and minimal friction.",
|
||||
"Fedora 42 and newer ship the Python and GTK stack Voculinux needs, and Fedora 42 is the release in the project's CI matrix. This guide focuses on reliable setup and minimal friction.",
|
||||
prerequisites: [
|
||||
"Fedora 42 or newer (Workstation or a spin)",
|
||||
"Python 3.11+ with python3-gobject (the installer handles this)",
|
||||
@@ -167,9 +167,9 @@ const distroConfig: Record<DistroSlug, DistroConfig> = {
|
||||
name: "Arch Linux",
|
||||
title: "Install Voice Dictation on Arch Linux",
|
||||
description:
|
||||
"Arch Linux voice dictation guide for offline speech recognition. Install Vocalinux from the AUR or the install script on Arch, Manjaro and EndeavourOS.",
|
||||
"Arch Linux voice dictation guide for offline speech recognition. Install Voculinux from the AUR or the install script on Arch, Manjaro and EndeavourOS.",
|
||||
intro:
|
||||
"Arch users can install Vocalinux from the AUR or with the install script. Both keep whisper.cpp as the default engine and work across rolling-release desktops.",
|
||||
"Arch users can install Voculinux from the AUR or with the install script. Both keep whisper.cpp as the default engine and work across rolling-release desktops.",
|
||||
prerequisites: [
|
||||
"Arch Linux, Manjaro or EndeavourOS",
|
||||
"Python 3.11+ with python-gobject",
|
||||
@@ -185,27 +185,27 @@ const distroConfig: Record<DistroSlug, DistroConfig> = {
|
||||
otherInstallOptions: [
|
||||
{
|
||||
label: "AUR packages",
|
||||
note: "vocalinux builds the canonical release sdist against Arch dependencies. vocalinux-bin installs the prebuilt release AppImage. vocalinux-git is a community package that tracks main. The three conflict, so install only one.",
|
||||
command: `yay -S vocalinux # canonical release sdist, built against Arch dependencies
|
||||
yay -S vocalinux-git # community package; tracks main`,
|
||||
note: "voculinux builds the canonical release sdist against Arch dependencies. voculinux-bin installs the prebuilt release AppImage. voculinux-git is a community package that tracks main. The three conflict, so install only one.",
|
||||
command: `yay -S voculinux # canonical release sdist, built against Arch dependencies
|
||||
yay -S voculinux-git # community package; tracks main`,
|
||||
},
|
||||
],
|
||||
setupNotes: [
|
||||
"Prefer whisper.cpp: it avoids the full PyTorch stack that OpenAI Whisper pulls in.",
|
||||
"On custom compositor setups, verify text injection behavior in both terminal and browser contexts.",
|
||||
"If you tweak keybinds heavily, set a non-conflicting activation shortcut in Vocalinux settings.",
|
||||
"If you tweak keybinds heavily, set a non-conflicting activation shortcut in Voculinux settings.",
|
||||
"AUR packages update with your AUR helper; the in-app update checker only notifies.",
|
||||
],
|
||||
postInstallChecks: [
|
||||
...COMMON_CHECKS,
|
||||
"Back up ~/.config/vocalinux/config.json after tuning preferences.",
|
||||
"Back up ~/.config/voculinux/config.json after tuning preferences.",
|
||||
],
|
||||
},
|
||||
opensuse: {
|
||||
name: "openSUSE",
|
||||
title: "Install Voice Dictation on openSUSE",
|
||||
description:
|
||||
"Install Vocalinux offline voice dictation on openSUSE Tumbleweed with the install script. Covers versioned Python packages, Vulkan builds, X11 and Wayland.",
|
||||
"Install Voculinux offline voice dictation on openSUSE Tumbleweed with the install script. Covers versioned Python packages, Vulkan builds, X11 and Wayland.",
|
||||
intro:
|
||||
"On openSUSE Tumbleweed the install script uses zypper, resolves the versioned Python packages for your snapshot, and sets up whisper.cpp with a checksum-verified tiny model.",
|
||||
prerequisites: [
|
||||
@@ -224,8 +224,8 @@ yay -S vocalinux-git # community package; tracks main`,
|
||||
{
|
||||
label: "AppImage",
|
||||
note: "Download the x86_64 or aarch64 AppImage from GitHub Releases. It starts on Tumbleweed and uses Vulkan through the host driver, but still needs host text-injection tools (xdotool on X11; wtype, ydotool or clipboard tools on Wayland).",
|
||||
command: `chmod +x Vocalinux-*-x86_64.AppImage # or aarch64
|
||||
./Vocalinux-*-x86_64.AppImage`,
|
||||
command: `chmod +x Voculinux-*-x86_64.AppImage # or aarch64
|
||||
./Voculinux-*-x86_64.AppImage`,
|
||||
},
|
||||
],
|
||||
setupNotes: [
|
||||
@@ -243,9 +243,9 @@ yay -S vocalinux-git # community package; tracks main`,
|
||||
name: "Linux Mint",
|
||||
title: "Install Voice Dictation on Linux Mint",
|
||||
description:
|
||||
"Install Vocalinux offline voice dictation on Linux Mint 22 with the install script or .deb. Covers Cinnamon, the Ubuntu 24.04 base and why Mint 21 is too old.",
|
||||
"Install Voculinux offline voice dictation on Linux Mint 22 with the install script or .deb. Covers Cinnamon, the Ubuntu 24.04 base and why Mint 21 is too old.",
|
||||
intro:
|
||||
"Linux Mint is judged by its Ubuntu base, not its own version number. Mint 22 is built on Ubuntu 24.04, so the install script treats it as Ubuntu and installs everything Vocalinux needs.",
|
||||
"Linux Mint is judged by its Ubuntu base, not its own version number. Mint 22 is built on Ubuntu 24.04, so the install script treats it as Ubuntu and installs everything Voculinux needs.",
|
||||
prerequisites: [
|
||||
"Linux Mint 22 or newer, on an Ubuntu 24.04+ base (Mint 21 is on Ubuntu 22.04, below the floor)",
|
||||
"Python 3.11+ with the distro's python3-gi (the installer handles this)",
|
||||
@@ -267,7 +267,7 @@ yay -S vocalinux-git # community package; tracks main`,
|
||||
setupNotes: [
|
||||
"Keep the default whisper.cpp engine unless you have a specific reason to switch.",
|
||||
"Cinnamon is fully supported and works with AppIndicator for the tray icon.",
|
||||
"Text is typed with xdotool on X11 sessions; on Wayland, Vocalinux picks from IBus, the RemoteDesktop portal, wtype or ydotool.",
|
||||
"Text is typed with xdotool on X11 sessions; on Wayland, Voculinux picks from IBus, the RemoteDesktop portal, wtype or ydotool.",
|
||||
"The install script adds you to the input group for Wayland hotkeys; log out and back in afterwards.",
|
||||
],
|
||||
postInstallChecks: [...COMMON_CHECKS],
|
||||
@@ -276,7 +276,7 @@ yay -S vocalinux-git # community package; tracks main`,
|
||||
name: "Pop!_OS",
|
||||
title: "Install Voice Dictation on Pop!_OS",
|
||||
description:
|
||||
"Install Vocalinux offline voice dictation on Pop!_OS 24.04 with the install script or .deb. Covers the Ubuntu base, Wayland hotkeys and fallback options.",
|
||||
"Install Voculinux offline voice dictation on Pop!_OS 24.04 with the install script or .deb. Covers the Ubuntu base, Wayland hotkeys and fallback options.",
|
||||
intro:
|
||||
"Pop!_OS uses Ubuntu's own version numbering, and 24.04 and newer meet the Python 3.11 floor. The install script detects Pop!_OS as part of the Ubuntu family.",
|
||||
prerequisites: [
|
||||
@@ -291,7 +291,7 @@ yay -S vocalinux-git # community package; tracks main`,
|
||||
setupNotes: [
|
||||
"For a manual install, use libgirepository-2.0-dev if libgirepository1.0-dev is not available.",
|
||||
"The install script adds you to the input group for Wayland hotkeys; log out and back in afterwards.",
|
||||
"If the hotkey or typing does not work in your session, enable Settings → Shortcuts → External Activation (Desktop Shortcut) and bind a desktop shortcut to vocalinux --toggle (toggle only, no push-to-talk), or dictate into the Dictation Pad and copy the text out.",
|
||||
"If the hotkey or typing does not work in your session, enable Settings → Shortcuts → External Activation (Desktop Shortcut) and bind a desktop shortcut to voculinux --toggle (toggle only, no push-to-talk), or dictate into the Dictation Pad and copy the text out.",
|
||||
"whisper.cpp uses a Vulkan GPU when available; check with vulkaninfo --summary.",
|
||||
],
|
||||
postInstallChecks: [...COMMON_CHECKS],
|
||||
@@ -321,7 +321,7 @@ const distroKeywords: Record<DistroSlug, string[]> = {
|
||||
"arch linux voice dictation",
|
||||
"speech to text arch linux",
|
||||
"manjaro dictation",
|
||||
"vocalinux aur",
|
||||
"voculinux aur",
|
||||
],
|
||||
opensuse: [
|
||||
"opensuse voice dictation",
|
||||
@@ -423,7 +423,7 @@ export async function generateMetadata({
|
||||
return buildPageMetadata({
|
||||
title: "Linux Voice Dictation Install Guide",
|
||||
description:
|
||||
"Install Vocalinux on Linux with distro-specific setup instructions for Ubuntu, Debian, Fedora, Arch, openSUSE, Linux Mint, and Pop!_OS.",
|
||||
"Install Voculinux on Linux with distro-specific setup instructions for Ubuntu, Debian, Fedora, Arch, openSUSE, Linux Mint, and Pop!_OS.",
|
||||
path: "/install",
|
||||
});
|
||||
}
|
||||
@@ -494,7 +494,7 @@ export default async function DistroInstallPage({
|
||||
{
|
||||
"@type": "HowToStep",
|
||||
name: "Start dictating",
|
||||
text: "Launch vocalinux and hold Right Alt (Option) to begin dictation, or choose toggle mode in Settings.",
|
||||
text: "Launch voculinux and hold Right Alt (Option) to begin dictation, or choose toggle mode in Settings.",
|
||||
url: absoluteUrl(`/install/${distro}`),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -13,9 +13,9 @@ import { SeoSubpageShell } from "@/components/seo-subpage-shell";
|
||||
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
|
||||
const PAGE_PATH = "/install/nixos";
|
||||
const PAGE_TITLE = "Vocalinux on NixOS: Nix Flake and NixOS Module | Vocalinux";
|
||||
const PAGE_TITLE = "Voculinux on NixOS: Nix Flake and NixOS Module | Voculinux";
|
||||
const PAGE_DESCRIPTION =
|
||||
"Install Vocalinux on NixOS or any Nix system with the official flake: nix run, nix profile, the NixOS and Home Manager modules, Wayland groups and scope.";
|
||||
"Install Voculinux on NixOS or any Nix system with the official flake: nix run, nix profile, the NixOS and Home Manager modules, Wayland groups and scope.";
|
||||
|
||||
const TRY_COMMANDS = `nix run github:VocaHQ/vocalinux # try it
|
||||
nix profile install github:VocaHQ/vocalinux`;
|
||||
@@ -56,7 +56,7 @@ const HOME_MANAGER_SNIPPET = `{
|
||||
const flakeOutputs = [
|
||||
{
|
||||
output: "packages.<system>.vocalinux (also default)",
|
||||
purpose: "The Vocalinux package for x86_64-linux and aarch64-linux",
|
||||
purpose: "The Voculinux package for x86_64-linux and aarch64-linux",
|
||||
},
|
||||
{
|
||||
output: "apps.<system>.vocalinux (also default)",
|
||||
@@ -130,10 +130,10 @@ export const metadata: Metadata = buildPageMetadata({
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"nixos voice dictation",
|
||||
"vocalinux nix flake",
|
||||
"voculinux nix flake",
|
||||
"nixos speech to text",
|
||||
"nixos module vocalinux",
|
||||
"home manager vocalinux",
|
||||
"nixos module voculinux",
|
||||
"home manager voculinux",
|
||||
"nix whisper.cpp dictation",
|
||||
],
|
||||
});
|
||||
@@ -152,7 +152,7 @@ export default function NixosInstallPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
headline: "Install Vocalinux on NixOS with the Nix flake",
|
||||
headline: "Install Voculinux on NixOS with the Nix flake",
|
||||
description: PAGE_DESCRIPTION,
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
@@ -162,10 +162,10 @@ export default function NixosInstallPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
@@ -174,7 +174,7 @@ export default function NixosInstallPage() {
|
||||
const howToJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Enable Vocalinux with the NixOS module",
|
||||
name: "Enable Voculinux with the NixOS module",
|
||||
description: PAGE_DESCRIPTION,
|
||||
tool: [{ "@type": "HowToTool", name: "Nix with flakes" }],
|
||||
step: moduleSteps.map((step) => ({
|
||||
@@ -213,14 +213,16 @@ export default function NixosInstallPage() {
|
||||
<section>
|
||||
<p className="subpage-kicker">Added in v0.18.2</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Install Vocalinux on NixOS with the Nix flake
|
||||
Install on NixOS with the Nix flake
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
The Vocalinux repository is a Nix flake. It builds the app against
|
||||
nixpkgs, ships a NixOS module and a Home Manager module, and wires
|
||||
every text-injection and clipboard tool onto the wrapped
|
||||
binary’s PATH. Use it on NixOS, or on any Linux with Nix and
|
||||
flakes enabled.
|
||||
<p className="mb-4 max-w-4xl text-lg text-muted-foreground">
|
||||
Voculinux does not yet publish its own Nix flake. The flake below is
|
||||
the upstream Vocalinux flake: it builds the app against nixpkgs,
|
||||
ships a NixOS module and a Home Manager module, and wires every
|
||||
text-injection and clipboard tool onto the wrapped binary’s
|
||||
PATH. Its snippets install Vocalinux (upstream), not Voculinux. For
|
||||
Voculinux on Void Linux, use the signed xbps repository or the
|
||||
install script.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -230,8 +232,9 @@ export default function NixosInstallPage() {
|
||||
Try it or install into a profile
|
||||
</h2>
|
||||
<p className="mb-3 text-muted-foreground">
|
||||
No configuration needed. <code>nix run</code> starts Vocalinux once;{" "}
|
||||
<code>nix profile install</code> keeps it in your user profile:
|
||||
No configuration needed. <code>nix run</code> starts Vocalinux
|
||||
(upstream) once; <code>nix profile install</code> keeps it in your
|
||||
user profile:
|
||||
</p>
|
||||
<Commands>{TRY_COMMANDS}</Commands>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
@@ -348,7 +351,7 @@ export default function NixosInstallPage() {
|
||||
conventional filesystem layout; the flake is the supported path.
|
||||
</li>
|
||||
<li>
|
||||
Speech models are not part of the Nix store. Vocalinux downloads one
|
||||
Speech models are not part of the Nix store. Voculinux downloads one
|
||||
only after you confirm it, and shows the size first.
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -31,7 +31,7 @@ const distroGuides = [
|
||||
name: "Arch Linux",
|
||||
href: "/install/arch/",
|
||||
description:
|
||||
"Install Vocalinux on Arch, Manjaro, and EndeavourOS with package prerequisites and tips.",
|
||||
"Install Voculinux on Arch, Manjaro, and EndeavourOS with package prerequisites and tips.",
|
||||
icon: Cpu,
|
||||
},
|
||||
{
|
||||
@@ -55,7 +55,7 @@ const distroGuides = [
|
||||
{
|
||||
name: "Pop!_OS",
|
||||
href: "/install/pop-os/",
|
||||
description: "Install Vocalinux on Pop!_OS 24.04 and later.",
|
||||
description: "Install Voculinux on Pop!_OS 24.04 and later.",
|
||||
icon: Laptop,
|
||||
},
|
||||
{
|
||||
@@ -99,7 +99,7 @@ export default function InstallGuidesPage() {
|
||||
/>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
Then launch <code>vocalinux</code>.
|
||||
Then launch <code>voculinux</code>.
|
||||
</p>
|
||||
<div className="install-alts">
|
||||
<a
|
||||
@@ -140,25 +140,25 @@ export default function InstallGuidesPage() {
|
||||
</a>
|
||||
<a
|
||||
className="install-alt"
|
||||
href="https://snapcraft.io/vocalinux"
|
||||
href="https://snapcraft.io/voculinux"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<p className="install-alt-kicker">Snap Store</p>
|
||||
<h2>Snap</h2>
|
||||
<p>
|
||||
<code>snap install vocalinux --edge</code>. amd64 only for
|
||||
<code>snap install voculinux --edge</code>. amd64 only for
|
||||
now; a .snap is attached to every release too.
|
||||
</p>
|
||||
</a>
|
||||
<a
|
||||
className="install-alt"
|
||||
href="https://aur.archlinux.org/packages/vocalinux"
|
||||
href="https://aur.archlinux.org/packages/voculinux"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<p className="install-alt-kicker">Arch</p>
|
||||
<h2>AUR</h2>
|
||||
<p>
|
||||
<code>yay -S vocalinux</code>, or vocalinux-bin for the
|
||||
<code>yay -S voculinux</code>, or voculinux-bin for the
|
||||
prebuilt package.
|
||||
</p>
|
||||
</a>
|
||||
@@ -208,7 +208,7 @@ export default function InstallGuidesPage() {
|
||||
<li>
|
||||
Launch with{" "}
|
||||
<code className="rounded bg-muted px-1.5 py-0.5 font-mono text-sm text-foreground">
|
||||
vocalinux
|
||||
voculinux
|
||||
</code>
|
||||
.
|
||||
</li>
|
||||
|
||||
@@ -288,7 +288,7 @@ const features = [
|
||||
{
|
||||
title: "Automatic Language Detection",
|
||||
description:
|
||||
"Vocalinux can automatically detect the language you're speaking, no manual switching required.",
|
||||
"Voculinux can automatically detect the language you're speaking, no manual switching required.",
|
||||
icon: Globe,
|
||||
},
|
||||
{
|
||||
@@ -335,7 +335,7 @@ export default function LanguagesPage() {
|
||||
"@type": "Article",
|
||||
headline: `Multilingual Voice Dictation for Linux - ${languageCount}+ Languages Supported`,
|
||||
description:
|
||||
"Complete guide to Vocalinux multilingual voice dictation. Dictate in Spanish, French, German, Hungarian, Japanese, Korean, Arabic, Hindi, and more.",
|
||||
"Complete guide to Voculinux multilingual voice dictation. Dictate in Spanish, French, German, Hungarian, Japanese, Korean, Arabic, Hindi, and more.",
|
||||
dateModified: "2026-07-29",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -344,10 +344,10 @@ export default function LanguagesPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/languages"),
|
||||
@@ -369,7 +369,7 @@ export default function LanguagesPage() {
|
||||
Multilingual Voice Dictation for Linux
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Dictate in your native language. Vocalinux lists {languageCount} languages in Settings,
|
||||
Dictate in your native language. Voculinux lists {languageCount} languages in Settings,
|
||||
and whisper.cpp / Whisper can auto-detect many more. Local engines stay on the machine.
|
||||
</p>
|
||||
</section>
|
||||
@@ -464,7 +464,7 @@ export default function LanguagesPage() {
|
||||
<section className="rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Ready to Dictate in Your Language?</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux and start dictating in your preferred language. All processing happens
|
||||
Install Voculinux and start dictating in your preferred language. All processing happens
|
||||
locally on your Linux machine.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
SITE_NAME,
|
||||
SITE_URL,
|
||||
TWITTER_HANDLE,
|
||||
VOCAHQ_URL,
|
||||
} from "@/lib/seo";
|
||||
|
||||
export const viewport = {
|
||||
@@ -23,8 +22,8 @@ export const viewport = {
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(SITE_URL),
|
||||
title: {
|
||||
default: "Vocalinux: Offline Speech to Text & Voice Dictation for Linux",
|
||||
template: "%s | Vocalinux",
|
||||
default: "Voculinux: Offline Speech to Text & Voice Dictation for Linux",
|
||||
template: "%s | Voculinux",
|
||||
},
|
||||
description:
|
||||
"Free, open-source speech to text for Linux. Offline voice dictation and voice typing in any app with whisper.cpp, VOSK or Parakeet, on X11 and Wayland.",
|
||||
@@ -52,11 +51,11 @@ export const metadata: Metadata = {
|
||||
publisher: SITE_NAME,
|
||||
icons: {
|
||||
icon: [
|
||||
{ url: "/brand/vocalinux-mark-circle.svg", type: "image/svg+xml" },
|
||||
{ url: "/brand/voculinux-mark-circle.svg", type: "image/svg+xml" },
|
||||
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
|
||||
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
|
||||
{ url: "/favicon-96x96.png", sizes: "96x96", type: "image/png" },
|
||||
{ url: "/vocalinux.png", type: "image/png", sizes: "512x512" },
|
||||
{ url: "/voculinux.png", type: "image/png", sizes: "512x512" },
|
||||
],
|
||||
apple: [
|
||||
{ url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" },
|
||||
@@ -80,7 +79,7 @@ export const metadata: Metadata = {
|
||||
locale: "en_US",
|
||||
url: absoluteUrl("/"),
|
||||
siteName: SITE_NAME,
|
||||
title: "Vocalinux: Offline Speech to Text & Voice Dictation for Linux",
|
||||
title: "Voculinux: Offline Speech to Text & Voice Dictation for Linux",
|
||||
description:
|
||||
"Voice dictation for Linux with local engines or an optional Remote API. Install in minutes and dictate in any app on Ubuntu, Fedora, Arch, X11, or Wayland.",
|
||||
images: [
|
||||
@@ -94,7 +93,7 @@ export const metadata: Metadata = {
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Vocalinux: Offline Speech to Text & Voice Dictation for Linux",
|
||||
title: "Voculinux: Offline Speech to Text & Voice Dictation for Linux",
|
||||
description:
|
||||
"Speech-to-text for Linux with whisper.cpp and VOSK. Local engines by default, optional Remote API, open source.",
|
||||
images: [DEFAULT_OG_IMAGE_PATH],
|
||||
@@ -127,19 +126,14 @@ const organizationJsonLd = {
|
||||
"@id": `${absoluteUrl("/")}#organization`,
|
||||
name: SITE_NAME,
|
||||
url: absoluteUrl("/"),
|
||||
logo: absoluteUrl("/vocalinux.png"),
|
||||
logo: absoluteUrl("/voculinux.png"),
|
||||
description: "Open-source, offline voice dictation software for Linux.",
|
||||
sameAs: [GITHUB_REPO_URL, VOCAHQ_URL],
|
||||
sameAs: [GITHUB_REPO_URL, "https://bongbetic.com"],
|
||||
founder: {
|
||||
"@type": "Person",
|
||||
name: "Jatin K Malik",
|
||||
url: "https://github.com/jatinkrmalik",
|
||||
},
|
||||
parentOrganization: {
|
||||
"@type": "Organization",
|
||||
name: "VocaHQ",
|
||||
url: VOCAHQ_URL,
|
||||
},
|
||||
};
|
||||
|
||||
const webSiteJsonLd = {
|
||||
@@ -150,7 +144,7 @@ const webSiteJsonLd = {
|
||||
url: absoluteUrl("/"),
|
||||
inLanguage: "en-US",
|
||||
description:
|
||||
"Vocalinux provides offline speech-to-text and voice dictation for Linux desktops.",
|
||||
"Voculinux provides offline speech-to-text and voice dictation for Linux desktops.",
|
||||
publisher: {
|
||||
"@id": `${absoluteUrl("/")}#organization`,
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const PAGE_PATH = "/local-gateway";
|
||||
const PAGE_TITLE = "Run a Local VocaGateway for Linux Dictation";
|
||||
const PAGE_DESCRIPTION =
|
||||
"Start a local VocaGateway from Vocalinux Settings with podman or docker, connect it via Remote API, and learn why gateway mode is not on-device transcription.";
|
||||
"Start a local VocaGateway from Voculinux Settings with podman or docker, connect it via Remote API, and learn why gateway mode is not on-device transcription.";
|
||||
|
||||
const comparisonRows = [
|
||||
{
|
||||
@@ -74,7 +74,7 @@ const steps = [
|
||||
},
|
||||
{
|
||||
name: "Use this Gateway",
|
||||
text: "Click Use this Gateway. Vocalinux fills Remote Server with the gateway URL and bearer token, sets the endpoint to /v1/audio/transcriptions and switches the engine to Remote API.",
|
||||
text: "Click Use this Gateway. Voculinux fills Remote Server with the gateway URL and bearer token, sets the endpoint to /v1/audio/transcriptions and switches the engine to Remote API.",
|
||||
},
|
||||
{
|
||||
name: "Dictate and verify",
|
||||
@@ -86,10 +86,10 @@ const faqs = [
|
||||
{
|
||||
question: "Is a local gateway the same as on-device dictation?",
|
||||
answer:
|
||||
"No. Even on 127.0.0.1, audio leaves the Vocalinux client and is transcribed by a separate gateway process over HTTP. The on-device path is a local engine such as whisper.cpp, which stays the default.",
|
||||
"No. Even on 127.0.0.1, audio leaves the Voculinux client and is transcribed by a separate gateway process over HTTP. The on-device path is a local engine such as whisper.cpp, which stays the default.",
|
||||
},
|
||||
{
|
||||
question: "Does quitting Vocalinux stop the gateway?",
|
||||
question: "Does quitting Voculinux stop the gateway?",
|
||||
answer:
|
||||
"No. The pinned compose file uses restart: unless-stopped, so the container keeps running after Quit. Use Stop local Gateway in Settings or the tray menu.",
|
||||
},
|
||||
@@ -111,14 +111,14 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: `${PAGE_TITLE} | Vocalinux`,
|
||||
title: `${PAGE_TITLE} | Voculinux`,
|
||||
description: PAGE_DESCRIPTION,
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"vocagateway linux",
|
||||
"local speech gateway podman",
|
||||
"self hosted dictation gateway",
|
||||
"vocalinux remote api gateway",
|
||||
"voculinux remote api gateway",
|
||||
"docker speech to text linux dictation",
|
||||
"phone dictation gateway linux",
|
||||
],
|
||||
@@ -148,17 +148,17 @@ export default function LocalGatewayPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
},
|
||||
{
|
||||
"@type": "HowTo",
|
||||
name: "Run a local VocaGateway from Vocalinux Settings",
|
||||
name: "Run a local VocaGateway from Voculinux Settings",
|
||||
step: steps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -187,10 +187,10 @@ export default function LocalGatewayPage() {
|
||||
<section>
|
||||
<p className="subpage-kicker">Added in v0.18.0 · optional</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Run a local VocaGateway from Vocalinux
|
||||
Run a local VocaGateway from Voculinux
|
||||
</h1>
|
||||
<p className="mb-6 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux can start{" "}
|
||||
Voculinux can start{" "}
|
||||
<a
|
||||
href="https://vocagateway.vocahq.com/"
|
||||
target="_blank"
|
||||
@@ -212,10 +212,10 @@ export default function LocalGatewayPage() {
|
||||
Gateway mode is not the on-device engine
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
With a local engine, audio is transcribed on this machine by Vocalinux
|
||||
With a local engine, audio is transcribed on this machine by Voculinux
|
||||
itself. In gateway mode it is sent over HTTP to the gateway, even when
|
||||
that gateway runs on <InlineCode>127.0.0.1</InlineCode>. If you point
|
||||
Vocalinux at a gateway on another machine, your audio leaves this
|
||||
Voculinux at a gateway on another machine, your audio leaves this
|
||||
machine for that endpoint. Keep it on a trusted LAN, an encrypted
|
||||
private network such as Tailscale, or HTTPS, and never expose port
|
||||
8765 to the public internet. Enabling the gateway does not change the
|
||||
@@ -334,7 +334,7 @@ export default function LocalGatewayPage() {
|
||||
|
||||
<section className="mb-12 rounded-[12px] border border-border bg-background p-6">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">
|
||||
What Vocalinux sets up
|
||||
What Voculinux sets up
|
||||
</h2>
|
||||
<ul className="list-disc space-y-2 pl-5 text-sm text-muted-foreground">
|
||||
<li>
|
||||
@@ -347,7 +347,7 @@ export default function LocalGatewayPage() {
|
||||
</li>
|
||||
<li>
|
||||
A private bootstrap token in{" "}
|
||||
<InlineCode>~/.config/vocalinux/gateway_embed/</InlineCode> with
|
||||
<InlineCode>~/.config/voculinux/gateway_embed/</InlineCode> with
|
||||
mode 600, plus a matching Compose <InlineCode>.env</InlineCode>.
|
||||
</li>
|
||||
<li>
|
||||
@@ -383,10 +383,10 @@ export default function LocalGatewayPage() {
|
||||
</p>
|
||||
<h3 className="mb-2 font-semibold">Quit does not stop it</h3>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
The container keeps running after you quit Vocalinux, including a
|
||||
The container keeps running after you quit Voculinux, including a
|
||||
LAN-published one. Use Stop local Gateway in Settings or the tray
|
||||
menu, which appears whenever Compose is running. Stopping keeps the
|
||||
named data volume, so downloaded models survive. Vocalinux does not
|
||||
named data volume, so downloaded models survive. Voculinux does not
|
||||
start the gateway on login.
|
||||
</p>
|
||||
<h3 className="mb-2 font-semibold">Other machines</h3>
|
||||
@@ -446,7 +446,7 @@ export default function LocalGatewayPage() {
|
||||
Start on-device, add a gateway later
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux with the default on-device engine. Add a local
|
||||
Install Voculinux with the default on-device engine. Add a local
|
||||
VocaGateway only if you need a shared transcription service.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
@@ -454,7 +454,7 @@ export default function LocalGatewayPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -12,7 +12,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
|
||||
const PAGE_PATH = "/multilingual-dictation";
|
||||
|
||||
// Mirrors SUPPORTED_LANGUAGES in src/vocalinux/utils/vosk_model_info.py (v0.18.5).
|
||||
// Mirrors SUPPORTED_LANGUAGES in src/voculinux/utils/vosk_model_info.py (v0.18.5).
|
||||
const catalog: { code: string; name: string; vosk: boolean }[] = [
|
||||
{ code: "en-us", name: "English (US)", vosk: true },
|
||||
{ code: "en-in", name: "English (India)", vosk: true },
|
||||
@@ -109,20 +109,20 @@ const howToSteps = [
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
q: "How many languages does Vocalinux support?",
|
||||
q: "How many languages does Voculinux support?",
|
||||
a: "The language catalog has 33 languages plus Auto-detect. English appears twice, as English (US) and English (India), so the list has 34 entries. Slovenian was added in v0.18.4.",
|
||||
},
|
||||
{
|
||||
q: "Can Vocalinux switch language in the middle of a sentence?",
|
||||
q: "Can Voculinux switch language in the middle of a sentence?",
|
||||
a: "No. Whisper-family engines take one language per dictation, or detect it once per utterance on Auto-detect. For mixed-language work, use Follow keyboard layout or a language shortcut so each dictation starts in the right language.",
|
||||
},
|
||||
{
|
||||
q: "Follow keyboard layout always picks the same language. Why?",
|
||||
a: "Reading the active layout uses GNOME's input-source settings. On other desktops Vocalinux falls back to the configured primary layout, which does not change when you switch. A layout that maps to no catalog language falls back to auto-detect.",
|
||||
a: "Reading the active layout uses GNOME's input-source settings. On other desktops Voculinux falls back to the configured primary layout, which does not change when you switch. A layout that maps to no catalog language falls back to auto-detect.",
|
||||
},
|
||||
{
|
||||
q: "My language shortcut plays an error sound. What is wrong?",
|
||||
a: "The loaded model cannot dictate in that language without a reload: an English-only Whisper model, a VOSK model for another language, or Parakeet. Vocalinux refuses rather than dictating in the wrong language. Choose a multilingual Whisper-family model.",
|
||||
a: "The loaded model cannot dictate in that language without a reload: an English-only Whisper model, a VOSK model for another language, or Parakeet. Voculinux refuses rather than dictating in the wrong language. Choose a multilingual Whisper-family model.",
|
||||
},
|
||||
{
|
||||
q: "Do voice commands work in other languages?",
|
||||
@@ -131,7 +131,7 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Multilingual Voice Dictation on Linux: 33 Languages | Vocalinux",
|
||||
title: "Multilingual Voice Dictation on Linux: 33 Languages | Voculinux",
|
||||
description:
|
||||
"Dictate in more than one language on Linux: per-language shortcuts, follow your keyboard layout, 33 languages plus auto-detect, and per-engine limits.",
|
||||
path: PAGE_PATH,
|
||||
@@ -149,9 +149,9 @@ export default function MultilingualDictationPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
headline: "Multilingual Voice Dictation on Linux with Vocalinux",
|
||||
headline: "Multilingual Voice Dictation on Linux with Voculinux",
|
||||
description:
|
||||
"How to dictate in more than one language with Vocalinux: the language catalog, per-language shortcuts, following the keyboard layout and engine caveats.",
|
||||
"How to dictate in more than one language with Voculinux: the language catalog, per-language shortcuts, following the keyboard layout and engine caveats.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -160,10 +160,10 @@ export default function MultilingualDictationPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
@@ -172,7 +172,7 @@ export default function MultilingualDictationPage() {
|
||||
const howToJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Set up a per-language dictation shortcut in Vocalinux",
|
||||
name: "Set up a per-language dictation shortcut in Voculinux",
|
||||
step: howToSteps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -213,7 +213,7 @@ export default function MultilingualDictationPage() {
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Per-language shortcuts and Follow keyboard layout arrived in v0.18.0.
|
||||
If you write in more than one language, Vocalinux gives you three ways
|
||||
If you write in more than one language, Voculinux gives you three ways
|
||||
to get the right one each time: auto-detect per utterance, a separate
|
||||
shortcut per language, or following whichever keyboard layout you are
|
||||
typing with. This page covers each, which engines support them, and
|
||||
@@ -259,7 +259,7 @@ export default function MultilingualDictationPage() {
|
||||
makes the engine guess the language each time; the optional Other
|
||||
language picker just records which one you had in mind, because
|
||||
Whisper-family engines take a single language or none. On first run,
|
||||
Vocalinux seeds the language from your keyboard layout and locale
|
||||
Voculinux seeds the language from your keyboard layout and locale
|
||||
(since v0.17.0).
|
||||
</p>
|
||||
<p className="text-muted-foreground">
|
||||
@@ -303,7 +303,7 @@ export default function MultilingualDictationPage() {
|
||||
</h2>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
Expand Advanced on the Speech Model page and turn on Follow keyboard
|
||||
layout. Vocalinux then re-reads the active layout at the start of
|
||||
layout. Voculinux then re-reads the active layout at the start of
|
||||
every dictation and uses the matching language. The Language picker
|
||||
greys out and shows what the current layout resolves to; turning the
|
||||
switch off pins that language.
|
||||
@@ -319,7 +319,7 @@ export default function MultilingualDictationPage() {
|
||||
Japanese, Pinyin and Rime to Chinese, and Hangul to Korean.
|
||||
</li>
|
||||
<li>
|
||||
On other desktops Vocalinux uses the configured primary layout,
|
||||
On other desktops Voculinux uses the configured primary layout,
|
||||
which does not follow your switches. A layout with no catalog
|
||||
language falls back to auto-detect.
|
||||
</li>
|
||||
@@ -334,7 +334,7 @@ export default function MultilingualDictationPage() {
|
||||
The settings in config.json
|
||||
</h2>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Settings writes these to <code>~/.config/vocalinux/config.json</code>.
|
||||
Settings writes these to <code>~/.config/voculinux/config.json</code>.
|
||||
The value <code>"layout"</code> is how Follow keyboard
|
||||
layout is stored:
|
||||
</p>
|
||||
@@ -469,7 +469,7 @@ export default function MultilingualDictationPage() {
|
||||
Dictate in your languages
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux, keep the default whisper.cpp engine with a
|
||||
Install Voculinux, keep the default whisper.cpp engine with a
|
||||
multilingual model, and add a shortcut for each language you write in.
|
||||
Names and jargon in any language can go in the{" "}
|
||||
<Link href="/custom-dictionary/">custom dictionary</Link>.
|
||||
@@ -479,7 +479,7 @@ export default function MultilingualDictationPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -5,7 +5,7 @@ import { DidYouMean } from "@/components/not-found-extras";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Page not found",
|
||||
description: "This page does not exist. Head back to the Vocalinux home page.",
|
||||
description: "This page does not exist. Head back to the Voculinux home page.",
|
||||
// Overrides the layout's "index, follow" so it agrees with Next's noindex.
|
||||
robots: { index: false, follow: true },
|
||||
};
|
||||
@@ -46,7 +46,7 @@ export default function NotFound() {
|
||||
</h1>
|
||||
<p className="nf-lede">
|
||||
The link is broken, the page moved, or the URL picked up a typo
|
||||
on the way here. Vocalinux can type what you say, but it can't
|
||||
on the way here. Voculinux can type what you say, but it can't
|
||||
type a page that doesn't exist.
|
||||
</p>
|
||||
</section>
|
||||
@@ -70,7 +70,7 @@ export default function NotFound() {
|
||||
Back to home
|
||||
</Link>
|
||||
<Link className="btn btn-secondary" href="/install/">
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
</Link>
|
||||
</div>
|
||||
<nav className="nf-links" aria-label="Popular pages">
|
||||
|
||||
@@ -71,7 +71,7 @@ const sensitiveUseCases = [
|
||||
{
|
||||
title: "Remote API is opt-in",
|
||||
description:
|
||||
"If you point Vocalinux at a server you configure, audio goes there. Local engines do not.",
|
||||
"If you point Voculinux at a server you configure, audio goes there. Local engines do not.",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -107,10 +107,10 @@ export default function OfflinePage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/offline"),
|
||||
@@ -163,7 +163,7 @@ export default function OfflinePage() {
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<th className="pb-3 pr-4 font-semibold">Feature</th>
|
||||
<th className="pb-3 pr-4 font-semibold text-center">Vocalinux (Offline)</th>
|
||||
<th className="pb-3 pr-4 font-semibold text-center">Voculinux (Offline)</th>
|
||||
<th className="pb-3 font-semibold text-center">Cloud Dictation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -218,7 +218,7 @@ export default function OfflinePage() {
|
||||
How Offline Processing Works
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Vocalinux uses speech recognition models that run entirely on your CPU or GPU:
|
||||
Voculinux uses speech recognition models that run entirely on your CPU or GPU:
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
<li className="flex items-start gap-2">
|
||||
@@ -247,7 +247,7 @@ export default function OfflinePage() {
|
||||
Verify It Yourself
|
||||
</h2>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Don't trust - verify. Vocalinux is open source. You can:
|
||||
Don't trust - verify. Voculinux is open source. You can:
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
<li className="flex items-start gap-2">
|
||||
@@ -283,7 +283,7 @@ export default function OfflinePage() {
|
||||
<section className="rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Truly Private Voice Dictation</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux and use a local engine if you want speech recognition on the machine.
|
||||
Install Voculinux and use a local engine if you want speech recognition on the machine.
|
||||
Remote API stays optional.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
|
||||
@@ -52,13 +52,13 @@ const benefits = [
|
||||
];
|
||||
|
||||
const vsProprietary = [
|
||||
{ feature: "Cost", vocalinux: "Free and open source", proprietary: "$10-500/month or $500+ license" },
|
||||
{ feature: "Source Code", vocalinux: "Fully open", proprietary: "Closed, proprietary" },
|
||||
{ feature: "Data Privacy", vocalinux: "Local engines by default", proprietary: "Often cloud-based" },
|
||||
{ feature: "Linux Support", vocalinux: "Native", proprietary: "Limited or none" },
|
||||
{ feature: "Customization", vocalinux: "Unlimited", proprietary: "Limited to vendor options" },
|
||||
{ feature: "Vendor Dependency", vocalinux: "None", proprietary: "High" },
|
||||
{ feature: "Community Support", vocalinux: "Active GitHub community", proprietary: "Paid support only" },
|
||||
{ feature: "Cost", voculinux: "Free and open source", proprietary: "$10-500/month or $500+ license" },
|
||||
{ feature: "Source Code", voculinux: "Fully open", proprietary: "Closed, proprietary" },
|
||||
{ feature: "Data Privacy", voculinux: "Local engines by default", proprietary: "Often cloud-based" },
|
||||
{ feature: "Linux Support", voculinux: "Native", proprietary: "Limited or none" },
|
||||
{ feature: "Customization", voculinux: "Unlimited", proprietary: "Limited to vendor options" },
|
||||
{ feature: "Vendor Dependency", voculinux: "None", proprietary: "High" },
|
||||
{ feature: "Community Support", voculinux: "Active GitHub community", proprietary: "Paid support only" },
|
||||
];
|
||||
|
||||
const techStack = [
|
||||
@@ -107,7 +107,7 @@ export default function OpenSourcePage() {
|
||||
"@type": "Article",
|
||||
headline: "Open Source Voice Dictation for Linux",
|
||||
description:
|
||||
"Why Vocalinux is 100% open source. AGPL-3.0 licensed, community-driven, no vendor lock-in voice dictation for Linux.",
|
||||
"Why Voculinux is 100% open source. AGPL-3.0 licensed, community-driven, no vendor lock-in voice dictation for Linux.",
|
||||
dateModified: "2026-02-22",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -116,10 +116,10 @@ export default function OpenSourcePage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/open-source"),
|
||||
@@ -141,7 +141,7 @@ export default function OpenSourcePage() {
|
||||
Free & Open Source Voice Dictation
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux is 100% open source under the AGPL-3.0 license, and part of{" "}
|
||||
Voculinux is 100% open source under the AGPL-3.0 license, and part of{" "}
|
||||
<a
|
||||
href="https://vocahq.com"
|
||||
target="_blank"
|
||||
@@ -163,7 +163,7 @@ export default function OpenSourcePage() {
|
||||
</h2>
|
||||
</div>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
Vocalinux is released under the GNU Affero General Public License v3.0, which means:
|
||||
Voculinux is released under the GNU Affero General Public License v3.0, which means:
|
||||
</p>
|
||||
<ul className="grid gap-2 sm:grid-cols-2">
|
||||
{[
|
||||
@@ -211,7 +211,7 @@ export default function OpenSourcePage() {
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<th className="pb-3 pr-4 font-semibold">Feature</th>
|
||||
<th className="pb-3 pr-4 font-semibold">Vocalinux</th>
|
||||
<th className="pb-3 pr-4 font-semibold">Voculinux</th>
|
||||
<th className="pb-3 font-semibold">Proprietary Alternatives</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -219,7 +219,7 @@ export default function OpenSourcePage() {
|
||||
{vsProprietary.map((row) => (
|
||||
<tr key={row.feature} className="border-b border-border">
|
||||
<td className="py-3 pr-4 font-medium">{row.feature}</td>
|
||||
<td className="py-3 pr-4 text-primary">{row.vocalinux}</td>
|
||||
<td className="py-3 pr-4 text-primary">{row.voculinux}</td>
|
||||
<td className="py-3 text-muted-foreground">{row.proprietary}</td>
|
||||
</tr>
|
||||
))}
|
||||
@@ -231,7 +231,7 @@ export default function OpenSourcePage() {
|
||||
<section className="mb-12">
|
||||
<h2 className="mb-6 font-display text-2xl font-semibold">Built on Open Source</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Vocalinux stands on the shoulders of these excellent open source projects:
|
||||
Voculinux stands on the shoulders of these excellent open source projects:
|
||||
</p>
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
{techStack.map((tech) => (
|
||||
@@ -257,7 +257,7 @@ export default function OpenSourcePage() {
|
||||
<div>
|
||||
<h2 className="mb-3 text-xl font-semibold">Privacy by Design</h2>
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
Because Vocalinux is open source, you can verify what local engines do on your
|
||||
Because Voculinux is open source, you can verify what local engines do on your
|
||||
machine. The installed app has no usage telemetry. Remote API is optional and only
|
||||
talks to a server you configure.
|
||||
</p>
|
||||
@@ -282,7 +282,7 @@ export default function OpenSourcePage() {
|
||||
<GitBranch className="mt-1 h-6 w-6 flex-shrink-0 text-primary" />
|
||||
<div>
|
||||
<h3 className="mb-2 font-semibold text-foreground">
|
||||
Contribute to Vocalinux
|
||||
Contribute to Voculinux
|
||||
</h3>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
We welcome contributions! Whether it's bug fixes, features, documentation, or
|
||||
@@ -304,7 +304,7 @@ export default function OpenSourcePage() {
|
||||
<section className="rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Join the Open Source Revolution</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux and experience voice dictation that respects your freedom and privacy.
|
||||
Install Voculinux and experience voice dictation that respects your freedom and privacy.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<Link
|
||||
|
||||
@@ -165,8 +165,9 @@ const homeJsonLd = [
|
||||
const engines = [
|
||||
{
|
||||
name: "whisper.cpp",
|
||||
badge: "Default",
|
||||
summary: "C++ Whisper with Vulkan. Fast install, multi-vendor GPU.",
|
||||
badge: "Guaranteed default",
|
||||
summary:
|
||||
"The guaranteed engine: packaged, checksum-pinned, and performance-budgeted. Fast install, multi-vendor GPU.",
|
||||
points: [
|
||||
"About 1-2 min default setup",
|
||||
"AMD / Intel / NVIDIA via Vulkan",
|
||||
@@ -175,7 +176,9 @@ const engines = [
|
||||
},
|
||||
{
|
||||
name: "Whisper",
|
||||
summary: "Original OpenAI PyTorch path for NVIDIA CUDA workflows.",
|
||||
badge: "Best-effort extra",
|
||||
summary:
|
||||
"Original OpenAI PyTorch path for NVIDIA CUDA workflows. Installable extra, outside the performance budgets.",
|
||||
points: [
|
||||
"Same model family accuracy",
|
||||
"CUDA when you already live in PyTorch",
|
||||
@@ -184,7 +187,9 @@ const engines = [
|
||||
},
|
||||
{
|
||||
name: "VOSK",
|
||||
summary: "Small footprint for older machines and tight RAM budgets.",
|
||||
badge: "Best-effort extra",
|
||||
summary:
|
||||
"Small footprint for older machines and tight RAM budgets. Installable extra, outside the performance budgets.",
|
||||
points: [
|
||||
"CPU-friendly streaming",
|
||||
"Models around ~40MB",
|
||||
@@ -193,7 +198,9 @@ const engines = [
|
||||
},
|
||||
{
|
||||
name: "Remote API",
|
||||
summary: "Offload to a server you trust while keeping desktop injection local.",
|
||||
badge: "User-configured",
|
||||
summary:
|
||||
"Offload to a server you trust while keeping desktop injection local. Audio leaves the machine — stated plainly.",
|
||||
points: [
|
||||
"OpenAI-compatible endpoints",
|
||||
"whisper.cpp server support",
|
||||
@@ -745,6 +752,18 @@ export default function HomePage() {
|
||||
/>
|
||||
<p className="section-lede">Then launch <code>voculinux</code>.</p>
|
||||
<div className="install-alts">
|
||||
<a
|
||||
className="install-alt"
|
||||
href={`${GITHUB_REPO_URL}/releases`}
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<p className="install-alt-kicker">Void Linux</p>
|
||||
<h3>xbps repository</h3>
|
||||
<p>
|
||||
Signed xbps repository data is attached to every release.
|
||||
Install and update with the normal Void package tools.
|
||||
</p>
|
||||
</a>
|
||||
<a
|
||||
className="install-alt"
|
||||
href={`${GITHUB_REPO_URL}/releases`}
|
||||
@@ -777,7 +796,7 @@ export default function HomePage() {
|
||||
<p className="install-alt-kicker">Auto-updates</p>
|
||||
<h3>Flatpak</h3>
|
||||
<p>
|
||||
Install once from the VocaHQ remote and{" "}
|
||||
Install once from the Flatpak remote and{" "}
|
||||
<code>flatpak update</code> carries each stable release. Or
|
||||
sideload the .flatpak bundle.
|
||||
</p>
|
||||
@@ -952,14 +971,13 @@ export default function HomePage() {
|
||||
<div className="shell">
|
||||
<div className="section-head">
|
||||
<h2 className="section-title" id="family-title">
|
||||
Same promise, other machines.
|
||||
A hard fork for Void Linux.
|
||||
</h2>
|
||||
<p className="section-lede">
|
||||
Voculinux is part of{" "}
|
||||
<a href="https://vocahq.com" rel="noopener noreferrer">
|
||||
VocaHQ
|
||||
</a>
|
||||
. This site is about the Linux app.
|
||||
Voculinux is a hard fork of Vocalinux for Void Linux (glibc,
|
||||
Wayland-primary under niri). The internal Python module keeps
|
||||
the upstream name so fixes stay cheap to port by hand; upstream
|
||||
links below are retained as provenance.
|
||||
</p>
|
||||
</div>
|
||||
<div className="family-grid">
|
||||
@@ -982,91 +1000,52 @@ export default function HomePage() {
|
||||
Linux.
|
||||
</p>
|
||||
</div>
|
||||
<a className="family-card" href="https://vocamac.com">
|
||||
<div className="family-card-top">
|
||||
<span className="family-platform">
|
||||
<img
|
||||
src="/brand/platforms/apple.svg"
|
||||
alt=""
|
||||
width={22}
|
||||
height={22}
|
||||
/>
|
||||
macOS
|
||||
</span>
|
||||
<span className="chip">Available now</span>
|
||||
</div>
|
||||
<h3>VocaMac</h3>
|
||||
<p>
|
||||
Native macOS menu bar app. Offline voice-to-text with WhisperKit
|
||||
and CoreML.
|
||||
</p>
|
||||
</a>
|
||||
<a className="family-card" href="https://vocawin.com">
|
||||
<div className="family-card-top">
|
||||
<span className="family-platform">
|
||||
<img
|
||||
src="/brand/platforms/windows.svg"
|
||||
alt=""
|
||||
width={22}
|
||||
height={22}
|
||||
/>
|
||||
Windows
|
||||
</span>
|
||||
<span className="chip">Beta</span>
|
||||
</div>
|
||||
<h3>VocaWin</h3>
|
||||
<p>
|
||||
Unsigned Windows speech-to-text, v0.1.1-beta. SmartScreen may
|
||||
warn about an unknown publisher.
|
||||
</p>
|
||||
</a>
|
||||
<a className="family-card" href="https://vocaphone.vocahq.com">
|
||||
<div className="family-card-top">
|
||||
<span className="family-platform">
|
||||
<span className="family-platform-pair">
|
||||
<img
|
||||
src="/brand/platforms/apple.svg"
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
<img
|
||||
src="/brand/platforms/android.svg"
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
</span>
|
||||
iPhone + Android
|
||||
</span>
|
||||
<span className="chip">Android on Google Play / iOS TestFlight</span>
|
||||
</div>
|
||||
<h3>VocaPhone</h3>
|
||||
<p>
|
||||
Android on Google Play and iOS TestFlight. On-device first,
|
||||
gateway optional.
|
||||
</p>
|
||||
</a>
|
||||
<a
|
||||
className="family-card"
|
||||
href="https://vocagateway.vocahq.com/"
|
||||
href={GITHUB_REPO_URL}
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="family-card-top">
|
||||
<span className="family-platform">
|
||||
<img
|
||||
src="/brand/platforms/server.svg"
|
||||
src="/brand/platforms/linux.svg"
|
||||
alt=""
|
||||
width={22}
|
||||
height={22}
|
||||
/>
|
||||
Infrastructure
|
||||
Upstream
|
||||
</span>
|
||||
<span className="chip">Beta</span>
|
||||
<span className="chip">Provenance</span>
|
||||
</div>
|
||||
<h3>VocaGateway</h3>
|
||||
<h3>Vocalinux (upstream)</h3>
|
||||
<p>
|
||||
Optional self-hosted speech-to-text on hardware you run. Not
|
||||
on-device.
|
||||
The upstream Linux dictation app this fork is ported from.
|
||||
Fixes are taken by hand, one at a time.
|
||||
</p>
|
||||
</a>
|
||||
<a
|
||||
className="family-card"
|
||||
href="https://bongbetic.com"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="family-card-top">
|
||||
<span className="family-platform">
|
||||
{/* Hosted brand asset: never vendored into the repository. */}
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="https://bongbetic.com/branding/bongbetic-logo.png"
|
||||
alt=""
|
||||
width={22}
|
||||
height={22}
|
||||
/>
|
||||
Publisher
|
||||
</span>
|
||||
<span className="chip">Attribution</span>
|
||||
</div>
|
||||
<h3>Bongbetic</h3>
|
||||
<p>
|
||||
Attribution chrome only. Brand binaries stay hosted; the
|
||||
repository gains no brand files.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -71,12 +71,12 @@ const packages = [
|
||||
note: "Use --engine=parakeet",
|
||||
},
|
||||
{
|
||||
name: "AUR (vocalinux)",
|
||||
name: "AUR (voculinux)",
|
||||
parakeet: true,
|
||||
note: "Listed as an optional dependency: python-sherpa-onnx",
|
||||
},
|
||||
{
|
||||
name: "AppImage (and AUR vocalinux-bin)",
|
||||
name: "AppImage (and AUR voculinux-bin)",
|
||||
parakeet: false,
|
||||
note: "Ships whisper.cpp only",
|
||||
},
|
||||
@@ -146,7 +146,7 @@ const faqs = [
|
||||
{
|
||||
question: "Why is the Language picker greyed out or ignored with Parakeet?",
|
||||
answer:
|
||||
"Parakeet's language coverage comes from the model, not from the Vocalinux language catalog. Vocalinux treats the language as auto for Parakeet, so pick v2-english for English only or v3-european for the European set. Follow keyboard layout is not available for Parakeet.",
|
||||
"Parakeet's language coverage comes from the model, not from the Voculinux language catalog. Voculinux treats the language as auto for Parakeet, so pick v2-english for English only or v3-european for the European set. Follow keyboard layout is not available for Parakeet.",
|
||||
},
|
||||
{
|
||||
question: "Can I use Parakeet from the AppImage, Flatpak or Snap?",
|
||||
@@ -156,14 +156,14 @@ const faqs = [
|
||||
{
|
||||
question: "What is Orukeet?",
|
||||
answer:
|
||||
"Orukeet v0.1.0 is an optional model for the Parakeet engine, added in v0.18.0. It runs on the same local sherpa-onnx recognizer, covers 25 European languages, takes about 641 MiB, and its weights are licensed CC BY-SA 4.0. Vocalinux downloads it from a pinned Hugging Face revision and checks every file against bundled SHA-256 pins.",
|
||||
"Orukeet v0.1.0 is an optional model for the Parakeet engine, added in v0.18.0. It runs on the same local sherpa-onnx recognizer, covers 25 European languages, takes about 641 MiB, and its weights are licensed CC BY-SA 4.0. Voculinux downloads it from a pinned Hugging Face revision and checks every file against bundled SHA-256 pins.",
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Parakeet Speech Recognition on Linux | Vocalinux",
|
||||
title: "Parakeet Speech Recognition on Linux | Voculinux",
|
||||
description:
|
||||
"Run NVIDIA Parakeet TDT speech recognition offline on Linux with Vocalinux: install, pick v3-european, v2-english or Orukeet, languages, packages and fixes.",
|
||||
"Run NVIDIA Parakeet TDT speech recognition offline on Linux with Voculinux: install, pick v3-european, v2-english or Orukeet, languages, packages and fixes.",
|
||||
path: "/parakeet",
|
||||
keywords: [
|
||||
"Parakeet speech recognition Linux",
|
||||
@@ -183,7 +183,7 @@ export default function ParakeetPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Parakeet speech recognition on Linux",
|
||||
description:
|
||||
"How to install and use the Parakeet speech engine in Vocalinux on Linux, including model variants, languages, package availability and troubleshooting.",
|
||||
"How to install and use the Parakeet speech engine in Voculinux on Linux, including model variants, languages, package availability and troubleshooting.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -192,10 +192,10 @@ export default function ParakeetPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/parakeet"),
|
||||
@@ -203,7 +203,7 @@ export default function ParakeetPage() {
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Set up the Parakeet engine in Vocalinux",
|
||||
name: "Set up the Parakeet engine in Voculinux",
|
||||
step: setupSteps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -238,12 +238,12 @@ export default function ParakeetPage() {
|
||||
Parakeet speech recognition on Linux
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Parakeet is an optional local speech engine in Vocalinux. It runs
|
||||
Parakeet is an optional local speech engine in Voculinux. It runs
|
||||
NVIDIA's Parakeet TDT 0.6B models on your CPU through sherpa-onnx
|
||||
and types what you say into the focused app, with no cloud
|
||||
transcription. It suits people who dictate in English or a European
|
||||
language and want a CPU engine with a short list of models to choose
|
||||
from.
|
||||
from. Parakeet is a best-effort extra: installable and selectable, outside the performance budgets.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -285,9 +285,9 @@ export default function ParakeetPage() {
|
||||
<div className="max-w-4xl space-y-4 text-muted-foreground">
|
||||
<p>
|
||||
Parakeet is a family of automatic speech recognition models from
|
||||
NVIDIA's NeMo toolkit. Vocalinux uses the TDT 0.6B models,
|
||||
NVIDIA's NeMo toolkit. Voculinux uses the TDT 0.6B models,
|
||||
which are transducer models: they turn audio straight into text
|
||||
tokens rather than generating text the way Whisper does. Vocalinux
|
||||
tokens rather than generating text the way Whisper does. Voculinux
|
||||
loads int8 ONNX exports of these models with{" "}
|
||||
<a
|
||||
href="https://github.com/k2-fsa/sherpa-onnx"
|
||||
@@ -299,7 +299,7 @@ export default function ParakeetPage() {
|
||||
, a speech runtime that runs on an ordinary CPU.
|
||||
</p>
|
||||
<p>
|
||||
Parakeet arrived in Vocalinux v0.17.0 alongside Faster Whisper.
|
||||
Parakeet arrived in Voculinux v0.17.0 alongside Faster Whisper.
|
||||
whisper.cpp is still the default engine; Parakeet is something you
|
||||
opt into.
|
||||
</p>
|
||||
@@ -339,11 +339,11 @@ export default function ParakeetPage() {
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
To start once with Parakeet from a terminal, run{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
vocalinux --engine parakeet
|
||||
voculinux --engine parakeet
|
||||
</code>
|
||||
. In{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
~/.config/vocalinux/config.json
|
||||
~/.config/voculinux/config.json
|
||||
</code>{" "}
|
||||
the engine name is{" "}
|
||||
<code className="rounded bg-muted px-1">parakeet</code>.
|
||||
@@ -356,7 +356,7 @@ export default function ParakeetPage() {
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
The Model size picker lists three models for the Parakeet engine.
|
||||
Sizes are the catalog values Vocalinux shows before a download.
|
||||
Sizes are the catalog values Voculinux shows before a download.
|
||||
</p>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left text-sm">
|
||||
@@ -393,7 +393,7 @@ export default function ParakeetPage() {
|
||||
Orukeet v0.1.0 was added in v0.18.0. It uses the same local
|
||||
sherpa-onnx recognizer and covers 25 European languages; the
|
||||
recommended Parakeet model and the default whisper.cpp engine are
|
||||
unchanged. Vocalinux downloads it from a pinned revision of{" "}
|
||||
unchanged. Voculinux downloads it from a pinned revision of{" "}
|
||||
<a
|
||||
href="https://huggingface.co/oruk/orukeet"
|
||||
className="text-primary underline"
|
||||
@@ -413,7 +413,7 @@ export default function ParakeetPage() {
|
||||
<div className="max-w-4xl space-y-4 text-muted-foreground">
|
||||
<p>
|
||||
With Parakeet, the model decides the language, not the Language
|
||||
picker. Vocalinux treats the language as auto for this engine, so a
|
||||
picker. Voculinux treats the language as auto for this engine, so a
|
||||
language you chose for whisper.cpp is not passed to Parakeet. Choose
|
||||
v2-english if you only speak English, or v3-european (or Orukeet)
|
||||
for the 25-language European set.
|
||||
@@ -449,7 +449,7 @@ export default function ParakeetPage() {
|
||||
Hardware and packages
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Parakeet runs on the CPU. Vocalinux's Vulkan and CUDA
|
||||
Parakeet runs on the CPU. Voculinux's Vulkan and CUDA
|
||||
acceleration applies to whisper.cpp, so a GPU does not speed up
|
||||
Parakeet (see{" "}
|
||||
<Link href="/gpu-acceleration/" className="text-primary underline">
|
||||
@@ -457,7 +457,7 @@ export default function ParakeetPage() {
|
||||
</Link>
|
||||
). Plan for roughly 640 MB of disk per Parakeet model, stored under{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
~/.local/share/vocalinux/models/
|
||||
~/.local/share/voculinux/models/
|
||||
</code>
|
||||
.
|
||||
</p>
|
||||
@@ -574,7 +574,7 @@ export default function ParakeetPage() {
|
||||
The model will not load after an interrupted download
|
||||
</h3>
|
||||
<p>
|
||||
Vocalinux refuses to load Parakeet files that fail checksum
|
||||
Voculinux refuses to load Parakeet files that fail checksum
|
||||
verification. In Settings → Speech Model, delete the leftover
|
||||
model from <strong>Unused downloads</strong> and download it
|
||||
again.
|
||||
@@ -596,10 +596,10 @@ export default function ParakeetPage() {
|
||||
</h3>
|
||||
<p>
|
||||
Run{" "}
|
||||
<code className="rounded bg-muted px-1">vocalinux --debug</code>{" "}
|
||||
<code className="rounded bg-muted px-1">voculinux --debug</code>{" "}
|
||||
and check{" "}
|
||||
<code className="rounded bg-muted px-1">
|
||||
~/.local/share/vocalinux/vocalinux.log
|
||||
~/.local/share/voculinux/voculinux.log
|
||||
</code>
|
||||
, then see the{" "}
|
||||
<Link href="/troubleshooting/" className="text-primary underline">
|
||||
@@ -633,7 +633,7 @@ export default function ParakeetPage() {
|
||||
Try Parakeet on your machine
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux with the Parakeet engine, or start with whisper.cpp
|
||||
Install Voculinux with the Parakeet engine, or start with whisper.cpp
|
||||
and compare. Also see{" "}
|
||||
<Link href="/faster-whisper/" className="text-primary underline">
|
||||
Faster Whisper on Linux
|
||||
@@ -645,7 +645,7 @@ export default function ParakeetPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -15,7 +15,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const PAGE_PATH = "/pipewire";
|
||||
const PAGE_TITLE = "PipeWire Audio Capture for Linux Voice Dictation";
|
||||
const PAGE_DESCRIPTION =
|
||||
"How Vocalinux records from microphones and PipeWire system-audio sources, how it differs from PortAudio, and how to fix wrong-mic, silence and Bluetooth issues.";
|
||||
"How Voculinux records from microphones and PipeWire system-audio sources, how it differs from PortAudio, and how to fix wrong-mic, silence and Bluetooth issues.";
|
||||
|
||||
const captureRows = [
|
||||
{
|
||||
@@ -37,7 +37,7 @@ const captureRows = [
|
||||
const steps = [
|
||||
{
|
||||
name: "Open the Audio page",
|
||||
text: "Open Vocalinux Settings, go to Audio and find Input Device. Use the refresh button next to the list after plugging in a headset.",
|
||||
text: "Open Voculinux Settings, go to Audio and find Input Device. Use the refresh button next to the list after plugging in a headset.",
|
||||
},
|
||||
{
|
||||
name: "Pick a source",
|
||||
@@ -55,7 +55,7 @@ const steps = [
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
question: "Does Vocalinux record microphones through PipeWire?",
|
||||
question: "Does Voculinux record microphones through PipeWire?",
|
||||
answer:
|
||||
"Microphones are listed and opened through PortAudio, including System Default. The native PipeWire path, pw-dump plus pw-record, is used for the System audio entries, because PortAudio cannot reach a sink monitor.",
|
||||
},
|
||||
@@ -67,7 +67,7 @@ const faqs = [
|
||||
{
|
||||
question: "Why are there no System audio entries in my device list?",
|
||||
answer:
|
||||
"Vocalinux lists them only when both pw-dump and pw-record are on the PATH and the PipeWire daemon answers. If either tool is missing, the list shows microphones only and nothing else changes.",
|
||||
"Voculinux lists them only when both pw-dump and pw-record are on the PATH and the PipeWire daemon answers. If either tool is missing, the list shows microphones only and nothing else changes.",
|
||||
},
|
||||
{
|
||||
question: "Does system-audio capture send anything online?",
|
||||
@@ -77,12 +77,12 @@ const faqs = [
|
||||
{
|
||||
question: "Which version added PipeWire capture?",
|
||||
answer:
|
||||
"PipeWire system-audio capture was added in v0.18.0. Check your version with vocalinux --version.",
|
||||
"PipeWire system-audio capture was added in v0.18.0. Check your version with voculinux --version.",
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: `${PAGE_TITLE} | Vocalinux`,
|
||||
title: `${PAGE_TITLE} | Voculinux`,
|
||||
description: PAGE_DESCRIPTION,
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
@@ -91,7 +91,7 @@ export const metadata: Metadata = buildPageMetadata({
|
||||
"linux dictation system audio",
|
||||
"pw-record transcription",
|
||||
"portaudio vs pipewire",
|
||||
"vocalinux microphone not working",
|
||||
"voculinux microphone not working",
|
||||
"bluetooth headset dictation linux",
|
||||
],
|
||||
});
|
||||
@@ -120,17 +120,17 @@ export default function PipeWirePage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
},
|
||||
{
|
||||
"@type": "HowTo",
|
||||
name: "Choose an audio source for Vocalinux dictation",
|
||||
name: "Choose an audio source for Voculinux dictation",
|
||||
step: steps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -159,10 +159,10 @@ export default function PipeWirePage() {
|
||||
<section>
|
||||
<p className="subpage-kicker">Added in v0.18.0</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
PipeWire audio capture in Vocalinux
|
||||
PipeWire audio capture in Voculinux
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux records from two kinds of source: microphones, opened
|
||||
Voculinux records from two kinds of source: microphones, opened
|
||||
through PortAudio, and system-audio sources that come straight from
|
||||
PipeWire. This page explains what each one is for, how to pick the
|
||||
right source, and what to check when dictation hears the wrong device
|
||||
@@ -178,10 +178,10 @@ export default function PipeWirePage() {
|
||||
PortAudio enumerates ALSA and PulseAudio devices, not PipeWire nodes.
|
||||
That works well for microphones, but it cannot see a sink's
|
||||
monitor, the stream of everything playing through an output. Since
|
||||
v0.18.0 Vocalinux asks PipeWire directly: it lists sinks with{" "}
|
||||
v0.18.0 Voculinux asks PipeWire directly: it lists sinks with{" "}
|
||||
<InlineCode>pw-dump</InlineCode> and records the chosen one with{" "}
|
||||
<InlineCode>pw-record --raw</InlineCode>. PipeWire converts the audio
|
||||
to the format Vocalinux asks for inside its own graph, so no format
|
||||
to the format Voculinux asks for inside its own graph, so no format
|
||||
negotiation is needed.
|
||||
</p>
|
||||
<div className="overflow-x-auto">
|
||||
@@ -263,7 +263,7 @@ export default function PipeWirePage() {
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Leaves valid default and virtual inputs under the sound
|
||||
server's control, so the mic you pick in desktop sound
|
||||
settings is the one Vocalinux hears.
|
||||
settings is the one Voculinux hears.
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-[12px] border border-border bg-background p-5">
|
||||
@@ -273,7 +273,7 @@ export default function PipeWirePage() {
|
||||
/>
|
||||
<h3 className="mb-2 font-semibold">A named microphone</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
A valid explicit choice always wins over System Default. Vocalinux
|
||||
A valid explicit choice always wins over System Default. Voculinux
|
||||
saves the device name and matches it again by name when indexes
|
||||
shift after a replug.
|
||||
</p>
|
||||
@@ -297,7 +297,7 @@ export default function PipeWirePage() {
|
||||
<h3 className="mb-2 font-semibold">Where the choice is stored</h3>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
The selection lives in{" "}
|
||||
<InlineCode>~/.config/vocalinux/config.json</InlineCode> under{" "}
|
||||
<InlineCode>~/.config/voculinux/config.json</InlineCode> under{" "}
|
||||
<InlineCode>audio.device_index</InlineCode> and{" "}
|
||||
<InlineCode>audio.device_name</InlineCode>. A{" "}
|
||||
<InlineCode>null</InlineCode> index means System Default.
|
||||
@@ -310,7 +310,7 @@ export default function PipeWirePage() {
|
||||
simply not listed.
|
||||
</li>
|
||||
<li>
|
||||
If a saved System audio sink disappears, Vocalinux refuses to record
|
||||
If a saved System audio sink disappears, Voculinux refuses to record
|
||||
instead of quietly switching to a microphone, because that would
|
||||
capture the wrong audio. Pick a source again.
|
||||
</li>
|
||||
@@ -338,15 +338,15 @@ export default function PipeWirePage() {
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Select the mic by name in Settings → Audio → Input Device rather than
|
||||
relying on System Default. On ALSA-only setups where PortAudio
|
||||
substitutes some other hardware for the default input, Vocalinux
|
||||
substitutes some other hardware for the default input, Voculinux
|
||||
prefers an input-capable <InlineCode>pulse</InlineCode> device so it
|
||||
follows your desktop's choice, and logs a warning when none
|
||||
exists. Run with debug logging to see which device was opened:
|
||||
</p>
|
||||
<div className="mb-6">
|
||||
<TerminalBlock
|
||||
command="vocalinux --debug"
|
||||
displayCommand="vocalinux --debug"
|
||||
command="voculinux --debug"
|
||||
displayCommand="voculinux --debug"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="mb-2 font-semibold">
|
||||
@@ -361,9 +361,9 @@ export default function PipeWirePage() {
|
||||
</div>
|
||||
<p className="mb-6 text-sm text-muted-foreground">
|
||||
A Microphone Stalled notification means the selected input stopped
|
||||
delivering audio and Vocalinux stopped that attempt. Use Microphone
|
||||
delivering audio and Voculinux stopped that attempt. Use Microphone
|
||||
Test, or choose another Input Device. If a stale device index is the
|
||||
problem, quit Vocalinux and set{" "}
|
||||
problem, quit Voculinux and set{" "}
|
||||
<InlineCode>audio.device_index</InlineCode> to{" "}
|
||||
<InlineCode>null</InlineCode> in <InlineCode>config.json</InlineCode>.
|
||||
With a System audio source, remember that a silent output produces
|
||||
@@ -372,7 +372,7 @@ export default function PipeWirePage() {
|
||||
<h3 className="mb-2 font-semibold">Bluetooth headsets</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Bluetooth headset microphones use a separate capture profile that is
|
||||
sensitive to repeated opening. Vocalinux opens the stream once per
|
||||
sensitive to repeated opening. Voculinux opens the stream once per
|
||||
session and pauses briefly between failed attempts on Bluetooth
|
||||
devices. If capture still fails, try a wired microphone to check
|
||||
whether the Bluetooth capture path is the cause.
|
||||
@@ -421,7 +421,7 @@ export default function PipeWirePage() {
|
||||
Pick a source and dictate
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux, choose your microphone or a system-audio source in
|
||||
Install Voculinux, choose your microphone or a system-audio source in
|
||||
Settings → Audio, and run the Microphone Test before your first
|
||||
dictation.
|
||||
</p>
|
||||
@@ -430,7 +430,7 @@ export default function PipeWirePage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -10,7 +10,7 @@ export const metadata: Metadata = buildPageMetadata({
|
||||
"Local engines keep audio on your computer. Remote API is optional and only talks to a server you configure.",
|
||||
path: "/privacy",
|
||||
keywords: [
|
||||
"vocalinux privacy",
|
||||
"voculinux privacy",
|
||||
"offline voice dictation privacy",
|
||||
"speech to text data privacy",
|
||||
"linux dictation security",
|
||||
@@ -21,9 +21,9 @@ export default function PrivacyPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux Privacy Policy",
|
||||
headline: "Voculinux Privacy Policy",
|
||||
description:
|
||||
"How Vocalinux handles voice data: local engines on your machine, optional Remote API to a server you configure.",
|
||||
"How Voculinux handles voice data: local engines on your machine, optional Remote API to a server you configure.",
|
||||
dateModified: "2026-09-23",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -32,10 +32,10 @@ export default function PrivacyPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/privacy"),
|
||||
@@ -54,10 +54,10 @@ export default function PrivacyPage() {
|
||||
Privacy First
|
||||
</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
How Vocalinux handles your voice
|
||||
How Voculinux handles your voice
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux is built for privacy. Local engines process speech on your machine. Remote API
|
||||
Voculinux is built for privacy. Local engines process speech on your machine. Remote API
|
||||
is optional and only talks to a server you set.
|
||||
</p>
|
||||
</section>
|
||||
@@ -108,7 +108,7 @@ export default function PrivacyPage() {
|
||||
<div className="space-y-4 text-muted-foreground">
|
||||
<p>
|
||||
<strong className="text-foreground">
|
||||
The installed Vocalinux app does not send usage telemetry.
|
||||
The installed Voculinux app does not send usage telemetry.
|
||||
</strong>{" "}
|
||||
It does not phone home. The installed app does not do the following
|
||||
for us:
|
||||
@@ -149,17 +149,17 @@ export default function PrivacyPage() {
|
||||
<article className="rounded-[12px] border border-border bg-background p-6">
|
||||
<h2 className="mb-4 flex items-center gap-2 font-display text-2xl font-semibold">
|
||||
<Eye className="h-5 w-5 text-primary" />
|
||||
This website (vocalinux.com)
|
||||
This website (voculinux.com)
|
||||
</h2>
|
||||
<div className="space-y-4 text-muted-foreground">
|
||||
<p>
|
||||
vocalinux.com loads Google Analytics via the googletagmanager gtag
|
||||
voculinux.com loads Google Analytics via the googletagmanager gtag
|
||||
script for measurement ID{" "}
|
||||
<code className="rounded bg-muted px-1.5 py-0.5">G-7NBBNJNNQ7</code>{" "}
|
||||
and runs gtag config with no IP anonymization and no cookie flags.
|
||||
That sends page views and a Google Analytics client identifier (a
|
||||
cookie) to Google. Google processes IP addresses and device and
|
||||
browser data. The installed Vocalinux app does not send usage
|
||||
browser data. The installed Voculinux app does not send usage
|
||||
telemetry.
|
||||
</p>
|
||||
</div>
|
||||
@@ -204,7 +204,7 @@ export default function PrivacyPage() {
|
||||
</h2>
|
||||
<div className="space-y-4 text-muted-foreground">
|
||||
<p>
|
||||
Vocalinux stores configuration locally at <code className="rounded bg-muted px-1.5 py-0.5">~/.config/vocalinux/config.json</code>:
|
||||
Voculinux stores configuration locally at <code className="rounded bg-muted px-1.5 py-0.5">~/.config/voculinux/config.json</code>:
|
||||
</p>
|
||||
<ul className="space-y-2">
|
||||
<li className="flex items-start gap-2">
|
||||
@@ -230,13 +230,13 @@ export default function PrivacyPage() {
|
||||
|
||||
{/* Comparison with Cloud Services */}
|
||||
<section className="mt-12 rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-6 font-display text-2xl font-semibold">Vocalinux vs Cloud Dictation Services</h2>
|
||||
<h2 className="mb-6 font-display text-2xl font-semibold">Voculinux vs Cloud Dictation Services</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left">
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<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">Voculinux</th>
|
||||
<th className="pb-3 text-sm font-semibold">Cloud Services</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -25,16 +25,16 @@ const protocolOptions = [
|
||||
name: "whisper.cpp server",
|
||||
endpoint: "/inference",
|
||||
description:
|
||||
"Point Vocalinux at the HTTP server bundled with whisper.cpp when you want a small LAN transcription appliance.",
|
||||
"Point Voculinux at the HTTP server bundled with whisper.cpp when you want a small LAN transcription appliance.",
|
||||
},
|
||||
];
|
||||
|
||||
const workflowSteps = [
|
||||
"Vocalinux records microphone audio locally as 16 kHz mono PCM.",
|
||||
"Voculinux records microphone audio locally as 16 kHz mono PCM.",
|
||||
"Voice activity detection decides when an utterance is ready.",
|
||||
"The utterance is packaged as an in-memory WAV upload.",
|
||||
"The configured server returns JSON with a text field.",
|
||||
"Vocalinux injects the transcription into the focused Linux app.",
|
||||
"Voculinux injects the transcription into the focused Linux app.",
|
||||
];
|
||||
|
||||
const setupSteps = [
|
||||
@@ -51,7 +51,7 @@ const setupSteps = [
|
||||
{
|
||||
title: "Choose the endpoint format",
|
||||
description:
|
||||
"Select OpenAI-compatible or whisper.cpp so Vocalinux sends the multipart fields your server expects.",
|
||||
"Select OpenAI-compatible or whisper.cpp so Voculinux sends the multipart fields your server expects.",
|
||||
},
|
||||
{
|
||||
title: "Test, then dictate",
|
||||
@@ -63,12 +63,12 @@ const setupSteps = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Remote API Speech Recognition for Linux Dictation",
|
||||
description:
|
||||
"Configure Vocalinux Remote API speech recognition with OpenAI-compatible Whisper servers or whisper.cpp server endpoints for Linux voice dictation.",
|
||||
"Configure Voculinux Remote API speech recognition with OpenAI-compatible Whisper servers or whisper.cpp server endpoints for Linux voice dictation.",
|
||||
path: "/remote-api",
|
||||
keywords: [
|
||||
"remote api speech recognition linux",
|
||||
"openai compatible whisper linux dictation",
|
||||
"whisper.cpp server vocalinux",
|
||||
"whisper.cpp server voculinux",
|
||||
"self hosted transcription linux",
|
||||
],
|
||||
});
|
||||
@@ -79,7 +79,7 @@ export default function RemoteApiPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Remote API Speech Recognition for Linux Dictation",
|
||||
description:
|
||||
"How Vocalinux connects Linux voice dictation to OpenAI-compatible and whisper.cpp remote transcription servers.",
|
||||
"How Voculinux connects Linux voice dictation to OpenAI-compatible and whisper.cpp remote transcription servers.",
|
||||
dateModified: "2026-06-11",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -88,10 +88,10 @@ export default function RemoteApiPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/remote-api"),
|
||||
@@ -113,9 +113,11 @@ export default function RemoteApiPage() {
|
||||
Remote API Speech Recognition for Linux
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux can offload the heavy transcription step to a trusted HTTP
|
||||
Voculinux can offload the heavy transcription step to a trusted HTTP
|
||||
server while keeping desktop capture, voice activity detection,
|
||||
shortcut handling, and text injection on your Linux machine.
|
||||
shortcut handling, and text injection on your Linux machine. Remote
|
||||
API is a user-configured, best-effort engine: audio leaves the
|
||||
machine for the server you configure.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -137,7 +139,7 @@ export default function RemoteApiPage() {
|
||||
icon: Settings,
|
||||
title: "Same desktop workflow",
|
||||
description:
|
||||
"Remote API behaves like a Vocalinux engine, so toggle mode, push-to-talk, VAD, and text injection still work normally.",
|
||||
"Remote API behaves like a Voculinux engine, so toggle mode, push-to-talk, VAD, and text injection still work normally.",
|
||||
},
|
||||
].map((item) => {
|
||||
const Icon = item.icon;
|
||||
|
||||
@@ -89,7 +89,7 @@ const statistics = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Voice Dictation for RSI & Carpal Tunnel Prevention | Vocalinux",
|
||||
title: "Voice Dictation for RSI & Carpal Tunnel Prevention | Voculinux",
|
||||
description:
|
||||
"Prevent and manage RSI, carpal tunnel, and repetitive strain injuries with voice dictation. Hands-free typing for Linux users with local engines or an optional Remote API.",
|
||||
path: "/rsi-prevention",
|
||||
@@ -120,10 +120,10 @@ export default function RsiPreventionPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/rsi-prevention"),
|
||||
@@ -231,7 +231,7 @@ export default function RsiPreventionPage() {
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-3 font-semibold">Vocalinux Advantages</h3>
|
||||
<h3 className="mb-3 font-semibold">Voculinux Advantages</h3>
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
<li className="flex items-start gap-2">
|
||||
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
|
||||
@@ -268,7 +268,7 @@ export default function RsiPreventionPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -15,7 +15,7 @@ const productShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/00-transcription.png",
|
||||
srcDark: "/screenshots/dark/00-transcription.png",
|
||||
alt: "Vocalinux dictating into a text editor with the tray menu open",
|
||||
alt: "Voculinux dictating into a text editor with the tray menu open",
|
||||
title: "Dictation in action",
|
||||
description:
|
||||
"Voice typing into a focused app while the tray menu shows listening state.",
|
||||
@@ -25,7 +25,7 @@ const productShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/02-system-tray.png",
|
||||
srcDark: "/screenshots/dark/02-system-tray.png",
|
||||
alt: "Vocalinux system tray menu with voice typing controls",
|
||||
alt: "Voculinux system tray menu with voice typing controls",
|
||||
title: "System tray",
|
||||
description: "Tray menu for start/stop, settings, logs, and about.",
|
||||
width: 315,
|
||||
@@ -34,7 +34,7 @@ const productShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/03-log-viewer.png",
|
||||
srcDark: "/screenshots/dark/03-log-viewer.png",
|
||||
alt: "Vocalinux log viewer dialog",
|
||||
alt: "Voculinux log viewer dialog",
|
||||
title: "Log viewer",
|
||||
description: "Inspect runtime logs when diagnosing dictation issues.",
|
||||
...SETTINGS_SIZE,
|
||||
@@ -45,7 +45,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/settings-speech-engine.png",
|
||||
srcDark: "/screenshots/dark/settings-speech-engine.png",
|
||||
alt: "Vocalinux Speech Model settings with sidebar navigation",
|
||||
alt: "Voculinux Speech Model settings with sidebar navigation",
|
||||
title: "Speech Model",
|
||||
description:
|
||||
"Choose whisper.cpp, Whisper, VOSK, or Remote API and pick a model.",
|
||||
@@ -54,7 +54,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/settings-recognition.png",
|
||||
srcDark: "/screenshots/dark/settings-recognition.png",
|
||||
alt: "Vocalinux Dictation settings page",
|
||||
alt: "Voculinux Dictation settings page",
|
||||
title: "Dictation",
|
||||
description: "Shortcuts, listening controls, and dictation output options.",
|
||||
...SETTINGS_SIZE,
|
||||
@@ -62,7 +62,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/settings-audio.png",
|
||||
srcDark: "/screenshots/dark/settings-audio.png",
|
||||
alt: "Vocalinux Audio settings page",
|
||||
alt: "Voculinux Audio settings page",
|
||||
title: "Audio",
|
||||
description: "Input device, feedback sounds, and capture options.",
|
||||
...SETTINGS_SIZE,
|
||||
@@ -70,7 +70,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/settings-performance.png",
|
||||
srcDark: "/screenshots/dark/settings-performance.png",
|
||||
alt: "Vocalinux Performance settings page",
|
||||
alt: "Voculinux Performance settings page",
|
||||
title: "Performance",
|
||||
description: "Auto-pause, model keep-alive, and GPU device selection.",
|
||||
...SETTINGS_SIZE,
|
||||
@@ -78,7 +78,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/settings-general.png",
|
||||
srcDark: "/screenshots/dark/settings-general.png",
|
||||
alt: "Vocalinux Application settings page",
|
||||
alt: "Voculinux Application settings page",
|
||||
title: "Application",
|
||||
description: "Autostart, start minimized, and everyday defaults.",
|
||||
...SETTINGS_SIZE,
|
||||
@@ -86,7 +86,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/settings-advanced.png",
|
||||
srcDark: "/screenshots/dark/settings-advanced.png",
|
||||
alt: "Vocalinux Advanced settings with whisper.cpp decoding controls",
|
||||
alt: "Voculinux Advanced settings with whisper.cpp decoding controls",
|
||||
title: "Advanced",
|
||||
description: "Power-user decoding controls and Remote Server options.",
|
||||
...SETTINGS_SIZE,
|
||||
@@ -94,7 +94,7 @@ const settingsShots: Screenshot[] = [
|
||||
{
|
||||
src: "/screenshots/05-about-view.png",
|
||||
srcDark: "/screenshots/dark/05-about-view.png",
|
||||
alt: "Vocalinux About settings page with update checker",
|
||||
alt: "Voculinux About settings page with update checker",
|
||||
title: "About",
|
||||
description:
|
||||
"Version info plus Stable/Nightly update checks from GitHub Releases.",
|
||||
@@ -105,10 +105,10 @@ const settingsShots: Screenshot[] = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Screenshots: Linux Voice Dictation App UI",
|
||||
description:
|
||||
"See Vocalinux in action: system tray, log viewer, and settings pages for speech model, dictation, audio, performance, application, advanced options, and about/updates. Flip between light and dark app shots.",
|
||||
"See Voculinux in action: system tray, log viewer, and settings pages for speech model, dictation, audio, performance, application, advanced options, and about/updates. Flip between light and dark app shots.",
|
||||
path: "/screenshots",
|
||||
keywords: [
|
||||
"Vocalinux screenshots",
|
||||
"Voculinux screenshots",
|
||||
"Linux voice dictation UI",
|
||||
"offline speech recognition settings",
|
||||
"whisper.cpp Linux screenshots",
|
||||
@@ -120,9 +120,9 @@ export default function ScreenshotsPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "ImageGallery",
|
||||
name: "Vocalinux Screenshots",
|
||||
name: "Voculinux Screenshots",
|
||||
description:
|
||||
"Product and settings screenshots of Vocalinux, offline voice dictation for Linux.",
|
||||
"Product and settings screenshots of Voculinux, offline voice dictation for Linux.",
|
||||
dateModified: "2026-08-03", // refreshed after About moved into Settings sidebar
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -131,10 +131,10 @@ export default function ScreenshotsPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/screenshots"),
|
||||
@@ -153,7 +153,7 @@ export default function ScreenshotsPage() {
|
||||
v0.16 UI
|
||||
</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Vocalinux Screenshots
|
||||
Voculinux Screenshots
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
A look at offline voice dictation on Linux: tray controls, debugging
|
||||
@@ -170,7 +170,7 @@ export default function ScreenshotsPage() {
|
||||
<section className="border-primary/20 bg-primary/5 rounded-[12px] border p-8">
|
||||
<h2 className="mb-3 font-display text-2xl font-semibold">Try it yourself</h2>
|
||||
<p className="mb-6 max-w-2xl text-muted-foreground">
|
||||
Install Vocalinux and open Settings from the system tray to explore
|
||||
Install Voculinux and open Settings from the system tray to explore
|
||||
the same screens on your desktop.
|
||||
</p>
|
||||
<div className="flex flex-col gap-3 sm:flex-row">
|
||||
|
||||
@@ -84,7 +84,7 @@ const shortcutCategories = [
|
||||
icon: Settings,
|
||||
iconColor: "text-primary",
|
||||
shortcuts: [
|
||||
{ keys: ["Config File"], action: "~/.config/vocalinux/config.json", note: "Manual editing" },
|
||||
{ keys: ["Config File"], action: "~/.config/voculinux/config.json", note: "Manual editing" },
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -102,10 +102,10 @@ function Mic(props: { className?: string }) {
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Keyboard Shortcuts and Voice Commands",
|
||||
description:
|
||||
"Learn Vocalinux keyboard shortcut modes and voice commands. Use toggle mode or push-to-talk, then customize activation and command behavior.",
|
||||
"Learn Voculinux keyboard shortcut modes and voice commands. Use toggle mode or push-to-talk, then customize activation and command behavior.",
|
||||
path: "/shortcuts",
|
||||
keywords: [
|
||||
"vocalinux shortcuts",
|
||||
"voculinux shortcuts",
|
||||
"linux voice dictation commands",
|
||||
"speech to text keyboard shortcuts",
|
||||
"voice commands linux",
|
||||
@@ -116,9 +116,9 @@ export default function ShortcutsPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux Keyboard Shortcuts & Voice Commands",
|
||||
headline: "Voculinux Keyboard Shortcuts & Voice Commands",
|
||||
description:
|
||||
"Complete guide to Vocalinux keyboard shortcuts and voice commands for efficient Linux voice dictation.",
|
||||
"Complete guide to Voculinux keyboard shortcuts and voice commands for efficient Linux voice dictation.",
|
||||
dateModified: "2026-03-30",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -127,10 +127,10 @@ export default function ShortcutsPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/shortcuts"),
|
||||
@@ -152,7 +152,7 @@ export default function ShortcutsPage() {
|
||||
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. New installs default to
|
||||
Master Voculinux with keyboard shortcuts and voice commands. New installs default to
|
||||
push-to-talk (hold Right Alt), or switch to toggle mode (double-tap), then apply voice
|
||||
commands for editing and formatting.
|
||||
</p>
|
||||
@@ -233,10 +233,10 @@ export default function ShortcutsPage() {
|
||||
configuration file directly:
|
||||
</p>
|
||||
<div className="rounded-lg bg-[color:var(--terminal)] p-4">
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">~/.config/vocalinux/config.json</code>
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">~/.config/voculinux/config.json</code>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
Open Vocalinux and access Settings from the tray icon to change keyboard shortcuts
|
||||
Open Voculinux and access Settings from the tray icon to change keyboard shortcuts
|
||||
through the GUI.
|
||||
</p>
|
||||
</section>
|
||||
@@ -249,7 +249,7 @@ export default function ShortcutsPage() {
|
||||
>
|
||||
<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.
|
||||
Get answers to common questions about Voculinux features and usage.
|
||||
</p>
|
||||
<span className="mt-4 inline-flex items-center gap-1 text-sm font-semibold text-primary">
|
||||
View FAQ
|
||||
|
||||
@@ -14,12 +14,12 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
|
||||
const PAGE_PATH = "/transcribe-audio-files";
|
||||
|
||||
const cliCommand = "vocalinux --transcribe-file meeting.wav";
|
||||
const cliCommand = "voculinux --transcribe-file meeting.wav";
|
||||
|
||||
const howToSteps = [
|
||||
{
|
||||
name: "Open the tray entry",
|
||||
text: "Click the Vocalinux tray icon and choose Transcribe Audio File…",
|
||||
text: "Click the Voculinux tray icon and choose Transcribe Audio File…",
|
||||
},
|
||||
{
|
||||
name: "Pick a recording",
|
||||
@@ -27,7 +27,7 @@ const howToSteps = [
|
||||
},
|
||||
{
|
||||
name: "Download TinyDiarize once",
|
||||
text: "The first time, Vocalinux asks to download the TinyDiarize model (about 465 MB, one time). Click Download. It is only used for file transcription and never becomes your dictation model.",
|
||||
text: "The first time, Voculinux asks to download the TinyDiarize model (about 465 MB, one time). Click Download. It is only used for file transcription and never becomes your dictation model.",
|
||||
},
|
||||
{
|
||||
name: "Wait for the transcript",
|
||||
@@ -61,15 +61,15 @@ const formatRows = [
|
||||
const faqs = [
|
||||
{
|
||||
q: "Can it label speakers in languages other than English?",
|
||||
a: "No. The TinyDiarize model Vocalinux uses, small.en-tdrz, is English-only. Speaker labels and the transcript itself are for English audio.",
|
||||
a: "No. The TinyDiarize model Voculinux uses, small.en-tdrz, is English-only. Speaker labels and the transcript itself are for English audio.",
|
||||
},
|
||||
{
|
||||
q: "Does Speaker 1 always mean the same person?",
|
||||
a: "No. TinyDiarize marks the points where the speaker changes, and Vocalinux numbers each new turn in order. A person who speaks again later gets a new number, so treat the labels as turn markers and rename them yourself.",
|
||||
a: "No. TinyDiarize marks the points where the speaker changes, and Voculinux numbers each new turn in order. A person who speaks again later gets a new number, so treat the labels as turn markers and rename them yourself.",
|
||||
},
|
||||
{
|
||||
q: "Why does the CLI say the model is not downloaded?",
|
||||
a: "vocalinux --transcribe-file never downloads anything. Run Transcribe Audio File… from the tray once and accept the TinyDiarize download, then the CLI can use the model.",
|
||||
a: "voculinux --transcribe-file never downloads anything. Run Transcribe Audio File… from the tray once and accept the TinyDiarize download, then the CLI can use the model.",
|
||||
},
|
||||
{
|
||||
q: "Is my audio uploaded anywhere?",
|
||||
@@ -82,9 +82,9 @@ const faqs = [
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Transcribe Audio Files on Linux Offline with Speakers | Vocalinux",
|
||||
title: "Transcribe Audio Files on Linux Offline with Speakers | Voculinux",
|
||||
description:
|
||||
"Transcribe an audio file on Linux offline with Vocalinux: tray or --transcribe-file, local TinyDiarize speaker labels (English), formats, output and limits.",
|
||||
"Transcribe an audio file on Linux offline with Voculinux: tray or --transcribe-file, local TinyDiarize speaker labels (English), formats, output and limits.",
|
||||
path: PAGE_PATH,
|
||||
keywords: [
|
||||
"transcribe audio file Linux offline",
|
||||
@@ -102,7 +102,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Transcribe Audio Files on Linux Offline with Speaker Labels",
|
||||
description:
|
||||
"How to transcribe recordings locally with Vocalinux from the tray or the --transcribe-file CLI, and how TinyDiarize speaker labels work.",
|
||||
"How to transcribe recordings locally with Voculinux from the tray or the --transcribe-file CLI, and how TinyDiarize speaker labels work.",
|
||||
dateModified: "2026-11-01",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -111,10 +111,10 @@ export default function TranscribeAudioFilesPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl(PAGE_PATH),
|
||||
@@ -123,7 +123,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
const howToJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: "Transcribe an audio file with speaker labels in Vocalinux",
|
||||
name: "Transcribe an audio file with speaker labels in Voculinux",
|
||||
step: howToSteps.map((step, index) => ({
|
||||
"@type": "HowToStep",
|
||||
position: index + 1,
|
||||
@@ -163,7 +163,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
Transcribe audio files offline, with speaker labels
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux can turn a recorded meeting, interview or voice memo into a
|
||||
Voculinux can turn a recorded meeting, interview or voice memo into a
|
||||
text transcript on your own machine. It uses TinyDiarize, a
|
||||
whisper.cpp model that also marks where the speaker changes, so the
|
||||
transcript comes out as timestamped blocks labelled Speaker 1, Speaker
|
||||
@@ -222,7 +222,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
</ol>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
The model download is checked against a pinned SHA-256 digest before
|
||||
use, like every other Vocalinux model. The status line under the
|
||||
use, like every other Voculinux model. The status line under the
|
||||
transcript reports how many blocks were found and the highest speaker
|
||||
number.
|
||||
</p>
|
||||
@@ -244,7 +244,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
/>
|
||||
<ul className="mt-4 space-y-2 text-sm text-muted-foreground">
|
||||
<li>
|
||||
It needs no display and no tray, and it runs alongside a Vocalinux
|
||||
It needs no display and no tray, and it runs alongside a Voculinux
|
||||
instance that is already running, so it works over SSH or from a
|
||||
script.
|
||||
</li>
|
||||
@@ -256,9 +256,9 @@ export default function TranscribeAudioFilesPage() {
|
||||
<li>
|
||||
Because the transcript goes to standard output, you can redirect it
|
||||
to a file with your shell. Errors go to standard error, prefixed
|
||||
with <code>vocalinux: could not transcribe</code>, and the exit
|
||||
with <code>voculinux: could not transcribe</code>, and the exit
|
||||
status is 1. A file with no detectable speech prints{" "}
|
||||
<code>vocalinux: no speech detected</code>.
|
||||
<code>voculinux: no speech detected</code>.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
@@ -272,7 +272,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<th className="pb-3 pr-4 font-semibold">Input</th>
|
||||
<th className="pb-3 font-semibold">How Vocalinux reads it</th>
|
||||
<th className="pb-3 font-semibold">How Voculinux reads it</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -286,7 +286,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
</table>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
Vocalinux does not install ffmpeg for you. Without it, only 16-bit 16
|
||||
Voculinux does not install ffmpeg for you. Without it, only 16-bit 16
|
||||
kHz WAV files can be transcribed, and the tray picker's filter
|
||||
says so.
|
||||
</p>
|
||||
@@ -319,7 +319,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
<p className="mb-4 text-muted-foreground">
|
||||
TinyDiarize is a small, English-only whisper.cpp model whose output
|
||||
includes a speaker-turn marker wherever it detects a change of voice.
|
||||
Vocalinux runs it in whisper.cpp's tinydiarize mode and splits
|
||||
Voculinux runs it in whisper.cpp's tinydiarize mode and splits
|
||||
the text at each marker. Each new block gets the next number.
|
||||
</p>
|
||||
<p className="text-muted-foreground">
|
||||
@@ -381,7 +381,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
File transcription is available from v0.18.0; check yours with{" "}
|
||||
<code>vocalinux --version</code>. For live dictation model choices,
|
||||
<code>voculinux --version</code>. For live dictation model choices,
|
||||
see the <Link href="/whisper-model-guide/">Whisper model guide</Link>;
|
||||
to fix names the model mishears in dictation, use the{" "}
|
||||
<Link href="/custom-dictionary/">custom dictionary</Link>.
|
||||
@@ -391,7 +391,7 @@ export default function TranscribeAudioFilesPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -14,7 +14,7 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
|
||||
const troubleshootingItems = [
|
||||
{
|
||||
title: "Vocalinux won't start",
|
||||
title: "Voculinux won't start",
|
||||
symptoms: [
|
||||
"Command not found",
|
||||
"Module import errors",
|
||||
@@ -22,7 +22,7 @@ const troubleshootingItems = [
|
||||
],
|
||||
solutions: [
|
||||
"Ensure you ran the installer from the homepage or install guide",
|
||||
"Check if the virtual environment is activated: source ~/.local/share/vocalinux/venv/bin/activate",
|
||||
"Check if the virtual environment is activated: source ~/.local/share/voculinux/venv/bin/activate",
|
||||
"Verify Python version (3.11+ required): python3 --version",
|
||||
"Try reinstalling: ./uninstall.sh && ./install.sh",
|
||||
],
|
||||
@@ -48,11 +48,11 @@ const troubleshootingItems = [
|
||||
"Text injection fails",
|
||||
],
|
||||
solutions: [
|
||||
"For Wayland: Ensure IBus is running and Vocalinux IBus is configured",
|
||||
"For Wayland: Ensure IBus is running and Voculinux 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",
|
||||
"Restart Voculinux after changing display servers",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -89,7 +89,7 @@ const troubleshootingItems = [
|
||||
"HTTP 404 on transcription",
|
||||
],
|
||||
solutions: [
|
||||
"Confirm the server URL is reachable from the Vocalinux machine",
|
||||
"Confirm the server URL is reachable from the Voculinux machine",
|
||||
"Check whether the server expects /inference or /v1/audio/transcriptions",
|
||||
"Set the API key if your server requires bearer token authentication",
|
||||
"Use HTTPS and a firewall when the server is outside a trusted LAN",
|
||||
@@ -102,10 +102,10 @@ const troubleshootingItems = [
|
||||
"Silence-only buffers still appear",
|
||||
],
|
||||
solutions: [
|
||||
'Install neural VAD support: pip install "vocalinux[vad]"',
|
||||
"Restart Vocalinux after installing ONNX Runtime support",
|
||||
'Install neural VAD support: pip install "voculinux[vad]"',
|
||||
"Restart Voculinux after installing ONNX Runtime support",
|
||||
"Use the VAD sensitivity setting in Recognition to tune quiet speech detection",
|
||||
"If Silero cannot load, Vocalinux falls back safely to amplitude-based VAD",
|
||||
"If Silero cannot load, Voculinux falls back safely to amplitude-based VAD",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -127,13 +127,13 @@ const troubleshootingItems = [
|
||||
],
|
||||
solutions: [
|
||||
"Check if another application is capturing the shortcut",
|
||||
"Verify Vocalinux is running (check system tray)",
|
||||
"Verify Voculinux is running (check system tray)",
|
||||
"Try changing the shortcut in Settings",
|
||||
"On Wayland, ensure keyboard shortcuts are not blocked by compositor settings",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Vocalinux stops working after system suspend/resume",
|
||||
title: "Voculinux stops working after system suspend/resume",
|
||||
symptoms: [
|
||||
"Dictation doesn't start after laptop wakes",
|
||||
"Keyboard shortcuts stop working",
|
||||
@@ -142,7 +142,7 @@ const troubleshootingItems = [
|
||||
solutions: [
|
||||
"v0.10.1+ automatically recovers after suspend - ensure you're on latest version",
|
||||
"Check system tray icon status after resume",
|
||||
"If issues persist, restart Vocalinux from tray menu",
|
||||
"If issues persist, restart Voculinux from tray menu",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -154,7 +154,7 @@ const troubleshootingItems = [
|
||||
"Install the GNOME AppIndicator extension (pick your distro): Debian/Ubuntu: sudo apt install gnome-shell-extension-appindicator — Fedora: sudo dnf install gnome-shell-extension-appindicator — Arch: sudo pacman -S gnome-shell-extension-appindicator",
|
||||
"Then enable the extension (Extensions app, or: gnome-extensions enable appindicatorsupport@rgcjonas.gmail.com) and log out/in if needed",
|
||||
"Debian/Ubuntu: sudo apt install libayatana-appindicator3-1 — Fedora: sudo dnf install libayatana-appindicator-gtk3 — Arch: sudo pacman -S libayatana-appindicator (legacy libappindicator-gtk3 can leave the icon missing on KDE)",
|
||||
"Try launching from terminal to see any errors: vocalinux --debug",
|
||||
"Try launching from terminal to see any errors: voculinux --debug",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -170,10 +170,10 @@ const troubleshootingItems = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Linux Voice Dictation Troubleshooting Guide",
|
||||
description:
|
||||
"Fix common Vocalinux issues: microphone problems, text injection, installation errors, and performance. Step-by-step solutions for Linux voice dictation.",
|
||||
"Fix common Voculinux issues: microphone problems, text injection, installation errors, and performance. Step-by-step solutions for Linux voice dictation.",
|
||||
path: "/troubleshooting",
|
||||
keywords: [
|
||||
"vocalinux troubleshooting",
|
||||
"voculinux troubleshooting",
|
||||
"linux voice dictation problems",
|
||||
"speech to text not working",
|
||||
"microphone issues linux",
|
||||
@@ -184,9 +184,9 @@ export default function TroubleshootingPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux Troubleshooting Guide",
|
||||
headline: "Voculinux Troubleshooting Guide",
|
||||
description:
|
||||
"Complete troubleshooting guide for Vocalinux Linux voice dictation software.",
|
||||
"Complete troubleshooting guide for Voculinux Linux voice dictation software.",
|
||||
dateModified: "2026-06-11",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -195,10 +195,10 @@ export default function TroubleshootingPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/troubleshooting"),
|
||||
@@ -220,7 +220,7 @@ export default function TroubleshootingPage() {
|
||||
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.
|
||||
Having issues with Voculinux? Find solutions to common problems below.
|
||||
Can't find your issue? Open a GitHub issue for help.
|
||||
</p>
|
||||
</section>
|
||||
@@ -231,10 +231,10 @@ export default function TroubleshootingPage() {
|
||||
Quick Debug Command
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Run Vocalinux with debug output to see detailed logs:
|
||||
Run Voculinux with debug output to see detailed logs:
|
||||
</p>
|
||||
<div className="rounded-lg bg-[color:var(--terminal)] p-4">
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">vocalinux --debug</code>
|
||||
<code className="text-sm text-[color:var(--terminal-fg)]">voculinux --debug</code>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ const useCases = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Use Cases for Linux Voice Dictation",
|
||||
description:
|
||||
"Discover how developers, writers, students, and professionals use Vocalinux for Linux voice dictation. Find your use case and boost productivity.",
|
||||
"Discover how developers, writers, students, and professionals use Voculinux for Linux voice dictation. Find your use case and boost productivity.",
|
||||
path: "/use-cases",
|
||||
keywords: [
|
||||
"voice dictation for developers",
|
||||
@@ -108,9 +108,9 @@ export default function UseCasesPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux Use Cases - Voice Dictation for Every Workflow",
|
||||
headline: "Voculinux Use Cases - Voice Dictation for Every Workflow",
|
||||
description:
|
||||
"Discover how different professionals use Vocalinux for Linux voice dictation.",
|
||||
"Discover how different professionals use Voculinux for Linux voice dictation.",
|
||||
dateModified: "2026-02-19",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -119,10 +119,10 @@ export default function UseCasesPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/use-cases"),
|
||||
@@ -144,7 +144,7 @@ export default function UseCasesPage() {
|
||||
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
|
||||
Whether you're coding, writing, studying, or need accessibility support, Voculinux adapts
|
||||
to your needs. See how different professionals use voice dictation to boost productivity.
|
||||
</p>
|
||||
</section>
|
||||
@@ -202,7 +202,7 @@ export default function UseCasesPage() {
|
||||
<section className="mt-12 rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Ready to Get Started?</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Install Vocalinux in minutes and start dictating in any application on Linux.
|
||||
Install Voculinux in minutes and start dictating in any application on Linux.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<Link
|
||||
|
||||
@@ -17,7 +17,7 @@ const vadBenefits = [
|
||||
{
|
||||
title: "Drops silence-only buffers",
|
||||
description:
|
||||
"Silero VAD helps Vocalinux ignore chunks that do not contain speech before they reach the recognition engine.",
|
||||
"Silero VAD helps Voculinux ignore chunks that do not contain speech before they reach the recognition engine.",
|
||||
},
|
||||
{
|
||||
title: "Cleaner dictation sessions",
|
||||
@@ -33,7 +33,7 @@ const vadBenefits = [
|
||||
|
||||
const signalFlow = [
|
||||
"Microphone audio is captured locally.",
|
||||
"Vocalinux checks each short chunk for speech activity.",
|
||||
"Voculinux checks each short chunk for speech activity.",
|
||||
"Speech chunks are kept for transcription.",
|
||||
"Silence-only chunks are dropped before recognition.",
|
||||
"If Silero is unavailable, amplitude-based VAD takes over.",
|
||||
@@ -42,12 +42,12 @@ const signalFlow = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Silero VAD for Cleaner Linux Voice Dictation",
|
||||
description:
|
||||
"Learn how Vocalinux uses Silero neural voice activity detection to drop silence-only buffers and improve Linux speech-to-text dictation.",
|
||||
"Learn how Voculinux uses Silero neural voice activity detection to drop silence-only buffers and improve Linux speech-to-text dictation.",
|
||||
path: "/voice-activity-detection",
|
||||
keywords: [
|
||||
"silero vad linux dictation",
|
||||
"voice activity detection speech to text",
|
||||
"vocalinux vad sensitivity",
|
||||
"voculinux vad sensitivity",
|
||||
"cleaner whisper dictation linux",
|
||||
],
|
||||
});
|
||||
@@ -58,7 +58,7 @@ export default function VoiceActivityDetectionPage() {
|
||||
"@type": "TechArticle",
|
||||
headline: "Silero VAD for Cleaner Linux Voice Dictation",
|
||||
description:
|
||||
"How Vocalinux uses neural voice activity detection to separate speech from silence before transcription.",
|
||||
"How Voculinux uses neural voice activity detection to separate speech from silence before transcription.",
|
||||
dateModified: "2026-06-11",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -67,10 +67,10 @@ export default function VoiceActivityDetectionPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/voice-activity-detection"),
|
||||
@@ -92,7 +92,7 @@ export default function VoiceActivityDetectionPage() {
|
||||
Silero VAD for Cleaner Linux Voice Dictation
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Vocalinux now uses Silero neural voice activity detection when ONNX
|
||||
Voculinux now uses Silero neural voice activity detection when ONNX
|
||||
Runtime support is available. It identifies speech before
|
||||
transcription, drops silence-only buffers, and falls back safely when
|
||||
the neural backend is not installed.
|
||||
@@ -142,12 +142,12 @@ export default function VoiceActivityDetectionPage() {
|
||||
<div className="space-y-4 text-sm text-muted-foreground">
|
||||
<p>
|
||||
The official installer attempts to install neural VAD support. If
|
||||
ONNX Runtime is not available, Vocalinux logs the fallback and
|
||||
ONNX Runtime is not available, Voculinux logs the fallback and
|
||||
continues with amplitude-based VAD.
|
||||
</p>
|
||||
<div className="rounded-lg bg-[color:var(--terminal)] p-4">
|
||||
<code className="text-[color:var(--terminal-fg)]">
|
||||
pip install "vocalinux[vad]"
|
||||
pip install "voculinux[vad]"
|
||||
</code>
|
||||
</div>
|
||||
<p>
|
||||
|
||||
@@ -16,9 +16,9 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
|
||||
const setupSteps = [
|
||||
{
|
||||
title: "Install Vocalinux",
|
||||
title: "Install Voculinux",
|
||||
description:
|
||||
"Follow the install guide, launch Vocalinux, and confirm your microphone and language are configured.",
|
||||
"Follow the install guide, launch Voculinux, and confirm your microphone and language are configured.",
|
||||
href: "/install/",
|
||||
linkLabel: "Open installation guide",
|
||||
icon: CheckCircle2,
|
||||
@@ -83,8 +83,8 @@ const vscodeTips = [
|
||||
];
|
||||
|
||||
const troubleshootingTips = [
|
||||
"No text appears in VS Code: verify Vocalinux is active and the editor window is focused.",
|
||||
"Shortcut conflicts: remap Vocalinux activation to avoid overlapping VS Code keybinds.",
|
||||
"No text appears in VS Code: verify Voculinux is active and the editor window is focused.",
|
||||
"Shortcut conflicts: remap Voculinux activation to avoid overlapping VS Code keybinds.",
|
||||
"Unexpected punctuation: review your voice command phrases and disable commands if needed.",
|
||||
"Low accuracy: use a quieter mic setup and test another model size/engine in settings.",
|
||||
];
|
||||
@@ -92,14 +92,14 @@ const troubleshootingTips = [
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "How to Dictate in VS Code on Linux (Voice Coding Workflow)",
|
||||
description:
|
||||
"Learn how to use voice dictation in VS Code on Linux. Setup Vocalinux for programming, recommended workflows for coding, PTT vs toggle mode, and troubleshooting tips.",
|
||||
"Learn how to use voice dictation in VS Code on Linux. Setup Voculinux for programming, recommended workflows for coding, PTT vs toggle mode, and troubleshooting tips.",
|
||||
path: "/voice-typing-vscode",
|
||||
keywords: [
|
||||
"voice typing VS Code Linux",
|
||||
"voice coding linux",
|
||||
"dictate code linux",
|
||||
"speech to text programming linux",
|
||||
"vocalinux VS Code",
|
||||
"voculinux VS Code",
|
||||
],
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ export default function VoiceTypingVsCodePage() {
|
||||
"@type": "Article",
|
||||
headline: "How to Dictate in VS Code on Linux (Voice Coding Workflow)",
|
||||
description:
|
||||
"Learn how to use voice dictation in VS Code on Linux. Setup Vocalinux for programming, recommended workflows for coding, PTT vs toggle mode, and troubleshooting tips.",
|
||||
"Learn how to use voice dictation in VS Code on Linux. Setup Voculinux for programming, recommended workflows for coding, PTT vs toggle mode, and troubleshooting tips.",
|
||||
dateModified: "2026-03-30",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -118,10 +118,10 @@ export default function VoiceTypingVsCodePage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/voice-typing-vscode"),
|
||||
@@ -143,7 +143,7 @@ export default function VoiceTypingVsCodePage() {
|
||||
How to Dictate in VS Code on Linux (Voice Coding Workflow)
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Learn how to use Vocalinux for practical, low-friction voice coding in VS Code on Linux.
|
||||
Learn how to use Voculinux for practical, low-friction voice coding in VS Code on Linux.
|
||||
This guide covers setup, toggle vs push-to-talk, editing workflows, and common fixes.
|
||||
</p>
|
||||
</section>
|
||||
@@ -257,14 +257,14 @@ export default function VoiceTypingVsCodePage() {
|
||||
<section className="rounded-[12px] border border-primary/20 bg-primary/5 p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Ready to voice-type in VS Code?</h2>
|
||||
<p className="mb-6 max-w-3xl text-muted-foreground">
|
||||
Install Vocalinux and use a hybrid keyboard + voice workflow that fits real-world Linux
|
||||
Install Voculinux and use a hybrid keyboard + voice workflow that fits real-world Linux
|
||||
development.
|
||||
</p>
|
||||
<Link
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</section>
|
||||
|
||||
@@ -17,62 +17,62 @@ import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
|
||||
const comparisonRows = [
|
||||
{
|
||||
feature: "Interface and daily workflow",
|
||||
vocalinux: "Full GTK GUI + tray controls + keyboard shortcuts",
|
||||
voculinux: "Full GTK GUI + tray controls + keyboard shortcuts",
|
||||
nerdDictation: "CLI-first terminal workflow",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: PanelTop,
|
||||
},
|
||||
{
|
||||
feature: "Offline voice dictation",
|
||||
vocalinux: "Local engines, plus an optional Remote API",
|
||||
voculinux: "Local engines, plus an optional Remote API",
|
||||
nerdDictation: "Offline dictation, single CLI-centered flow",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: Command,
|
||||
},
|
||||
{
|
||||
feature: "Wayland text injection",
|
||||
vocalinux: "Native IBus integration for dictation in any app",
|
||||
voculinux: "Native IBus integration for dictation in any app",
|
||||
nerdDictation: "IBus-based text injection on Wayland",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: Waypoints,
|
||||
},
|
||||
{
|
||||
feature: "GPU acceleration",
|
||||
vocalinux: "Vulkan acceleration across AMD, Intel, and NVIDIA",
|
||||
voculinux: "Vulkan acceleration across AMD, Intel, and NVIDIA",
|
||||
nerdDictation: "CPU-focused workflow",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: Cpu,
|
||||
},
|
||||
{
|
||||
feature: "Push-to-talk",
|
||||
vocalinux: "Built-in push-to-talk and toggle mode",
|
||||
voculinux: "Built-in push-to-talk and toggle mode",
|
||||
nerdDictation: "Terminal-first trigger workflow",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: Gauge,
|
||||
},
|
||||
{
|
||||
feature: "Audio feedback",
|
||||
vocalinux: "Built-in pleasant sound effects for start/stop/error",
|
||||
voculinux: "Built-in pleasant sound effects for start/stop/error",
|
||||
nerdDictation: "No native desktop sound-feedback layer",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: Headphones,
|
||||
},
|
||||
{
|
||||
feature: "System tray integration",
|
||||
vocalinux: "Tray icon with status, controls, and settings access",
|
||||
voculinux: "Tray icon with status, controls, and settings access",
|
||||
nerdDictation: "No native system tray app",
|
||||
winner: "Vocalinux",
|
||||
winner: "Voculinux",
|
||||
icon: Trophy,
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Nerd Dictation Alternative for Linux | Vocalinux",
|
||||
title: "Nerd Dictation Alternative for Linux | Voculinux",
|
||||
description:
|
||||
"Comparing Vocalinux and Nerd Dictation for offline Linux voice dictation. CLI vs GUI, GPU vs CPU-only, Wayland support, and more.",
|
||||
"Comparing Voculinux and Nerd Dictation for offline Linux voice dictation. CLI vs GUI, GPU vs CPU-only, Wayland support, and more.",
|
||||
path: "/vs-nerd-dictation",
|
||||
keywords: [
|
||||
"vocalinux vs nerd dictation",
|
||||
"voculinux vs nerd dictation",
|
||||
"linux voice dictation comparison",
|
||||
"offline speech to text linux",
|
||||
],
|
||||
@@ -82,9 +82,9 @@ export default function VsNerdDictationPage() {
|
||||
const articleJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: "Vocalinux vs Nerd Dictation: Best Offline Voice Dictation for Linux",
|
||||
headline: "Voculinux vs Nerd Dictation: Best Offline Voice Dictation for Linux",
|
||||
description:
|
||||
"Comparing Vocalinux and Nerd Dictation for offline Linux voice dictation. CLI vs GUI, GPU vs CPU-only, Wayland support, and more.",
|
||||
"Comparing Voculinux and Nerd Dictation for offline Linux voice dictation. CLI vs GUI, GPU vs CPU-only, Wayland support, and more.",
|
||||
dateModified: "2026-03-30",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -93,10 +93,10 @@ export default function VsNerdDictationPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/vs-nerd-dictation"),
|
||||
@@ -112,15 +112,15 @@ export default function VsNerdDictationPage() {
|
||||
<section>
|
||||
<p className="subpage-kicker">
|
||||
<Trophy className="h-4 w-4" />
|
||||
Vocalinux Comparison
|
||||
Voculinux Comparison
|
||||
</p>
|
||||
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Vocalinux vs Nerd Dictation
|
||||
Voculinux vs Nerd Dictation
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Nerd Dictation is a popular offline CLI tool for Linux. But if you want a complete desktop
|
||||
dictation experience with GUI controls, tray integration, push-to-talk, and broad GPU support,
|
||||
Vocalinux is the better choice.
|
||||
Voculinux is the better choice.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -130,7 +130,7 @@ export default function VsNerdDictationPage() {
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<th className="px-4 py-3 text-sm font-semibold">Feature</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Vocalinux</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Voculinux</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Nerd Dictation</th>
|
||||
<th className="px-4 py-3 text-sm font-semibold">Winner</th>
|
||||
</tr>
|
||||
@@ -152,7 +152,7 @@ export default function VsNerdDictationPage() {
|
||||
{row.feature}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-4 text-sm text-muted-foreground">{row.vocalinux}</td>
|
||||
<td className="px-4 py-4 text-sm text-muted-foreground">{row.voculinux}</td>
|
||||
<td className="px-4 py-4 text-sm text-muted-foreground">{row.nerdDictation}</td>
|
||||
<td className="px-4 py-4 text-sm font-semibold text-primary">
|
||||
<span className="inline-flex items-center gap-2">
|
||||
@@ -194,7 +194,7 @@ export default function VsNerdDictationPage() {
|
||||
<section className="mt-10 rounded-[12px] border border-primary/20 bg-primary/5 p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Ready to switch from terminal-only dictation?</h2>
|
||||
<p className="mb-6 max-w-3xl text-muted-foreground">
|
||||
Install Vocalinux for a native Linux voice dictation workflow with offline privacy, better
|
||||
Install Voculinux for a native Linux voice dictation workflow with offline privacy, better
|
||||
usability, and stronger performance options.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
@@ -202,7 +202,7 @@ export default function VsNerdDictationPage() {
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Link>
|
||||
<Link
|
||||
|
||||
@@ -99,14 +99,14 @@ const setupSteps = [
|
||||
},
|
||||
{
|
||||
step: 3,
|
||||
title: "Run Vocalinux",
|
||||
description: "Vocalinux will auto-detect Wayland and configure IBus:",
|
||||
command: "vocalinux",
|
||||
title: "Run Voculinux",
|
||||
description: "Voculinux will auto-detect Wayland and configure IBus:",
|
||||
command: "voculinux",
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Wayland Voice Dictation Support - GNOME, KDE, Sway | Vocalinux",
|
||||
title: "Wayland Voice Dictation Support - GNOME, KDE, Sway | Voculinux",
|
||||
description:
|
||||
"Full Wayland support for voice dictation on Linux. Works with GNOME, KDE Plasma, Sway, Hyprland, and other Wayland compositors via IBus integration.",
|
||||
path: "/wayland",
|
||||
@@ -128,7 +128,7 @@ export default function WaylandPage() {
|
||||
"@type": "Article",
|
||||
headline: "Wayland Voice Dictation Support for Linux",
|
||||
description:
|
||||
"Complete guide to Vocalinux Wayland support. Voice dictation for GNOME, KDE, Sway, Hyprland, and other Wayland compositors.",
|
||||
"Complete guide to Voculinux Wayland support. Voice dictation for GNOME, KDE, Sway, Hyprland, and other Wayland compositors.",
|
||||
dateModified: "2026-06-11",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -137,10 +137,10 @@ export default function WaylandPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/wayland"),
|
||||
@@ -258,14 +258,14 @@ export default function WaylandPage() {
|
||||
</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Unlike X11 where applications can simulate keyboard input globally,
|
||||
Wayland's security model requires a different approach. Vocalinux
|
||||
Wayland's security model requires a different approach. Voculinux
|
||||
uses:
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
<li className="flex items-start gap-2">
|
||||
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0" />
|
||||
<strong>IBus Engine</strong> - A custom IBus input method that
|
||||
receives text from Vocalinux and types it into the focused
|
||||
receives text from Voculinux and types it into the focused
|
||||
application
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
@@ -293,7 +293,7 @@ export default function WaylandPage() {
|
||||
<section className="rounded-[12px] border border-border bg-muted p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Start Dictating on Wayland</h2>
|
||||
<p className="mb-6 text-muted-foreground">
|
||||
Vocalinux automatically detects your display server and configures the
|
||||
Voculinux automatically detects your display server and configures the
|
||||
appropriate text injection method. Just install and run.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
|
||||
@@ -89,10 +89,10 @@ export default function WhisperModelGuidePage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/whisper-model-guide"),
|
||||
@@ -116,7 +116,7 @@ export default function WhisperModelGuidePage() {
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Picking the right model is the biggest performance decision for Linux voice dictation.
|
||||
Use this guide to choose between tiny, base, small, medium, and large based on RAM,
|
||||
speed, and real-world transcription accuracy in Vocalinux.
|
||||
speed, and real-world transcription accuracy in Voculinux.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -249,7 +249,7 @@ export default function WhisperModelGuidePage() {
|
||||
<article className="rounded-[12px] border border-border bg-background p-6">
|
||||
<h2 className="mb-3 text-xl font-semibold">Ready to install?</h2>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
Use the install guide to get Vocalinux running with the model size that fits your hardware.
|
||||
Use the install guide to get Voculinux running with the model size that fits your hardware.
|
||||
</p>
|
||||
<Link href="/install/" className="inline-flex items-center gap-1 text-primary hover:underline">
|
||||
Installation guide <ArrowRight className="h-4 w-4" />
|
||||
@@ -258,17 +258,17 @@ export default function WhisperModelGuidePage() {
|
||||
</section>
|
||||
|
||||
<section className="mt-12 rounded-[12px] border border-primary/30 bg-primary/10 p-8">
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Install Vocalinux and start dictating today</h2>
|
||||
<h2 className="mb-4 font-display text-2xl font-semibold">Install Voculinux and start dictating today</h2>
|
||||
<p className="mb-6 max-w-3xl text-muted-foreground">
|
||||
Start with <strong>small</strong> if unsure, then move up or down after a day of use.
|
||||
Vocalinux makes model changes simple, so you can tune for your exact speed/accuracy
|
||||
Voculinux makes model changes simple, so you can tune for your exact speed/accuracy
|
||||
preference.
|
||||
</p>
|
||||
<Link
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</section>
|
||||
|
||||
@@ -65,14 +65,14 @@ const integrations = [
|
||||
{
|
||||
app: "Terminal Editors",
|
||||
description:
|
||||
"Use Vocalinux with terminal apps and editors to write notes, commit messages, and drafts quickly.",
|
||||
"Use Voculinux with terminal apps and editors to write notes, commit messages, and drafts quickly.",
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata: Metadata = buildPageMetadata({
|
||||
title: "Voice Dictation for Writers on Linux",
|
||||
description:
|
||||
"Complete guide to voice dictation for writers on Linux. How to dictate novels, blog posts, and notes using Vocalinux. Hands-free writing workflow tips.",
|
||||
"Complete guide to voice dictation for writers on Linux. How to dictate novels, blog posts, and notes using Voculinux. Hands-free writing workflow tips.",
|
||||
path: "/writers",
|
||||
keywords: [
|
||||
"voice dictation for writers linux",
|
||||
@@ -89,7 +89,7 @@ export default function WritersPage() {
|
||||
"@type": "Article",
|
||||
headline: "Voice Dictation for Writers on Linux: Dictate Novels, Articles & Notes",
|
||||
description:
|
||||
"Complete guide to voice dictation for writers on Linux. How to dictate novels, blog posts, and notes using Vocalinux. Hands-free writing workflow tips.",
|
||||
"Complete guide to voice dictation for writers on Linux. How to dictate novels, blog posts, and notes using Voculinux. Hands-free writing workflow tips.",
|
||||
dateModified: "2026-03-30",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
@@ -98,10 +98,10 @@ export default function WritersPage() {
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Vocalinux",
|
||||
name: "Voculinux",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: absoluteUrl("/vocalinux.png"),
|
||||
url: absoluteUrl("/voculinux.png"),
|
||||
},
|
||||
},
|
||||
mainEntityOfPage: absoluteUrl("/writers"),
|
||||
@@ -123,7 +123,7 @@ export default function WritersPage() {
|
||||
Voice Dictation for Writers on Linux: Dictate Novels, Articles & Notes
|
||||
</h1>
|
||||
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
|
||||
Write at the speed of thought. Vocalinux helps novelists, bloggers, students, and
|
||||
Write at the speed of thought. Voculinux helps novelists, bloggers, students, and
|
||||
journalists dictate drafts hands-free in their favorite Linux apps.
|
||||
</p>
|
||||
</section>
|
||||
@@ -239,21 +239,21 @@ export default function WritersPage() {
|
||||
>
|
||||
<BookOpen className="mb-3 h-6 w-6 text-primary" />
|
||||
<h3 className="mb-1 font-semibold">More Use Cases</h3>
|
||||
<p className="text-sm text-muted-foreground">Explore all workflows powered by Vocalinux.</p>
|
||||
<p className="text-sm text-muted-foreground">Explore all workflows powered by Voculinux.</p>
|
||||
</Link>
|
||||
</section>
|
||||
|
||||
<section className="rounded-[12px] border border-primary/30 bg-primary/10 p-8">
|
||||
<h2 className="mb-3 font-display text-2xl font-semibold">Start Writing with Your Voice</h2>
|
||||
<p className="mb-6 max-w-3xl text-muted-foreground">
|
||||
Install Vocalinux and start dictating novels, blog posts, academic notes, and newsroom
|
||||
Install Voculinux and start dictating novels, blog posts, academic notes, and newsroom
|
||||
drafts directly on Linux - without cloud lock-in.
|
||||
</p>
|
||||
<Link
|
||||
href="/install/"
|
||||
className="inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground"
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { OptimizedImage, VocalinuxLogo } from '../optimized-image';
|
||||
import { OptimizedImage, VoculinuxLogo } from '../optimized-image';
|
||||
|
||||
// Mock Next.js Image component
|
||||
jest.mock('next/image', () => ({
|
||||
@@ -91,47 +91,47 @@ describe('OptimizedImage', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('VocalinuxLogo', () => {
|
||||
describe('VoculinuxLogo', () => {
|
||||
it('renders without crashing', () => {
|
||||
render(<VocalinuxLogo />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('uses the circular mark', () => {
|
||||
render(<VocalinuxLogo />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
expect(img).toHaveAttribute('src', '/brand/vocalinux-mark-circle.svg');
|
||||
render(<VoculinuxLogo />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('src', '/brand/voculinux-mark-circle.svg');
|
||||
});
|
||||
|
||||
it('uses default dimensions when not specified', () => {
|
||||
render(<VocalinuxLogo />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('width', '32');
|
||||
expect(img).toHaveAttribute('height', '32');
|
||||
});
|
||||
|
||||
it('accepts custom dimensions', () => {
|
||||
render(<VocalinuxLogo width={64} height={64} />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo width={64} height={64} />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('width', '64');
|
||||
expect(img).toHaveAttribute('height', '64');
|
||||
});
|
||||
|
||||
it('applies custom className', () => {
|
||||
render(<VocalinuxLogo className="logo-class" />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo className="logo-class" />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveClass('logo-class');
|
||||
});
|
||||
|
||||
it('passes priority prop for eager loading', () => {
|
||||
render(<VocalinuxLogo priority />);
|
||||
const img = screen.getByAltText('Vocalinux');
|
||||
render(<VoculinuxLogo priority />);
|
||||
const img = screen.getByAltText('Voculinux');
|
||||
expect(img).toHaveAttribute('loading', 'eager');
|
||||
});
|
||||
|
||||
it('uses empty alt text when decorative', () => {
|
||||
const { container } = render(<VocalinuxLogo decorative />);
|
||||
const { container } = render(<VoculinuxLogo decorative />);
|
||||
expect(container.querySelector('img')).toHaveAttribute('alt', '');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -134,11 +134,11 @@ describe("ScreenshotGallery lightbox", () => {
|
||||
"aria-pressed",
|
||||
"true",
|
||||
);
|
||||
expect(sessionStorage.getItem("vocalinux-shot-appearance")).toBe("dark");
|
||||
expect(sessionStorage.getItem("voculinux-shot-appearance")).toBe("dark");
|
||||
});
|
||||
|
||||
it("restores a tab override from sessionStorage", async () => {
|
||||
sessionStorage.setItem("vocalinux-shot-appearance", "dark");
|
||||
sessionStorage.setItem("voculinux-shot-appearance", "dark");
|
||||
render(
|
||||
<ScreenshotGallery
|
||||
productShots={productShots}
|
||||
|
||||
@@ -4,14 +4,14 @@ import React from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
// Re-export from optimized-image component for backward compatibility
|
||||
export { VocalinuxLogo } from "./optimized-image";
|
||||
export { VoculinuxLogo } from "./optimized-image";
|
||||
|
||||
// Legacy export - use VocalinuxLogo from optimized-image instead
|
||||
export const VocalinuxLogoLegacy: React.FC<{ className?: string }> = ({ className = "" }) => {
|
||||
// Legacy export - use VoculinuxLogo from optimized-image instead
|
||||
export const VoculinuxLogoLegacy: React.FC<{ className?: string }> = ({ className = "" }) => {
|
||||
return (
|
||||
<Image
|
||||
src="/vocalinux.png"
|
||||
alt="Vocalinux Logo"
|
||||
src="/voculinux.png"
|
||||
alt="Voculinux Logo"
|
||||
width={36}
|
||||
height={36}
|
||||
className={className}
|
||||
@@ -21,7 +21,7 @@ export const VocalinuxLogoLegacy: React.FC<{ className?: string }> = ({ classNam
|
||||
};
|
||||
|
||||
// Alternative: Inline SVG version for when color customization is needed
|
||||
export const VocalinuxLogoInline: React.FC<React.SVGProps<SVGSVGElement>> = (props) => {
|
||||
export const VoculinuxLogoInline: React.FC<React.SVGProps<SVGSVGElement>> = (props) => {
|
||||
return (
|
||||
<svg width="36" height="36" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<path d="M243.33 120.92c-58.29 1.8-107.88 51.39-107.88 110.12v100.24c0 20.87 5.16 39.95 14.02 57.07l-44.12 44.12c-3.27 3.27-3.27 8.58 0 11.86 1.64 1.64 3.79 2.46 5.93 2.46 2.14 0 4.29-.82 5.93-2.46l43.39-43.39a107.388 107.388 0 0074.73 30.13h.01c20.94 0 40.83-6.05 57.99-16.52 23.86-14.53 42.22-37.58 49.7-64.48.8-2.89-1.18-5.8-4.17-6.14-2.99-.33-5.57 1.79-5.75 4.8-2.91 48.11-43.05 85.82-91.5 85.82h-.76c-50.83-1.57-93.56-42.09-93.56-93.67V231.04c0-51.11 41.57-93.67 92.68-93.67 46.36 0 86.43 35.37 93.54 80.62.41 2.64 2.69 4.56 5.38 4.5 2.67-.06 4.84-2.1 5.13-4.75 7.65-71.11-46.43-98.62-99.69-96.82z" fill="currentColor" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { VocalinuxLogo } from "./icons";
|
||||
import { VoculinuxLogo } from "./icons";
|
||||
import { cn } from "@/lib/utils";
|
||||
interface LogoProps {
|
||||
className?: string;
|
||||
@@ -12,7 +12,7 @@ export function Logo({
|
||||
textClassName
|
||||
}: LogoProps) {
|
||||
return <div className={cn("flex items-center gap-2", className)}>
|
||||
<VocalinuxLogo className={cn("h-8 w-8", iconClassName)} />
|
||||
<span className={cn("font-bold text-xl", textClassName)}>Vocalinux</span>
|
||||
<VoculinuxLogo className={cn("h-8 w-8", iconClassName)} />
|
||||
<span className={cn("font-bold text-xl", textClassName)}>Voculinux</span>
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@ export const OptimizedImage: React.FC<OptimizedImageProps> = ({
|
||||
};
|
||||
|
||||
/**
|
||||
* Specialized Vocalinux logo component with WebP support
|
||||
* Specialized Voculinux logo component with WebP support
|
||||
*/
|
||||
export const VocalinuxLogo: React.FC<{
|
||||
export const VoculinuxLogo: React.FC<{
|
||||
className?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
priority?: boolean;
|
||||
/** Set when the visible "Vocalinux" text sits next to the mark. */
|
||||
/** Set when the visible "Voculinux" text sits next to the mark. */
|
||||
decorative?: boolean;
|
||||
}> = ({
|
||||
className = "",
|
||||
@@ -66,8 +66,8 @@ export const VocalinuxLogo: React.FC<{
|
||||
// SVG lockup; next/image is for raster.
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src="/brand/vocalinux-mark-circle.svg"
|
||||
alt={decorative ? "" : "Vocalinux"}
|
||||
src="/brand/voculinux-mark-circle.svg"
|
||||
alt={decorative ? "" : "Voculinux"}
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
|
||||
@@ -22,7 +22,7 @@ export type Screenshot = {
|
||||
|
||||
type ShotTheme = "light" | "dark";
|
||||
|
||||
const THEME_STORAGE_KEY = "vocalinux-shot-appearance";
|
||||
const THEME_STORAGE_KEY = "voculinux-shot-appearance";
|
||||
|
||||
export function darkScreenshotPath(src: string): string {
|
||||
if (src.includes("/dark/")) return src;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import React, { useEffect, useId, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { Star } from "lucide-react";
|
||||
import { VocalinuxLogo } from "@/components/optimized-image";
|
||||
import { GITHUB_REPO_URL, VOCAHQ_URL } from "@/lib/seo";
|
||||
import { VoculinuxLogo } from "@/components/optimized-image";
|
||||
import { GITHUB_REPO_URL } from "@/lib/seo";
|
||||
import {
|
||||
footerGroups,
|
||||
homeNav,
|
||||
@@ -101,16 +101,35 @@ export function SiteChrome({
|
||||
|
||||
<header className="site-header">
|
||||
<div className="shell header-inner">
|
||||
<Link href="/" className="brand" aria-label="Vocalinux home">
|
||||
<VocalinuxLogo
|
||||
<Link href="/" className="brand" aria-label="Voculinux home">
|
||||
<VoculinuxLogo
|
||||
width={28}
|
||||
height={28}
|
||||
className="h-7 w-7"
|
||||
priority
|
||||
decorative
|
||||
/>
|
||||
<span>Vocalinux</span>
|
||||
<span>Voculinux</span>
|
||||
</Link>
|
||||
<a
|
||||
className="header-attribution"
|
||||
href="https://bongbetic.com"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="By Bongbetic"
|
||||
title="By Bongbetic"
|
||||
>
|
||||
{/* Hosted brand asset: never vendored into the repository. */}
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="https://bongbetic.com/branding/bongbetic-logo.png"
|
||||
alt=""
|
||||
width={18}
|
||||
height={18}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<span>by Bongbetic</span>
|
||||
</a>
|
||||
|
||||
<nav className="nav-links" aria-label="Primary">
|
||||
{nav.map((item) => (
|
||||
@@ -127,8 +146,8 @@ export function SiteChrome({
|
||||
rel="noopener noreferrer"
|
||||
aria-label={
|
||||
stars !== null
|
||||
? `Vocalinux on GitHub, ${stars.toLocaleString("en-US")} stars`
|
||||
: "Vocalinux on GitHub"
|
||||
? `Voculinux on GitHub, ${stars.toLocaleString("en-US")} stars`
|
||||
: "Voculinux on GitHub"
|
||||
}
|
||||
>
|
||||
<Star
|
||||
@@ -179,7 +198,7 @@ export function SiteChrome({
|
||||
href={ctaHref}
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
Install Vocalinux
|
||||
Install Voculinux
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
||||
@@ -191,13 +210,13 @@ export function SiteChrome({
|
||||
<div className="footer-inner">
|
||||
<div className="footer-brand">
|
||||
<Link href="/" className="brand">
|
||||
<VocalinuxLogo
|
||||
<VoculinuxLogo
|
||||
width={28}
|
||||
height={28}
|
||||
className="h-7 w-7"
|
||||
decorative
|
||||
/>
|
||||
<span>Vocalinux</span>
|
||||
<span>Voculinux</span>
|
||||
</Link>
|
||||
<p>
|
||||
Offline voice typing for Linux. Local engines by default, no
|
||||
@@ -250,10 +269,22 @@ export function SiteChrome({
|
||||
</a>
|
||||
.
|
||||
</span>
|
||||
<span>
|
||||
Part of{" "}
|
||||
<a href={VOCAHQ_URL} rel="noopener noreferrer">
|
||||
VocaHQ
|
||||
<span className="footer-attribution">
|
||||
{/* Hosted brand assets: linked, never vendored. */}
|
||||
<a
|
||||
href="https://bongbetic.com"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Bongbetic"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="https://bongbetic.com/branding/bongbetic-logo-lockup.png"
|
||||
alt="Bongbetic"
|
||||
width={96}
|
||||
height={24}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -2,22 +2,22 @@ import { absoluteUrl } from "../seo";
|
||||
|
||||
describe("absoluteUrl", () => {
|
||||
it("returns the site root for /", () => {
|
||||
expect(absoluteUrl("/")).toBe("https://vocalinux.com/");
|
||||
expect(absoluteUrl("/")).toBe("https://voculinux.com/");
|
||||
});
|
||||
|
||||
it("adds the trailing slash pages are served with", () => {
|
||||
expect(absoluteUrl("/install/debian")).toBe(
|
||||
"https://vocalinux.com/install/debian/",
|
||||
"https://voculinux.com/install/debian/",
|
||||
);
|
||||
expect(absoluteUrl("/faq/")).toBe("https://vocalinux.com/faq/");
|
||||
expect(absoluteUrl("/faq/")).toBe("https://voculinux.com/faq/");
|
||||
});
|
||||
|
||||
it("leaves file URLs without a trailing slash", () => {
|
||||
expect(absoluteUrl("/vocalinux.png")).toBe(
|
||||
"https://vocalinux.com/vocalinux.png",
|
||||
expect(absoluteUrl("/voculinux.png")).toBe(
|
||||
"https://voculinux.com/voculinux.png",
|
||||
);
|
||||
expect(absoluteUrl("/og-image.png")).toBe(
|
||||
"https://vocalinux.com/og-image.png",
|
||||
"https://voculinux.com/og-image.png",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { SITE_NAME, SITE_URL } from "../seo";
|
||||
|
||||
describe("voculinux rebrand (ticket #24)", () => {
|
||||
it("names the fork site", () => {
|
||||
expect(SITE_NAME).toBe("Voculinux");
|
||||
});
|
||||
|
||||
it("points at the fork domain", () => {
|
||||
expect(SITE_URL).toBe("https://voculinux.com");
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import { type Metadata } from "next";
|
||||
|
||||
export const SITE_URL = "https://vocalinux.com";
|
||||
export const SITE_NAME = "Vocalinux";
|
||||
export const SITE_URL = "https://voculinux.com";
|
||||
export const SITE_NAME = "Voculinux";
|
||||
export const DEFAULT_OG_IMAGE_PATH = "/og-image.png";
|
||||
export const DEFAULT_OG_IMAGE_ALT =
|
||||
"Dictate locally. In any app. Offline voice dictation for Linux.";
|
||||
@@ -26,8 +26,8 @@ const normalizePath = (path: string): string => {
|
||||
|
||||
const trimmed = path.replace(/^\/+|\/+$/g, "");
|
||||
|
||||
// Files such as /vocalinux.png must not get the page trailing slash:
|
||||
// /vocalinux.png/ is a 404 on GitHub Pages.
|
||||
// Files such as /voculinux.png must not get the page trailing slash:
|
||||
// /voculinux.png/ is a 404 on GitHub Pages.
|
||||
if (/\.[a-z0-9]+$/i.test(trimmed)) {
|
||||
return `/${trimmed}`;
|
||||
}
|
||||
@@ -47,9 +47,9 @@ export const buildPageMetadata = ({
|
||||
}: PageMetadataOptions): Metadata => {
|
||||
const canonical = absoluteUrl(path);
|
||||
|
||||
// The root layout applies the "%s | Vocalinux" template. Titles that already
|
||||
// The root layout applies the "%s | Voculinux" template. Titles that already
|
||||
// carry the brand suffix are emitted as-is so search results do not show
|
||||
// "| Vocalinux | Vocalinux".
|
||||
// "| Voculinux | Voculinux".
|
||||
const pageTitle: Metadata["title"] = new RegExp(
|
||||
`[|\\-–—]\\s*${SITE_NAME}$`,
|
||||
).test(title)
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
DISCORD_URL,
|
||||
EMAIL_URL,
|
||||
GITHUB_REPO_URL,
|
||||
VOCAHQ_URL,
|
||||
X_URL,
|
||||
} from "@/lib/seo";
|
||||
|
||||
@@ -104,7 +103,7 @@ export const footerGroups: { title: string; links: NavLink[] }[] = [
|
||||
{ href: "/privacy/", label: "Privacy" },
|
||||
{ href: "/changelog/", label: "Changelog" },
|
||||
{ href: GITHUB_REPO_URL, label: "Source" },
|
||||
{ href: VOCAHQ_URL, label: "VocaHQ" },
|
||||
{ href: "https://bongbetic.com", label: "Bongbetic" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* Vocalinux — Voca family workbench.
|
||||
/* Voculinux — Carbon-mapped house palette.
|
||||
Warm paper, deep ink, one teal accent. Flat fills only; no gradients. */
|
||||
|
||||
@layer base {
|
||||
@@ -379,6 +379,29 @@
|
||||
border-color: var(--brand);
|
||||
}
|
||||
|
||||
.header-attribution {
|
||||
display: inline-flex;
|
||||
gap: 0.4rem;
|
||||
align-items: center;
|
||||
min-height: 44px;
|
||||
padding: 0 0.6rem;
|
||||
color: var(--muted-copy);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.header-attribution img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.header-attribution:hover {
|
||||
color: var(--brand-dark);
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
@@ -1479,6 +1502,17 @@
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.footer-attribution {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.footer-attribution img {
|
||||
display: block;
|
||||
width: 96px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* ---------- Interior pages ---------- */
|
||||
|
||||
.page-main {
|
||||
@@ -1929,6 +1963,12 @@ nextjs-portal {
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 920px) {
|
||||
.header-attribution span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 921px) {
|
||||
.nav-links {
|
||||
display: flex;
|
||||
|
||||