Mehboob Khan 7ed6a51d9f
Some checks are pending
CI / build (push) Waiting to run
Rewrite page copy across the site, fix nav/blog polish, resize SDK explorer
Restores and rewrites content on Home, Mobile SDK, DNS Protect, Halo CPE,
For Operators, Financial Services, Why BlackDice, Investors and Contact to
match the approved source copy, removing stray dashes site-wide in favour
of plain punctuation. Removes an unreachable duplicate Contact page block
that left a stray unclosed <div> in the markup. Shrinks and repads the
Guardian Mobile SDK explorer widget so it fits without excess scrolling.
Also includes in-progress nav, blog seed and demo scenario tweaks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 05:31:37 +05:00

BlackDice Cyber — Website + Studio (React + TypeScript)

The BlackDice marketing site as a Vite + React + TypeScript app, with BlackDice Studio — the CMS — built in at a single admin route, and the BlackDice Angel product demos embedded as real React components.

npm install
npm run dev        # site on http://localhost:5173, CMS API on http://localhost:8787
npm run build      # production build → dist/
npm start          # serve dist/ + the CMS API from one Node process (port 8787)

Documentation

Doc Audience Covers
docs/ARCHITECTURE.md Developers How the system works: content flow, the CMS hook system, routing, the API server, resilience, threat model
docs/PROJECT-STRUCTURE.md Developers Directory-by-directory reference; "where do I make this change" table
docs/CMS-GUIDE.md Editors (Paul, Mark, Campbell) How to use Studio — editing pages, publishing articles, demos, SEO
docs/DEPLOYMENT.md Ops Environment variables, hosting (Node/nginx/IIS/Docker/static), backups, release checklist
CHANGELOG.md Everyone What changed in the CMS rebuild and why

Why the old studio kept wiping the site

blackdice-studio.html worked by exporting HTML: saving cloned the live DOM into a new index.html and rebuilt blog.html from a template. Anything edited in those files by hand — the contact-form links, SEO tags, routing tweaks — was overwritten by the next export, because the export was the source of truth.

Here, content and markup are separate:

Old studio This project
What "save" writes whole index.html + blog.html (27MB) one JSON document (~200KB)
Where copy lives inside the HTML content/site-content.json
Hand-made changes lost on next export untouched — they are in the code
Images base64 inside the HTML files under content/uploads/
Rollback manual file copies automatic snapshot per publish

Publishing can no longer overwrite anything a developer wrote, so Requirement 1 disappears by construction.


How content flows

Three layers, each overriding the one before:

  1. The buildsrc/site/siteMarkup.txt (the page markup) plus defaults in src/cms/pages.ts (routes, per-page SEO, demo slots).
  2. Factory contentsrc/cms/generated/seedContent.json, imported from the studio export. This is what the site shows before anything is published.
  3. Published contentcontent/site-content.json, written by /admin.

The site fetches layer 3 at load and merges it over 12 (src/cms/store.tsx). If the API is unreachable, the site still renders layers 12 rather than going blank.

What the CMS can change

Field type Hook in the markup Edited in
Copy (652 fields) data-cms="c0001" Pages tab — click the text on the page
Images data-cms-img="img001" Pages tab — click the image
Animated stats data-cms-num="n001" Pages tab — value + suffix
Articles Articles tab
Demo clips Demos tab
Titles, meta, form recipient SEO tab

Hooks are injected by a script, so re-running it after markup edits is safe — existing ids are preserved and only new elements get new ids:

npm run cms:ids

It also writes src/cms/generated/cmsFields.json, the field index the Studio uses to list and jump to every editable region.

Importing from the old studio

npm run cms:import -- "path/to/blackdice-studio.json"

Pulls in the post library, writes base64 heroes out as real files under public/content/posts/ (and downscales them — some originals were 8000px/12MB), and strips Word/Outlook formatting from article bodies. Studio drafts can also be imported at runtime from Studio → History → Import a file.

Posts authored in this repo rather than in the studio live in content-seed/additional-posts.json and survive re-imports.


What's inside

Path Purpose
src/main.tsx Router: one real route per page, /blog/:slug, /admin, demo routes
src/site/SiteApp.tsx Renders the site markup, applies CMS content, mounts the React islands, boots the ported controller
src/site/siteMarkup.txt Page markup with CMS hooks (imported as a raw string)
src/site/siteController.js Ported js/main.js: page switching, enquiry forms, live feed, count-ups
src/site/styles.css The original stylesheet + newsroom/article/demo styles
src/site/blog/ Newsroom grid and article pages
src/site/demos/ Demo section (Mobile SDK) and clip players (Halo CPE)
src/cms/ Content model, API client, store, SEO helpers, sanitiser
src/cms/admin/ BlackDice Studio — the /admin app
src/demo/ The BlackDice Angel demo (cinematic player + interactive flows + threat demos)
server/index.mjs Site + CMS server: auth, content, uploads, snapshots, leads, sitemap (no dependencies)
scripts/ inject-cms-ids, seed-content, generate-sitemap, resize-images, dev

Routes

Route What it is
/, /mobile-sdk, /dns-protect, /halo-cpe, /for-operators, /financial-services, /why-blackdice, /news, /investors, /contact, /cookie-policy, /privacy-policy The site — real, shareable, crawlable URLs
/blog/<slug> One page per article
/admin BlackDice Studio
/threat-demos, /threat-demo/:id Threat-detection demos (slider + single scenario)
/demo-video, /demo, /demo?mode=video Angel product video and interactive demo player
/sitemap.xml, /robots.txt Generated from live content by the server

Every route updates document.title, the meta description, canonical and OG tags, and pushes a HubSpot virtual pageview. Articles also emit BlogPosting JSON-LD; the home page emits Organization.

Deep links need an SPA fallback on the host. server/index.mjs does it out of the box; vercel.json, public/_redirects and public/web.config cover Vercel, Netlify and IIS.

Enquiry forms

Every "Talk to us", "Book a demonstration", "Request a demonstration" and mailto: link opens the enquiry form. On submit the details are POSTed to /api/leads (visible in Studio → Enquiries, exportable as CSV) and handed to the visitor's mail client addressed to settings.formRecipient (campbell.ferrier@blackdice.ai by default, changeable in the SEO tab).

Demos on the product pages

The Mobile SDK page carries a tabbed demo section — scam call (voice/VOIP), scam SMS, SIM swap, per-device DNS analytics (iOS and Android) and permissions checking. Each tab plays the clip uploaded in Studio → Demos if there is one, and otherwise plays the interactive demo built into this project, shown as the phone mockup with no surrounding frame. Halo CPE has slots for the Retina dashboard and Angel web UI walkthroughs, which appear under their screenshots once clips are uploaded.

CSS isolation

SiteApp, DemoScreen, DemoVideoPage and AdminApp are lazy-loaded as separate chunks, so the site's global styles.css only loads on site routes (and in the Studio, which previews the real site). The demo ships a scoped reset (src/demo/demo.css, applied via .bd-demo-root) that keeps the phone screens pixel-faithful to the original prototype. Studio styles are all prefixed .bdcms-.

Notes

  • Fonts (Ubuntu / Ubuntu Mono) load from Google Fonts via index.html.
  • The site markup is rendered with dangerouslySetInnerHTML; its inline handlers resolve to the globals registered by siteController.js, and React features are portalled into named mount points inside it.
  • standalone.html is the old single-file build, kept for reference only.
Description
No description provided
Readme 7 MiB
Languages
HTML 68.9%
TypeScript 22.2%
CSS 5.1%
JavaScript 3.8%