Node scripts that build a content site and a city directory out of JSON files
This is the code that runs blackfoxvr.com, packaged so you can run it on your own domain. About 850 lines of Node (ES modules, one npm dependency) plus five small PHP files, every one of them optional: a stats collector, its beacon, a private dashboard, a link redirector and a Telegram cron poster. You feed it JSON, it writes plain HTML, a sitemap, an Atom feed and a social image. No CMS, no database, no build framework, no admin panel.
What it actually is
A set of command line scripts, not a product with a UI. You run node tools/new-article.mjs article.json and a finished HTML page appears, linked from the homepage, listed in the sitemap and the feed, with its own OG image. Branding, navigation, footer lines, labels and folder names come from one settings file, tools/content/site-config.json. Markup lives in the template scripts, which you edit as JavaScript. That is the whole model.
- One command publishes an article. Page HTML with OG tags, JSON-LD (Article, BreadcrumbList, FAQPage), a table of contents with anchor links, an FAQ section, an analytics beacon. Plus the card on the homepage, the sitemap entry, the feed entry and the OG image.
- One JSON array builds a directory section. A hub page and one page per city, with cards, phone and site buttons, ItemList JSON-LD, and a per record status so unverified entries are labelled as unverified instead of quietly pretending to be facts.
- A validator you run before deploying. It walks every page on the site and fails on a missing canonical, missing OG tags, a stale CSS version query, an OG image referenced but absent from disk, or an article missing from the sitemap, the feed or the homepage.
- One command builds the static pages. Home page, about page and privacy page come from
tools/content/pages.json, so you do not hand write the shell of the site. By default the generator skips files that already exist, because the home page collects article cards and overwriting it would wipe them. - Five PHP files, all optional. Cookieless traffic stats (collector, beacon, private dashboard), a click counting redirector for outbound and affiliate links, and Telegram autoposting on cron. The site publishes fine without any of them.
Output is static files. Any shared host with Apache or LiteSpeed works, and the included .htaccess handles canonical redirects, cache policy and security headers.
What each script does
| File | Size | Job |
|---|---|---|
new-article.mjs | ~110 lines | Reads an article JSON, writes the page, inserts the homepage card, then triggers the OG, sitemap and feed generators. --check runs the whole site validator. |
build-article.mjs | ~80 lines | The article template itself, as a template literal. This is where you change markup and class names; headings and labels come from the settings file. |
build-pages.mjs | ~100 lines | The static page template: home page, about, privacy and anything else you list in content/pages.json. Skips existing files unless you pass --force. |
build-clubs.mjs | ~190 lines | The directory generator: hub page, one page per city, card rendering, structured data, source and status fields per record. City names and slugs live in content/cities.json, not in the code. |
og-generate.mjs | ~120 lines | 1200x630 social images. Composes an SVG (gradient background, brand mark, tag line, title wrapped and auto shrunk to fit) and rasterizes it with resvg. |
build-sitemap.mjsbuild-feed.mjs | ~35 + ~45 | Sitemap and Atom feed built from the files actually on disk and the JSON-LD inside them, so they cannot drift from reality. |
check-clubs-links.mjs | ~35 lines | Requests every external link in the directory and prints the dead ones. |
site-lib.mjs | ~140 lines | Shared helpers: loads content/site-config.json, builds the header and footer, slugify with a transliteration table, the OG block, the three JSON-LD builders, page read and write. |
lib/tg-post.php | PHP, cron | Posts to a Telegram channel. A queue of .txt files published in name order and moved to a sent folder. When the queue empties it rotates evergreen articles in a loop from a state file, so the channel never goes silent. At two posts remaining it emails you once a day. |
lib/stats.php + t.php + stats.php | PHP | Page views and funnel events. Uniques are stored as sha1(date + IP + user agent), which rotates daily and cannot be turned back into an IP. One JSON file per day, obvious bots filtered, private dashboard behind a key. |
r.php | PHP | Outbound link redirector for affiliate and campaign links. Targets are a whitelist in data/offers.json, every click is counted as an event, and the referrer is stripped on the way out. |
Line counts are rounded and move a little with every edit. Nine Node scripts, about 850 lines in total, plus the PHP files.
Who it is for, and who should not buy it
Buy it if:
- You are comfortable running
node script.mjsand editing a JavaScript template literal. - You want a niche content site, a local directory, or both on the same domain.
- You would rather own a folder of small scripts you can read in one evening than maintain a CMS, its plugins and its update treadmill.
- You host on a cheap shared plan and want pages that need no cache layer, because there is nothing dynamic to cache.
Do not buy it if:
- You want a drag and drop admin panel or a WYSIWYG editor. There is none, and adding one is not on any roadmap.
- You have non technical authors who need to publish without you.
- You need comments, user accounts, site search, ecommerce, memberships or a theme marketplace.
- You expect it to write content. It does not generate a single sentence. You bring the JSON.
- You have never run a script from a terminal. It will be a frustrating evening. Skip it.
What is in the zip, and what you will have to edit
Included:
- The
tools/folder: nine generators and the shared library, unminified and commented, pluscontent/site-config.json, the single settings file all of them read. - The static page generator with
content/pages.json, so the home page, the about page and the privacy page are generated instead of hand written. content/cities.json: the directory city list, kept out of the code, so adding a city is one line of JSON.- The PHP side:
t.php,r.php,stats.php,lib/stats.php,lib/tg-post.php, andlib/tg-config.phpfilled with placeholders. - The site skeleton you upload: the dark theme stylesheet, the favicon,
robots.txt,.htaccesswith the canonical redirect, cache rules and security headers, and the empty folders the scripts write into. - Six example JSON files: an article, a directory dataset, the settings file, the pages file, the cities file, the redirector whitelist. Demo data with every field filled in, not lorem ipsum, so
npm run setupgives you a working site on the first run. - Docs: a README in English and the same README in Ukrainian (article JSON schema, publish flow, cron line),
DEPLOY.md,HOSTING.mdand the license.
Not included, so there are no surprises: the articles and the real 53 record directory of blackfoxvr.com. That is content, and it stays with the site that wrote it. The demo dataset in the zip is six invented records in English, enough to show the shape and to make the generator run.
Honest list of what you will hit in the first hour:
- The directory wording is still inside its script. Nav labels, footer lines, the contents heading, the FAQ heading and the article labels all come from the settings file, but the directory pages keep their Ukrainian sentences in
build-clubs.mjs: the two section headings, the card buttons, the owner call to action. You translate about a dozen strings once, then never again. - The slug helper transliterates Cyrillic. Latin text passes through untouched, but the table is there, and it is fifteen lines if you want to replace it.
- OG images need two TTF fonts. The generator looks in
tools/fonts/first (brand-bold.ttfandbrand-regular.ttf), then falls back to the usual Windows, macOS and Linux system paths. On a bare Linux box with no fonts installed it stops with a clear message instead of drawing blank cards: drop two TTF files intotools/fonts/and run it again. - One settings file, not a theme system.
tools/content/site-config.jsonholds the origin, site name, logo markup, language and locale, contact email, Telegram link, the CSS version query, the two folder names, the nav, every footer line, the article labels and byline, the directory headings and tips, the OG card list, the static pages of the sitemap, and which validator checks are on. Design itself still lives in the templates and one stylesheet. - Requirements: Node 20.11 or newer (the scripts use
import.meta.dirname) andnpm installfor the single image package. Apache or LiteSpeed for the bundled.htaccess. PHP 8 and cron only if you want the Telegram poster and the stats. - Page weight is roughly 17 to 20 KB of HTML including inline JSON-LD. Small, not microscopic. Anyone advertising 2 KB pages with structured data is rounding creatively.
Live proof: the site you are reading
blackfoxvr.com is not a demo build. It is the production site, running this exact code, and every number below comes from it.
- 21 articles, each with structured data, a generated table of contents and an FAQ block.
- A venue directory: 53 records across 17 city pages, generated from a single JSON file. 36 records verified against a live source, 17 marked unverified on the page, because that is what the data supports.
- An OG image for every page, an Atom feed and a sitemap, all regenerated automatically on publish.
- No database query and no cache plugin between the request and the response: Apache hands over a file that was written at publish time. We are not quoting you a benchmark number, because your host and your visitors are not ours. Measure it yourself, the page you are reading is the production site.
- Six security headers set by the included
.htaccessand nothing else: HSTS, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy. - A Telegram channel that has posted three times a week on cron since July 2026 without anyone opening a terminal.
What this is not proof of: traffic. The site launched in July 2026 and its search numbers are still small. Buy the engine because the publishing workflow saves you an hour per article, not because someone showed you a graph.
Price, license, support
- $39, once. No subscription, no license key, no phone home, no seat count.
- License: use it on as many sites as you own or build for clients. Do not resell the scripts themselves as a product.
- Updates: you get the files as they exist today. If I improve something meaningful, buyers get an email with the new zip. I am not promising a roadmap I might not keep.
- Support: email admin@blackfoxvr.com. One person, usually a reply within a day or two. I will help you get the scripts running. I will not build your site for you at this price.
- Refund: within 14 days, ask and you get it back. If the scripts do not run on your machine and I cannot fix that, the refund is the right outcome and I would rather hear about the bug.
One zip: the Node generators, the PHP cron and stats scripts, the site skeleton with the stylesheet and the .htaccess, six example JSON files, and a README in English and Ukrainian. Full source, no subscription. Honest about the checkout: there is no instant download yet. You email us, we send payment details (bank transfer or USDT), and the zip goes back to you by email once the payment lands, usually the same day. Card checkout opens in August 2026, when the paperwork is done. Refund within 14 days if it does not work for you.
Get the engine, $39