DocsHosting
Newsletter, bookings, content and checkout
A hosted site (see "Host a website") gets four more building blocks for free, each usable with a plain HTML form or a one-line script tag - no server code, no separate account required to get started.
Newsletter signup
Add a form like this anywhere on your site:
<form action="/api/sites/<your-site>/newsletter" method="post">
<input type="email" name="email" required placeholder="you@example.com" />
<input type="text" name="name" placeholder="Name (optional)" />
<input type="text" name="_honeypot" style="display:none" tabindex="-1" autocomplete="off" />
<button type="submit">Subscribe</button>
</form>The _honeypot field is a decoy - leave it empty and hidden; a real visitor never fills it in, and a submission that does is quietly dropped.
If you have a mail sender configured on this deployment, a new subscriber gets a confirmation email first (double opt-in) - they're only added once they click the link. Without one configured, signups are added immediately (single opt-in). Either way, subscribers can leave any time from the unsubscribe link at the bottom of every email you send.
Manage the list from Settings › Sites: see subscriber counts, export the list, and compose a campaign (a subject line and a message written in a light markdown - headings, bold/italic, links and lists) to send to everyone currently confirmed.
Bookings
Set your weekly availability in Settings › Sites - a timezone, how long each appointment is, a buffer between them, and a cap on bookings per day. Then either build your own form and call the two endpoints directly, or drop in the ready-made widget:
<script src="/api/sites/<your-site>/booking/widget.js" data-slug="<your-site>" data-days="14"></script>
<select id="nx-booking-slot"></select>
<form id="nx-booking-form" data-success="Booked!">
<input type="text" name="name" required placeholder="Name" />
<input type="email" name="email" required placeholder="Email" />
<input type="text" name="note" placeholder="Anything we should know?" />
<input type="text" name="_honeypot" style="display:none" tabindex="-1" autocomplete="off" />
<button type="submit">Book</button>
</form>The widget fills the dropdown with your currently open times and posts a booking when the form is submitted. Every booking becomes a lead in Settings › Sites (so a sales agent can follow up the same way it would a contact-form submission), gets a calendar file the visitor can add to their own calendar, and - if you have a mail sender configured - a confirmation email. Cancel a booking any time from Settings › Sites; that time reopens immediately.
Content collections
Any file under content/<collection>/<name>.md in your site's files is one item in that collection - a blog post, a case study, a changelog entry, anything. Give it a short header at the top:
---
title: Our first post
date: 2026-01-15
description: A short summary for previews and search.
tags: [news, launch]
---
The rest of the file is the post itself, written in markdown.Publishing renders each item to its own page (<collection>/<name>.html) plus an index page listing everything in that collection, using your own templates/<collection>.html if you provide one (with {{title}}, {{date}}, {{description}}, {{content}} and {{tags}} placeholders) or a plain built-in layout otherwise. Set draft: true on an item to keep working on it without publishing it.
Ask the assistant to write a post and it can create, read, update and list these items directly.
Product checkout
List what you sell in Settings › Sites - a name, a price, an optional description and image. Each product needs a way to actually take payment: paste in a payment link from whatever you already use (a Stripe payment link, a Gumroad link, anything), or connect your own Square account once and a payment link is created for you automatically. Either way, the money goes straight to you - nothing here is a merchant of record for your sales.
Read the current list from /api/sites/<your-site>/products.json and render it however you like, for example:
<div id="products"></div>
<script>
fetch('/api/sites/<your-site>/products.json')
.then((r) => r.json())
.then(({ products }) => {
document.getElementById('products').innerHTML = products
.map((p) => `<div><h3>${p.name}</h3><p>$${(p.priceCents / 100).toFixed(2)}</p>${p.checkoutUrl ? `<a href="${p.checkoutUrl}">Buy</a>` : ''}</div>`)
.join('');
});
</script>