fix(web): link the fork's own source host and drop the upstream star count

The header badge fetched the star count of VocaHQ/vocalinux at build time
and labelled it as Voculinux's. The fetch and the count are gone; the
header, footer and social "source" links now go to the fork repository at
git.bongbetic.com/xavierk/voculinux, as do the issue links, the docs
anchors, the home page JSON-LD and the xbps release card.

Upstream GitHub stays only where it is the real artefact or provenance and
is labelled as such: the install script, the AppImage release card, the
upstream card and the changelog release links. The changelog now says its
entries are upstream history, the open-source page no longer claims
VocaHQ membership or an active GitHub community, and the organization
JSON-LD drops the upstream author as founder. DESIGN.md and PRODUCT.md
follow.
This commit is contained in:
2026-11-06 18:22:17 +05:30
parent a2736ee6e4
commit c9be45d3c3
16 changed files with 97 additions and 114 deletions
+12 -3
View File
@@ -11,7 +11,11 @@ import {
Zap,
} from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
import {
absoluteUrl,
buildPageMetadata,
UPSTREAM_REPO_URL,
} from "@/lib/seo";
const releases = [
{
@@ -574,6 +578,11 @@ export default function ChangelogPage() {
Track every release and see how Voculinux has evolved. From initial
alpha to stable releases, follow the journey of Linux voice dictation.
</p>
<p className="mb-8 max-w-4xl text-sm text-muted-foreground">
Fork status: the releases below are the upstream Vocalinux history
this fork is ported from. Voculinux fork releases are not published
yet, so each release link goes to upstream GitHub Releases.
</p>
</section>
<section className="space-y-6">
@@ -644,13 +653,13 @@ export default function ChangelogPage() {
<div className="mt-4 border-t border-border pt-4">
<a
href={`https://github.com/VocaHQ/vocalinux/releases/tag/${release.version}`}
href={`${UPSTREAM_REPO_URL}/releases/tag/${release.version}`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline"
>
<Download className="h-4 w-4" />
View release on GitHub
View upstream release on GitHub
<ChevronRight className="h-4 w-4" />
</a>
</div>
+3 -3
View File
@@ -12,7 +12,7 @@ import {
Zap,
} from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { buildPageMetadata } from "@/lib/seo";
import { buildPageMetadata, SOURCE_REPO_URL } from "@/lib/seo";
const faqCategories = [
{
@@ -239,12 +239,12 @@ export default function FaqPage() {
<span className="inline-flex items-center gap-2">
<ChevronRight className="h-4 w-4 text-primary" />
<a
href="https://github.com/VocaHQ/vocalinux/issues"
href={`${SOURCE_REPO_URL}/issues`}
target="_blank"
rel="noopener noreferrer"
className="font-semibold text-primary hover:underline"
>
Open an issue on GitHub
Open an issue in the Voculinux repository
</a>
</span>
</li>
+10 -6
View File
@@ -3,7 +3,11 @@ import { type Metadata } from "next";
import { ChevronRight, Cpu, Laptop, Terminal } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { TerminalBlock } from "@/components/terminal-block";
import { buildPageMetadata } from "@/lib/seo";
import {
buildPageMetadata,
SOURCE_REPO_URL,
UPSTREAM_REPO_URL,
} from "@/lib/seo";
const installCommand =
"curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh --interactive";
@@ -116,7 +120,7 @@ export default function InstallGuidesPage() {
<div className="install-alts">
<a
className="install-alt"
href="https://github.com/VocaHQ/vocalinux/releases"
href={`${UPSTREAM_REPO_URL}/releases`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">No installer</p>
@@ -128,7 +132,7 @@ export default function InstallGuidesPage() {
</a>
<a
className="install-alt"
href="https://github.com/VocaHQ/vocalinux/blob/main/docs/INSTALL.md#distro-packages-deb--rpm"
href={`${SOURCE_REPO_URL}/src/branch/main/docs/INSTALL.md#distro-packages-deb--rpm`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">New</p>
@@ -174,14 +178,14 @@ export default function InstallGuidesPage() {
</a>
<a
className="install-alt"
href="https://github.com/VocaHQ/vocalinux/blob/main/docs/INSTALL.md#from-source"
href={`${SOURCE_REPO_URL}/src/branch/main/docs/INSTALL.md#from-source`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">From source</p>
<h2>Build it yourself</h2>
<p>
Clone the repo and run <code>./install.sh</code>. The upstream
install guide has the full source path.
Clone the repo and run <code>./install.sh</code>. The install
guide in the Voculinux repository has the full source path.
</p>
</a>
</div>
+3 -8
View File
@@ -6,7 +6,7 @@ import {
absoluteUrl,
DEFAULT_OG_IMAGE_ALT,
DEFAULT_OG_IMAGE_PATH,
GITHUB_REPO_URL,
SOURCE_REPO_URL,
SITE_NAME,
SITE_URL,
TWITTER_HANDLE,
@@ -128,12 +128,7 @@ const organizationJsonLd = {
url: absoluteUrl("/"),
logo: absoluteUrl("/voculinux.png"),
description: "Open-source, offline voice dictation software for Linux.",
sameAs: [GITHUB_REPO_URL, "https://bongbetic.com"],
founder: {
"@type": "Person",
name: "Jatin K Malik",
url: "https://github.com/jatinkrmalik",
},
sameAs: [SOURCE_REPO_URL, "https://bongbetic.com"],
};
const webSiteJsonLd = {
@@ -152,7 +147,7 @@ const webSiteJsonLd = {
"@type": "SearchAction",
target: {
"@type": "EntryPoint",
urlTemplate: `${GITHUB_REPO_URL}/issues?q={search_term_string}`,
urlTemplate: `${SOURCE_REPO_URL}/issues?q={search_term_string}`,
},
"query-input": {
"@type": "PropertyValueSpecification",
+4 -4
View File
@@ -11,7 +11,7 @@ import {
XCircle,
} from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
import { absoluteUrl, buildPageMetadata, SOURCE_REPO_URL } from "@/lib/seo";
const benefits = [
{
@@ -252,14 +252,14 @@ export default function OfflinePage() {
<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" />
Read every line of code on{" "}
Read every line of code in the{" "}
<a
href="https://github.com/VocaHQ/vocalinux"
href={SOURCE_REPO_URL}
target="_blank"
rel="noopener noreferrer"
className="font-semibold hover:underline"
>
GitHub
Voculinux repository
</a>
</li>
<li className="flex items-start gap-2">
+8 -8
View File
@@ -14,7 +14,7 @@ import {
Zap,
} from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
import { absoluteUrl, buildPageMetadata, SOURCE_REPO_URL } from "@/lib/seo";
const benefits = [
{
@@ -58,7 +58,7 @@ const vsProprietary = [
{ 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" },
{ feature: "Community Support", voculinux: "Public issue tracker", proprietary: "Paid support only" },
];
const techStack = [
@@ -87,7 +87,7 @@ const techStack = [
export const metadata: Metadata = buildPageMetadata({
title: "Open Source Dictation Software for Linux (AGPL-3.0)",
description:
"Free, open source dictation software for Linux under AGPL-3.0. Offline speech recognition with whisper.cpp or VOSK, no required account, all code on GitHub.",
"Free, open source dictation software for Linux under AGPL-3.0. Offline speech recognition with whisper.cpp or VOSK, no required account, all code in the public repository.",
path: "/open-source",
keywords: [
"open source voice dictation",
@@ -141,14 +141,14 @@ export default function OpenSourcePage() {
Free & Open Source Voice Dictation
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Voculinux is 100% open source under the AGPL-3.0 license, and part of{" "}
Voculinux is 100% open source under the AGPL-3.0 license, a hard fork of{" "}
<a
href="https://vocahq.com"
href="https://github.com/VocaHQ/vocalinux"
target="_blank"
rel="noopener noreferrer"
className="font-medium text-primary hover:underline"
>
VocaHQ
Vocalinux (upstream, by VocaHQ)
</a>
. No subscriptions, no vendor lock-in, no hidden costs. Local engines keep
audio on the machine. Remote API is optional.
@@ -289,13 +289,13 @@ export default function OpenSourcePage() {
translations - join the community.
</p>
<a
href="https://github.com/VocaHQ/vocalinux"
href={SOURCE_REPO_URL}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 rounded-full border border-border bg-background px-4 py-2 text-sm font-semibold text-foreground hover:bg-muted"
>
<Zap className="h-4 w-4" />
View on GitHub
View the Voculinux source
</a>
</div>
</div>
+21 -19
View File
@@ -5,20 +5,22 @@ import Link from "next/link";
import Image from "next/image";
import { SiteChrome } from "@/components/site-chrome";
import { TerminalBlock, TerminalPrompt } from "@/components/terminal-block";
import { GITHUB_REPO_URL } from "@/lib/seo";
import { SOURCE_REPO_URL, UPSTREAM_REPO_URL } from "@/lib/seo";
const GITHUB_REPO_PATH = GITHUB_REPO_URL.replace("https://github.com/", "");
const GITHUB_RAW_BASE = `https://raw.githubusercontent.com/${GITHUB_REPO_PATH}`;
// The install and uninstall scripts below are fetched from upstream: the fork
// has no published raw script host yet. The install section labels this.
const UPSTREAM_REPO_PATH = UPSTREAM_REPO_URL.replace("https://github.com/", "");
const UPSTREAM_RAW_BASE = `https://raw.githubusercontent.com/${UPSTREAM_REPO_PATH}`;
const installCommands = {
interactiveInstallCommand: `curl -fsSL ${GITHUB_RAW_BASE}/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh --interactive`,
interactiveInstallCommand: `curl -fsSL ${UPSTREAM_RAW_BASE}/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh --interactive`,
interactiveInstallDisplayCommand: `curl -fsSL \\
${GITHUB_RAW_BASE}/main/install.sh \\
${UPSTREAM_RAW_BASE}/main/install.sh \\
-o /tmp/vl.sh && \\
bash /tmp/vl.sh --interactive`,
uninstallCommand: `curl -fsSL ${GITHUB_RAW_BASE}/main/uninstall.sh -o /tmp/vul.sh && bash /tmp/vul.sh`,
uninstallCommand: `curl -fsSL ${UPSTREAM_RAW_BASE}/main/uninstall.sh -o /tmp/vul.sh && bash /tmp/vul.sh`,
uninstallDisplayCommand: `curl -fsSL \\
${GITHUB_RAW_BASE}/main/uninstall.sh \\
${UPSTREAM_RAW_BASE}/main/uninstall.sh \\
-o /tmp/vul.sh && \\
bash /tmp/vul.sh`,
};
@@ -32,7 +34,7 @@ const homeJsonLd = [
applicationCategory: "UtilitiesApplication",
operatingSystem: "Linux",
isAccessibleForFree: true,
license: `${GITHUB_REPO_URL}/blob/main/LICENSE`,
license: `${SOURCE_REPO_URL}/src/branch/main/LICENSE`,
offers: {
"@type": "Offer",
price: "0",
@@ -47,7 +49,7 @@ const homeJsonLd = [
url: "https://github.com/jatinkrmalik",
},
url: "https://voculinux.com/",
downloadUrl: GITHUB_REPO_URL,
downloadUrl: SOURCE_REPO_URL,
screenshot: "https://voculinux.com/og-image.png",
featureList: [
"Local speech recognition with whisper.cpp, Faster Whisper, Whisper, VOSK, and Parakeet",
@@ -305,7 +307,7 @@ export default function HomePage() {
</a>
<a
className="btn btn-secondary"
href={GITHUB_REPO_URL}
href={SOURCE_REPO_URL}
rel="noopener noreferrer"
>
View the source{" "}
@@ -759,7 +761,7 @@ export default function HomePage() {
<div className="install-alts">
<a
className="install-alt"
href={`${GITHUB_REPO_URL}/releases`}
href={`${SOURCE_REPO_URL}/releases`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">Void Linux</p>
@@ -772,7 +774,7 @@ export default function HomePage() {
</a>
<a
className="install-alt"
href={`${GITHUB_REPO_URL}/releases`}
href={`${UPSTREAM_REPO_URL}/releases`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">No installer</p>
@@ -784,7 +786,7 @@ export default function HomePage() {
</a>
<a
className="install-alt"
href={`${GITHUB_REPO_URL}/blob/main/docs/INSTALL.md#distro-packages-deb--rpm`}
href={`${SOURCE_REPO_URL}/src/branch/main/docs/INSTALL.md#distro-packages-deb--rpm`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">New</p>
@@ -796,7 +798,7 @@ export default function HomePage() {
</a>
<a
className="install-alt"
href={`${GITHUB_REPO_URL}/blob/main/docs/INSTALL.md#flatpak`}
href={`${SOURCE_REPO_URL}/src/branch/main/docs/INSTALL.md#flatpak`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">Auto-updates</p>
@@ -834,14 +836,14 @@ export default function HomePage() {
</a>
<a
className="install-alt"
href={`${GITHUB_REPO_URL}/blob/main/docs/INSTALL.md#from-source`}
href={`${SOURCE_REPO_URL}/src/branch/main/docs/INSTALL.md#from-source`}
rel="noopener noreferrer"
>
<p className="install-alt-kicker">From source</p>
<h3>Build it yourself</h3>
<p>
Clone the repo and run <code>./install.sh</code>. The upstream
install guide has the full source path.
Clone the repo and run <code>./install.sh</code>. The install
guide in the Voculinux repository has the full source path.
</p>
</a>
</div>
@@ -1016,7 +1018,7 @@ export default function HomePage() {
</div>
<a
className="family-card"
href={GITHUB_REPO_URL}
href={UPSTREAM_REPO_URL}
rel="noopener noreferrer"
>
<div className="family-card-top">
@@ -1081,7 +1083,7 @@ export default function HomePage() {
</a>
<a
className="btn btn-secondary"
href={GITHUB_REPO_URL}
href={SOURCE_REPO_URL}
rel="noopener noreferrer"
>
View the source
+5 -5
View File
@@ -2,7 +2,7 @@ import Link from "next/link";
import { type Metadata } from "next";
import { CheckCircle2, Lock, Server, Shield, Eye, Database, ExternalLink } from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
import { absoluteUrl, buildPageMetadata, SOURCE_REPO_URL } from "@/lib/seo";
export const metadata: Metadata = buildPageMetadata({
title: "Privacy Policy - Local Voice Dictation",
@@ -92,8 +92,8 @@ export default function PrivacyPage() {
</div>
<h2 className="subpage-card-title mb-2 text-xl font-semibold">Open Source</h2>
<p className="text-sm text-muted-foreground">
Fully open source under AGPL-3.0. Inspect the code yourself on GitHub. The installed
app does not send usage telemetry.
Fully open source under AGPL-3.0. Inspect the code yourself in the Voculinux source
repository. The installed app does not send usage telemetry.
</p>
</article>
</section>
@@ -283,12 +283,12 @@ export default function PrivacyPage() {
please reach out:
</p>
<a
href="https://github.com/VocaHQ/vocalinux/issues"
href={`${SOURCE_REPO_URL}/issues`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-primary hover:underline"
>
Open an issue on GitHub
Open an issue in the Voculinux repository
<ExternalLink className="h-4 w-4" />
</a>
</section>
+5 -5
View File
@@ -10,7 +10,7 @@ import {
Wrench,
} from "lucide-react";
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
import { absoluteUrl, buildPageMetadata, SOURCE_REPO_URL } from "@/lib/seo";
const troubleshootingItems = [
{
@@ -221,7 +221,7 @@ export default function TroubleshootingPage() {
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Having issues with Voculinux? Find solutions to common problems below.
Can't find your issue? Open a GitHub issue for help.
Can't find your issue? Open an issue in the Voculinux repository for help.
</p>
</section>
@@ -320,12 +320,12 @@ export default function TroubleshootingPage() {
<ChevronRight className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
<span>
<a
href="https://github.com/VocaHQ/vocalinux/issues"
href={`${SOURCE_REPO_URL}/issues`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
>
Search existing issues on GitHub
Search existing issues in the Voculinux repository
<ExternalLink className="h-3.5 w-3.5" />
</a>
</span>
@@ -334,7 +334,7 @@ export default function TroubleshootingPage() {
<ChevronRight className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
<span>
<a
href="https://github.com/VocaHQ/vocalinux/issues/new"
href={`${SOURCE_REPO_URL}/issues/new`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
+7 -17
View File
@@ -2,9 +2,9 @@
import React, { useEffect, useId, useState } from "react";
import Link from "next/link";
import { Star } from "lucide-react";
import { Code } from "lucide-react";
import { VoculinuxLogo } from "@/components/optimized-image";
import { GITHUB_REPO_URL } from "@/lib/seo";
import { SOURCE_REPO_URL } from "@/lib/seo";
import {
footerGroups,
homeNav,
@@ -14,10 +14,6 @@ import {
type NavLink,
} from "@/lib/site-nav";
// Star count is fetched once at build time (next.config.js) so visitors never
// call api.github.com. Empty or missing falls back to the "GitHub" label.
const GITHUB_STARS = Number(process.env.NEXT_PUBLIC_GITHUB_STARS) || null;
function SmartLink({
href,
className,
@@ -65,7 +61,6 @@ export function SiteChrome({
variant?: "home" | "page";
}) {
const [open, setOpen] = useState(false);
const stars = GITHUB_STARS;
const navId = useId();
const nav = variant === "home" ? homeNav : pageNav;
const ctaHref = variant === "home" ? "#install" : "/#install";
@@ -141,22 +136,17 @@ export function SiteChrome({
<div className="header-actions">
<a
className="header-stars"
href={GITHUB_REPO_URL}
className="header-source"
href={SOURCE_REPO_URL}
rel="noopener noreferrer"
aria-label={
stars !== null
? `Voculinux on GitHub, ${stars.toLocaleString("en-US")} stars`
: "Voculinux on GitHub"
}
aria-label="Voculinux source repository"
>
<Star
<Code
className="h-4 w-4"
strokeWidth={1.75}
fill="currentColor"
aria-hidden="true"
/>
<span>{stars !== null ? stars.toLocaleString("en-US") : "GitHub"}</span>
<span>Source</span>
</a>
<button
className="nav-toggle"
+7 -1
View File
@@ -7,7 +7,13 @@ export const DEFAULT_OG_IMAGE_ALT =
"Dictate locally. In any app. Offline voice dictation for Linux.";
export const TWITTER_HANDLE = "@vocahq";
export const VOCAHQ_URL = "https://vocahq.com";
export const GITHUB_REPO_URL = "https://github.com/VocaHQ/vocalinux";
// The fork's own source, issue and release host. Everything that says "our
// source", "our issues" or "our releases" resolves here.
export const SOURCE_REPO_URL = "https://git.bongbetic.com/xavierk/voculinux";
// Upstream Vocalinux on GitHub. Retained only as labelled provenance (the
// upstream install script, the AppImage and packages published there, and the
// upstream release history behind the changelog).
export const UPSTREAM_REPO_URL = "https://github.com/VocaHQ/vocalinux";
export const X_URL = "https://x.com/vocahq";
export const DISCORD_URL = "https://discord.gg/t6muquAJbm";
export const EMAIL_URL = "mailto:hello@vocahq.com";
+7 -3
View File
@@ -1,7 +1,7 @@
import {
DISCORD_URL,
EMAIL_URL,
GITHUB_REPO_URL,
SOURCE_REPO_URL,
X_URL,
} from "@/lib/seo";
@@ -35,7 +35,11 @@ export const mobileExtraNav: NavLink[] = [
export const socialLinks: { href: string; label: string; icon: string }[] = [
{ href: X_URL, label: "X", icon: "/brand/social/x.svg" },
{ href: DISCORD_URL, label: "Discord", icon: "/brand/social/discord.svg" },
{ href: GITHUB_REPO_URL, label: "GitHub", icon: "/brand/social/github.svg" },
{
href: SOURCE_REPO_URL,
label: "Voculinux source repository",
icon: "/brand/social/github.svg",
},
{ href: EMAIL_URL, label: "Email hello@vocahq.com", icon: "/brand/social/mail.svg" },
];
@@ -102,7 +106,7 @@ export const footerGroups: { title: string; links: NavLink[] }[] = [
{ href: "/troubleshooting/", label: "Troubleshooting" },
{ href: "/privacy/", label: "Privacy" },
{ href: "/changelog/", label: "Changelog" },
{ href: GITHUB_REPO_URL, label: "Source" },
{ href: SOURCE_REPO_URL, label: "Source" },
{ href: "https://bongbetic.com", label: "Bongbetic" },
],
},
+2 -2
View File
@@ -357,7 +357,7 @@
margin-left: auto;
}
.header-stars {
.header-source {
display: inline-flex;
gap: 0.4rem;
align-items: center;
@@ -373,7 +373,7 @@
text-decoration: none;
}
.header-stars:hover {
.header-source:hover {
color: var(--brand-dark);
background: var(--brand-softer);
border-color: var(--brand);