Add SEO: sitemap.xml, robots.txt, meta tags + structured data

- sitemap.xml (homepage) + robots.txt (allow crawl, disallow /api/, link sitemap)
- <head>: SEO title, meta description, keywords, canonical, robots
- Open Graph + Twitter Card tags for link previews
- JSON-LD WebApplication structured data (features, free, publisher)
- <noscript> crawlable content so the JS-rendered SPA has indexable text
- SW cache v11

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
King Omar 2026-07-22 19:50:35 +10:00
parent e075629d4d
commit 5d41ed72f4
4 changed files with 83 additions and 3 deletions

View file

@ -4,7 +4,52 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="theme-color" content="#0B0B09" />
<title>Cipher — a Radical Party project</title>
<title>Cipher — Free End-to-End Encrypted Messenger | Private Chat, Calls &amp; Groups</title>
<meta name="description" content="Cipher is a free, private, end-to-end encrypted messenger. Signal-grade encrypted 1:1 and group chats, voice &amp; video calls, and disappearing messages — your keys never leave your device. No phone number required." />
<meta name="keywords" content="encrypted messenger, end-to-end encryption, private messaging, secure chat, encrypted calls, disappearing messages, Signal alternative, WhatsApp alternative, E2E encryption, private group chat" />
<meta name="author" content="Radical Party" />
<meta name="robots" content="index, follow, max-image-preview:large" />
<link rel="canonical" href="https://cipher.theradicalparty.com/" />
<!-- Open Graph / social -->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Cipher" />
<meta property="og:title" content="Cipher — Free End-to-End Encrypted Messenger" />
<meta property="og:description" content="Private, end-to-end encrypted chats, groups, and voice &amp; video calls. Your keys never leave your device. No phone number required." />
<meta property="og:url" content="https://cipher.theradicalparty.com/" />
<meta property="og:image" content="https://cipher.theradicalparty.com/icons/icon.svg" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Cipher — Free End-to-End Encrypted Messenger" />
<meta name="twitter:description" content="Private, end-to-end encrypted chats, groups, and voice &amp; video calls. Your keys never leave your device." />
<meta name="twitter:image" content="https://cipher.theradicalparty.com/icons/icon.svg" />
<!-- Structured data: helps Google understand this is a messaging web app -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "Cipher",
"url": "https://cipher.theradicalparty.com/",
"applicationCategory": "CommunicationApplication",
"operatingSystem": "Web, iOS, Android, Windows, macOS, Linux",
"browserRequirements": "Requires JavaScript. Requires a modern browser.",
"description": "Cipher is a free, end-to-end encrypted messenger with private 1:1 and group chats, encrypted voice and video calls, and disappearing messages. Private keys are generated on-device and never sent to the server.",
"isAccessibleForFree": true,
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"featureList": [
"End-to-end encryption (Signal Protocol)",
"Private one-to-one and group chats",
"Encrypted voice and video calls",
"Disappearing messages",
"Read receipts",
"Group invite links",
"Multi-device with QR linking",
"No phone number required"
],
"publisher": { "@type": "Organization", "name": "Radical Party" }
}
</script>
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="icon" href="/icons/icon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/icons/icon.svg" />
@ -267,7 +312,26 @@
</style>
</head>
<body>
<div id="app"></div>
<div id="app">
<!-- Server-visible content for crawlers / no-JS. The real app hydrates over this. -->
<noscript>
<h1>Cipher — Free End-to-End Encrypted Messenger</h1>
<p>Cipher is a free, private messenger with end-to-end encryption built on the
Signal Protocol. Chat one-to-one or in groups, make encrypted voice and video
calls, and send disappearing messages. Your private keys are generated on your
device and never leave it — the server only ever relays ciphertext.</p>
<h2>Features</h2>
<ul>
<li>End-to-end encrypted 1:1 and group chats</li>
<li>Encrypted voice and video calls</li>
<li>Disappearing messages and read receipts</li>
<li>Shareable group invite links</li>
<li>Multi-device sync with QR linking</li>
<li>No phone number required</li>
</ul>
<p>Cipher requires JavaScript. Please enable it to sign in or create an account.</p>
</noscript>
</div>
<script type="module" src="/js/app.js"></script>
</body>
</html>

7
public/robots.txt Normal file
View file

@ -0,0 +1,7 @@
# Cipher — allow crawling of the public app shell; keep the API out of the index.
# JS/CSS are intentionally crawlable so Google can render the single-page app.
User-agent: *
Allow: /
Disallow: /api/
Sitemap: https://cipher.theradicalparty.com/sitemap.xml

9
public/sitemap.xml Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://cipher.theradicalparty.com/</loc>
<lastmod>2026-07-22</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
</urlset>

View file

@ -1,7 +1,7 @@
// Service worker: offline app shell + Web Push wake-up.
// It never touches message plaintext — decryption happens only in the page.
const CACHE = "cipher-v10";
const CACHE = "cipher-v11";
const SHELL = [
"/",
"/index.html",