Deploying
Getting each format onto a host, and what each host needs.
Every format ends as static files, so hosting is simple and cheap everywhere. What differs is which folder you upload and whether the host runs a build for you.
Before any of this, set site_url in source/content/seo.json to your real domain and rebuild. Canonical tags, Open Graph URLs and the sitemap are all built from that value, and shipping with the demo value points every canonical at somebody else's site.
What to upload
| Format | Build | Upload |
|---|---|---|
| HTML | already built | the contents of html/ |
| Hugo | hugo --themesDir ../.. | public/ |
| Jekyll | bundle exec jekyll build | _site/ |
| JBake | mvn generate-resources | target/site/ |
The HTML format needs no build at all, which is why it is the one to reach for when you are handing a site to somebody who will not run a toolchain.
Hosts
Netlify and Cloudflare Pages
Both take a folder by drag and drop and give you a URL in under a minute, which is the fastest way to get something in front of a colleague.
For a repository-connected deploy, the build settings are:
| Build command | Publish directory | |
|---|---|---|
| HTML | leave empty | html |
| Hugo | hugo --themesDir ../.. | public |
| Jekyll | bundle exec jekyll build | _site |
Clean URLs. Both hosts serve /about from about.html automatically, so you can strip .html from internal links if you prefer the look. The theme ships them with .html so the built folder also works from a plain file server and by double-clicking, which is the more useful default.
Caching. Add a _headers file if you want long caching on fonts and short caching on HTML:
/fonts/*
Cache-Control: public, max-age=31536000, immutable
/*.html
Cache-Control: public, max-age=600
Fonts are safe to cache for a year because their filenames change when they do. Do not do the same to the stylesheet unless you version its filename, or a fix will not reach anyone who has already visited.
GitHub Pages
Works for all four. For Jekyll it is the native case: push the jekyll/ folder contents as the repository root and Pages builds it. For the others, build locally or in an action and publish the output folder.
If the site lives at username.github.io/repo rather than at a domain root, set the base path in your engine's config, or every absolute link breaks.
S3, shared hosting, a Raspberry Pi
Upload the folder. There is nothing to run, no database, no PHP, no Node. Set the index document to index.html and the error document to 404.html.
For S3 behind CloudFront, remember that CloudFront caches aggressively by default: invalidate after a deploy or you will spend an afternoon convinced the build is broken.
A regulated or air-gapped network
The site makes zero external network requests. No CDN, no font service, no analytics, no telemetry, no cookies set by the theme. You can verify that by disconnecting and opening the built HTML from a file path: everything still renders, including the 3D.
That property is worth stating in a security review, and it is the reason the fonts are bundled rather than linked.
The contact form
The form validates in the browser and submits nowhere. That is deliberate: a template that quietly posts a visitor's details to an address they cannot see would be indefensible.
To make it live, set data-endpoint on the form to your handler. Anything that accepts a POST works: Formspree, Netlify Forms, your own function. Until you do, it shows its success state without sending anything, which is right for a demo and wrong for a launch. Wire it or remove it before you go live.
The same applies to the partner portal sign-in, which is a front-end mock.
A pre-launch checklist
site_urlinseo.jsonis your domain.- Every company, person, product, NDC and figure is yours. The demo content is invented, deliberately, and leadership photographs are illustrations.
prescribing_info_urlon each product points at a real document.- The contact form has an endpoint, or is gone.
- The portal sign-in is wired, or is gone.
robotsinseo.jsonallows indexing. Preview deploys should not.analyticsinseo.jsonis filled in, or left empty deliberately.- Favicon and social card replaced.
Rolling out a change
Edit the JSON, rebuild, upload. There is no cache to prime, no database migration and no server to restart. If your host caches HTML, that is the only thing standing between an edit and a visitor seeing it.