Bootstrap Studio hosting
Bootstrap Studio can publish a design to its own hosting (yourname.bss.design), and put it on your own domain through Cloudflare. The pages are plain files, and Headra supplies the content, so editors never need to republish the design.
What you'll end up with
- Bootstrap Studio holds the design and pages, and publishes them to Bootstrap Studio Sites.
- Cloudflare puts the site on your domain (e.g.
www.clientsite.com) with HTTPS. - Headra (
https://app.headracms.com) sends the posts, menus and SEO tags to the pages as they load. - Headra also serves the sitemap on a subdomain such as
api.clientsite.com.
Before you start
- Bootstrap Studio. Its Sites hosting is free for Bootstrap Studio users.
- A Cloudflare account (the free plan is enough) and the domain.
- A Headra website for the client and a public API key (API keys).
1. Set up the website in Headra
- In Account → Websites, set the website's site URL to the live address (e.g.
https://www.clientsite.com). While you're testing on the free address, you can usehttps://yourname.bss.designand change it later. - Create a public key under API keys.
- Set the URL patterns to match the pages. Bootstrap Studio Sites serves plain files, so one page (e.g.
post.html) shows every post, and the post is chosen by the address's query string:Sitemaps, canonical links and theWhere Setting Pattern Posts Content types → Posts → Front-end URL /post.html?slug={slug}Other types (e.g. events) The type's Front-end URL /event.html?slug={slug}Categories SEO → Category URL /index.html?category={slug}Tags SEO → Tag URL /index.html?tag={slug}urlof each item are built from these patterns, so they must match the pages you create in Bootstrap Studio.
2. Add Headra to the design
- Download
config.jsandheadra.jsfrom the starter kit (or all files as a .zip). Put the public key inconfig.js. - In Bootstrap Studio's Design panel, right-click JavaScript → Import JS File, and import
config.js, thenheadra.js. Create your page scripts (below) with right-click → New → JS File. - Right-click JavaScript → Include Order:
config.jsfirst, thenheadra.js, then the page scripts. - Right-click each page script → Visibility, and tick only the page it belongs to (e.g.
post.jsonly onpost.html). - On each page, add an empty element where the content goes and give it an ID in the Options panel. For a grid of cards, use a Row (e.g. ID
latest-posts) and the script fills it with columns.
A grid of posts: latest-posts.js (on index.html)
(async () => {
const { api, esc, image, field, date } = Headra;
const result = await api('/api/posts', { per_page: 6, fields: 'excerpt,featured_image' });
document.querySelector('#latest-posts').innerHTML = result.data.map((post) => `
<div class="col-md-6 col-lg-4">
<div class="card h-100">
${image(post.fields.featured_image, 'medium', 'card-img-top')}
<div class="card-body">
<h3 class="h5"><a href="post.html?slug=${encodeURIComponent(post.slug)}">${esc(post.title)}</a></h3>
<p class="small text-muted">${esc(date(post.published_at))}</p>
${field('excerpt', post.fields.excerpt)}
</div>
</div>
</div>`).join('');
})();
One post: post.js (on post.html, with an element of ID post)
(async () => {
const { api, esc, image, field, seo, track, query } = Headra;
const result = await api(`/api/posts/${encodeURIComponent(query.get('slug') ?? '')}`);
if (!result) { document.querySelector('#post').innerHTML = '<p>Not found.</p>'; return; }
const post = result.data;
seo(post); // title, description, social tags, canonical link, structured data
document.querySelector('#post').innerHTML = `
<h1>${esc(post.title)}</h1>
${image(post.fields.featured_image, 'large', 'img-fluid rounded mb-4')}
${field('body', post.fields.body)}`;
track('posts', post.slug); // counts a view for Analytics
})();
- Preview in Bootstrap Studio shows the live content, because the Headra API accepts requests from any address.
- Escape every value with
esc(), except rich text, which Headra has already cleaned. See Connecting a website for the rest ofheadra.js. - Videos in rich text use Bootstrap's 16:9 ratio box already. Add
.video-half { width: 50%; }to a stylesheet if editors use half-width videos.
3. Publish to bss.design
- In Bootstrap Studio, open Cloud › Manage Websites, click Add Website and choose a subdomain.
- Click Publish (top right) and pick that website. Later, Publish Changes uploads only what changed.
- Open
https://yourname.bss.design/post.html?slug=…with a real post's slug and check that it loads.
4. Use your own domain with Cloudflare
Bootstrap Studio recommends Cloudflare: it provides the HTTPS certificate and lets the bare domain (clientsite.com) point at the hosting. Its own guide is at bootstrapstudio.io/docs/custom-domains.html.
- Add the domain to Cloudflare and change the nameservers at the domain's registrar to the two Cloudflare gives you. This can take a few hours. The current site stays up meanwhile.
- In Bootstrap Studio, open Cloud › Manage Websites › Add Website, choose Custom Domain, enter the domain and click Check. Domains with non-Latin characters are entered in punycode (e.g.
xn--e1aybc.com). - In Cloudflare → DNS, add the record that Bootstrap Studio shows. The cloud icon must be orange (proxied), or HTTPS and hosting won't work. If a record with the same name already exists, delete it first, but check that it isn't used for anything else (email records are separate and must stay).
- In Cloudflare → SSL/TLS → Overview, set the encryption mode to Flexible. Bootstrap Studio's hosting needs it.
- Wait a couple of minutes, then click Verify Domain in Bootstrap Studio, and Publish to the new website.
- Optional: to make
www.clientsite.comandclientsite.comgo to the same place, add a redirect rule in Cloudflare (Rules → Redirect Rules).
5. Point Headra at the live address
When the domain works, change the website's site URL in Headra to it (e.g. https://www.clientsite.com). Sitemaps, canonical links and social tags change straight away. Nothing needs republishing.
6. Sitemap and search engines
Bootstrap Studio Sites can't run Headra's sitemap, so Headra serves it on a subdomain of the client's domain:
- In Cloudflare → DNS, add a CNAME record named
apipointing toapp.headracms.com, with the cloud grey (DNS only). It must not be proxied: Headra provides its own certificate, and the Flexible setting is only for Bootstrap Studio. - Ask your Headra administrator to connect
api.clientsite.comto Headra and add it under Account → Websites → Domains. - Check that
https://api.clientsite.com/sitemap.xmlloads. - Google Search Console: add the client's domain as a Domain property. Google gives you a TXT record; add it in Cloudflare's DNS. Once it's verified, submit the sitemap under Sitemaps. If Bootstrap Studio also produces a sitemap for the fixed pages, submit that as well.
- Bing Webmaster Tools: import the site from Search Console and submit the same sitemap.
7. Redirects and the 404 page
Bootstrap Studio Sites shows a page named 404.html (at the top level of the design) for any address that doesn't exist. Give that page the two Headra scripts and this one, so the redirects you add in Headra send visitors to the new page:
(async () => {
const found = await Headra.api('/api/redirects/resolve', { path: location.pathname + location.search });
if (found) location.replace(found.data.target);
})();
After launch
- Content edited in Headra shows on the site within seconds. Only design changes need Publish Changes.
- Cloudflare caches the design's files. If a changed script or stylesheet doesn't show after publishing, purge the cache in Cloudflare (Caching → Configuration → Purge Everything).
- Only the public key goes in
config.js. Any other key would be visible to every visitor.
Planned: tidier addresses
Cloudflare's URL Rewrite Rules can serve an address such as /blog/my-post from post.html without changing what the visitor sees. The starter kit will support this in a later version. You'll then switch the URL patterns to /blog/{slug} and add the rewrite rules in Cloudflare.