Repository layout
A vanityURLs instance keeps product-owned files separate from instance-owned files. That is what makes npm run upgrade practical: upstream can refresh defaults/ and scripts/, while your links, branding, policy choices, and Cloudflare deployment settings stay under your control.
The public v8s.link repository follows this layout:
- package.jsonnpm scripts and dependencies
- package-lock.jsonlocked dependency graph
- wrangler.tomlCloudflare Worker deployment settings
- defaults/product baseline refreshed by upgrade
- public/default pages, assets, badges, status pages, and headers
- _headersstatic asset cache and no-index headers
- robots.txt
- v8s-style.css
- v8s-script.js
- v8s-lookup.js
- v8s-links.txtstarter link inventory and inline schedules
- v8s-policies.jsondefault trust-and-safety policy
- v8s-blocklist-categories.jsonpolicy category labels
- v8s-language-metadata.jsonlocalized generated-page labels
- legal/default generated legal and trust copy
- v8s-legal-content.json
- v8s-site-config.jsondefault languages, branding, and operator values
- v8s-local-config.jsondefault workstation helper settings
- custom/instance-owned overrides
- public/instance branding, pages, assets, and headers
- _headers
- robots.txt
- style.cssoptional instance stylesheet example
- script.jsoptional instance script example
- v8s-links.txthuman-authored source of truth for links
- v8s-site-config.jsoninstance languages, branding, operator values, and contacts
- scripts/product tooling
- workers/canonical Worker source and tests
- worker.mjs
- worker.test.mjs
- lnkCLI for links, schedules, and policy workflows
- build.mjsbuild defaults plus custom into deploy output
- setup.mjsnpm run setup
- upgrade.mjsnpm run upgrade
- local-install.mjslocal helper setup
- v8s.shread-only local helper
- src/generated Worker entry copied from scripts/workers
- worker.mjs
- build/generated deploy output
- v8s.jsonruntime redirect registry
- v8s-blocklist.jsonruntime policy artifact
- v8s-site-config.jsonruntime site configuration
- v8s-custom-assets.jsoncustom public asset manifest for Worker security profiles
- _headers
- index.html
- _stats/protected stats shell
- index.html
- _tests/protected runtime test page
- index.html
- en/localized public pages and assets
- index.html
- 404.html
- expired.html
- disabled.html
- maintenance.html
Product Defaults
defaults/ is the product baseline. It contains public pages, localized status pages, redirected badges, policy pages, icons, the protected stats shell, starter links, inline starter schedules, default policy, site configuration, and local-helper defaults.
scripts/ is product tooling. Edit it only when you are changing vanityURLs itself. Instance operators usually receive updates to this directory through npm run upgrade.
Instance Files
custom/ belongs to the instance owner. Put links, brand assets, page overrides, site configuration, local helper configuration, and policy replacement here.
The build prefers custom/v8s-links.txt when it exists. If it does not, the build falls back to defaults/v8s-links.txt so a fresh clone can still produce a working starter instance.
custom/v8s-policies.json replaces the default policy source when present. It is not merged with defaults/v8s-policies.json; removed custom policy decisions should not reappear through a default merge.
Product-managed public runtime assets use v8s- filenames and normally stay in defaults/public/. Do not copy files such as v8s-style.css, v8s-script.js, v8s-lookup.js, or v8s-theme.js into custom/public/ during routine upgrades. The build already includes the product asset from defaults/public/; a matching file under custom/public/ is a shadow override and npm run doctor reports it. Use ./scripts/v8s-fix --assets to remove stale custom/public/v8s-* shadows.
When a custom public file is intentionally different, record that decision in custom/v8s-custom-overrides.json instead of forcing doctor to pass. See v8s-fix for the maintenance workflow.
wrangler.toml also belongs to the instance. It defines the Worker name, route or custom domain, build command, and Cloudflare Access team domain.
Generated Output
build/ and src/ are generated. Do not edit them by hand.
build/v8s.json is the runtime redirect registry. It contains normalized link targets, the schema 3.1 tree, routing rules, lifecycle states, metadata, generated timestamps, and optional schedule blocks.
build/v8s-blocklist.json is the runtime policy artifact consumed by the Worker. It is generated from the selected policy source and optional generated feed data.
build/v8s-site-config.json records the site configuration used for the build, including supported languages, branding, operator information, and contact settings.
build/v8s-custom-assets.json records the final public paths that came from custom/public/. The Worker uses it to apply the custom HTML security profile after localized pages and root English pages have been copied into their deployment paths. Product-managed v8s-* assets should not appear in that manifest unless the instance is deliberately maintaining a local fork.
build/v8s-release-manifest.json records the release package version, Git commit, schema versions, Cloudflare compatibility date, and SHA-256 hashes for release inputs and outputs.
src/worker.mjs and src/lib/analytics-policy.mjs are generated during npm run build so Wrangler can deploy the Worker and its support modules. The source of truth is scripts/workers/. npm run clean removes generated build/, src/, and old compatibility output.