diff --git a/src/App.tsx b/src/App.tsx
index 788c65d..1753251 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -61,7 +61,10 @@ function App() {
element={}
/>
)}
- } />
+ {/* Stats page route - only enabled when statsPage.enabled is true */}
+ {siteConfig.statsPage?.enabled && (
+ } />
+ )}
{/* Unsubscribe route for newsletter */}
} />
{/* Blog page route - only enabled when blogPage.enabled is true */}
diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx
index bb6a34f..6407cea 100644
--- a/src/components/Layout.tsx
+++ b/src/components/Layout.tsx
@@ -104,6 +104,10 @@ export default function Layout({ children }: LayoutProps) {
// Add hardcoded nav items (React routes like /stats, /write)
if (siteConfig.hardcodedNavItems && siteConfig.hardcodedNavItems.length > 0) {
siteConfig.hardcodedNavItems.forEach((item) => {
+ // Skip stats nav item if stats page is disabled
+ if (item.slug === "stats" && !siteConfig.statsPage?.enabled) {
+ return;
+ }
// Only add if showInNav is true (defaults to true)
if (item.showInNav !== false) {
navItems.push({
diff --git a/src/config/siteConfig.ts b/src/config/siteConfig.ts
index 469cdd3..7d84981 100644
--- a/src/config/siteConfig.ts
+++ b/src/config/siteConfig.ts
@@ -154,6 +154,13 @@ export interface NewsletterAdminConfig {
showInNav: boolean; // Show link in navigation (hidden by default for security)
}
+// Stats page configuration
+// Controls access to the /stats route for viewing site analytics
+export interface StatsPageConfig {
+ enabled: boolean; // Global toggle for stats page
+ showInNav: boolean; // Show link in navigation (controlled via hardcodedNavItems)
+}
+
// Newsletter notifications configuration
// Sends developer notifications for subscriber events
// Uses AGENTMAIL_CONTACT_EMAIL or AGENTMAIL_INBOX as recipient
@@ -284,6 +291,9 @@ export interface SiteConfig {
// Newsletter admin configuration (optional)
newsletterAdmin?: NewsletterAdminConfig;
+ // Stats page configuration (optional)
+ statsPage?: StatsPageConfig;
+
// Newsletter notifications configuration (optional)
newsletterNotifications?: NewsletterNotificationsConfig;
@@ -558,6 +568,14 @@ Created by [Wayne](https://x.com/waynesutton) with Convex, Cursor, and Claude Op
showInNav: false, // Hide from navigation for security
},
+ // Stats page configuration
+ // Controls access to the /stats route for viewing site analytics
+ // Set enabled: false to make stats page private (route still accessible but shows disabled message)
+ statsPage: {
+ enabled: true, // Global toggle for stats page
+ showInNav: true, // Show link in navigation (also controlled via hardcodedNavItems)
+ },
+
// Newsletter notifications configuration
// Sends developer notifications for subscriber events via AgentMail
newsletterNotifications: {
diff --git a/src/pages/Stats.tsx b/src/pages/Stats.tsx
index 1fd1a2a..f082be8 100644
--- a/src/pages/Stats.tsx
+++ b/src/pages/Stats.tsx
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
import { useQuery } from "convex/react";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, Link } from "react-router-dom";
import { api } from "../../convex/_generated/api";
import {
ArrowLeft,
@@ -37,6 +37,42 @@ export default function Stats() {
const navigate = useNavigate();
const stats = useQuery(api.stats.getStats);
+ // Check if stats page is enabled
+ if (!siteConfig.statsPage?.enabled) {
+ return (
+
+
+
+ Site Statistics
+
+
+ Stats page is disabled in site configuration.
+
+
+ Back to Home
+
+
+
+ );
+ }
+
// GitHub stars state
const [githubStars, setGithubStars] = useState(null);