Core Concepts
Understanding PageWeave's architecture and data model.
Websites
A website is the top-level entity. Each website has:
- Subdomain — auto-generated (e.g.,
my-site.pageweave.site) - Hostnames — names attached to the site that serve or redirect it (e.g.
example.com; optional) - Theme — daisyUI theme applied to all pages
- Language — BCP 47 tag (e.g.,
en,de). For multilingual sites, see the Internationalization (i18n) guide. - agents_md — private Markdown instructions agents write for other agents working on the site, following the AGENTS.md open standard. Not publicly served. Read it first when picking up an unfamiliar website.
Everything the agent creates is live immediately — there is no draft/published review gate. Every change is versioned. Freezing content to a specific version is done per surface with releases.
Pages
Pages are versioned HTML and/or Markdown content at URL paths:
- Path — URL anchor (e.g.,
/,/about,/contact) - Versions — every edit creates a new version; the newest version is live (releases freeze per environment)
- Title — page title for
<title>and metadata (stored verbatim — no Liquid) - HTML body — raw HTML, the default representation. Supports Liquid.
- Markdown body — served to agents (
Accept: text/markdown) and at the.mdURL. Supports Liquid. - additional_html_head_html — page-specific
<head>content (meta tags, Open Graph, schema.org, favicons, custom CSS), rendered after the globalhtml_head. Supports Liquid. - Language — optional per-page override (BCP 47 tag)
- Template pages — pages bound to a data table; path placeholders map to row fields (e.g.
/posts/:slug). See Data Tables.
Versioning
Every edit creates a new version with:
- Sequential version number
- Timestamp
- Rollback reference
revert_version creates a new version with old content — it never deletes anything. Freezing a version is done with releases: a release snapshots the latest versions of all pages, components, snippets, and the theme into an immutable manifest; attaching it to an environment serves exactly those versions on that surface.
Components
Header, Footer & HTML Head
Instance-based HTML components with versioning and display conditions. A website can have multiple instances per component type; instances without conditions are the fallback (render everywhere), instances with conditions render only where they match (path, language, host, row, indexable) — lowest priority wins. Routing lives on versions, so condition changes are versioned like content (revertible).
create_component/list_components/delete_component manage instances; get_component/update_component operate on the fallback instance without instance_id (auto-creating one on update when none exists) or on a specific instance with it (component accepts header, footer, or html_head). Conditioning ALL instances of a type removes chrome from non-matching pages — the update tools warn about this.
The global html_head is additional <head> content (meta tags, tracking scripts, analytics, favicons) rendered on every page, before each page's additional_html_head_html. Versioned like pages — manage it via update_component with component: "html_head". Per-path/per-language instances give you per-page heads.
Themes
daisyUI 5 + Tailwind CSS v4 theme system:
- Built-in themes — 35+ themes (nord, sunset, dark, etc.)
- Custom themes — custom CSS variables with a
[data-theme]selector - Instant changes — CSS variables update, no re-render needed
See Themes.
Snippets
Versioned text files served at /snippets/<path> on the website's domain:
- Types — CSS, JS, JSON, HTML, SVG, XML, YAML, Markdown, CSV, plain text
- Path — relative, no leading slash (
css/style.css,js/app.js) - Versioning — every edit creates a new version; revert like pages
- Size limit — 256 KB per version
- Content type — inferred from extension when omitted
- Skip-unchanged — identical content creates no new version
- Canonical URLs are unversioned — reference snippets by their canonical URL; the platform rewrites refs to content-hash-marked URLs (
/snippets/style.h1a2b3c4d.css) at render time, served withCache-Control: public, max-age=31536000, immutable(marker = content-hash cache key: identical content always maps to the same URL). References to other snippets inside snippet content are not rewritten — the nested ref stays canonical and the browser follows a 302 to the referenced snippet's live hash URL. - Releases freeze versions per environment — a release manifest pins exact versions of every snippet; an environment attached to a release serves those versions. A snippet absent from the manifest 404s at the snippet route.
Use snippets for reusable code/data referenced from multiple pages (<link>, <script src>, fetch()). For binary files (images, fonts, video, PDFs), use assets.
Environments & Releases
Every website is served on environments. The default environment ("live") backs the platform subdomain; additional dev/staging environments get generated *.env.pageweave.site hosts (noindex, no analytics) with optional live-reload. Draft table rows render on dev environments on template pages only — {% for %} loops are published-only everywhere.
Releases snapshot the latest versions of every page, component, snippet, and the theme into an immutable manifest. Attaching a release to an environment freezes that surface to the manifest (pages absent from the manifest 404; snippets absent from the manifest 404 at the snippet route; the theme falls back to the built-in default). Every release has a *.r.pageweave.site permalink, kept while the release is retained (unattached releases past 50 are pruned). Rollback = attach an older release.
Assets
Binary file uploads with automatic optimization:
- Images — WebP + AVIF variants generated
- Fonts — WOFF2, TTF, OTF supported
- Documents — PDF, DOCX, XLSX, PPTX
- Size limits — 5MB images, 2.5MB fonts, 15MB video/audio, 10MB other
- Batch uploads — one plain upload URL (
request_upload_url) is reusable for 10 minutes; each PUT creates a new asset — pass a different?filename=per PUT to upload a whole batch - Replace is permanent — passing
asset_idto an upload tool replaces the bytes in place; old bytes are purged immediately (no undo, no version history). A replacement upload URL always overwrites that one asset on every PUT
Image Rendering
Images are automatically enhanced at render time:
- WebP/AVIF — modern formats generated for raster images
- Responsive srcset — multiple sizes generated
- Original — original file always available
- Text assets — CSS, JS, JSON, HTML, SVG should use snippets, not assets
Analytics
Privacy-first, server-side only analytics:
- No cookies — no tracking cookies, no GDPR banners needed
- No JS trackers — no fingerprinting, no client-side scripts
- Raw data retention — 90 days
- Daily/hourly metrics — page views, referrers, countries, cities, bots, AI agents
- Live visitors — real-time count
Forms
Versioned forms with email notifications:
- Fields — text, email, textarea, select, checkbox, radio, number, etc.
- Notifications — email to site owner; requires email verification
- Spam protection — ALTCHA proof-of-work with tiers: standard (default), code, strict (adds an accessible image/audio code challenge)
- Spam shield — automatic: sustained abuse raises a form's protection (site-wide if several forms are hit) and decays back after; owners get notified
- Spam scoring — content checks route suspicious submissions to a reviewable spam folder; release or mark as spam per submission (see Security)
- Versioned — each version has a unique
submit_url; old versions keep working - Submissions — stored as JSONB, exported via the admin
Hostnames & Domains
Hostnames attach names (e.g. example.com) to a website; domains are DNS zones managed by PageWeave or purchased through us:
- Hostnames — serve (Pro) or redirect to the platform subdomain (Free); apex auto-creates a www companion
- Domains — DNS-managed zones;
manage_domain_dnssets up zone + records + hostname in one call - Domain purchase — check availability, buy via Stripe checkout
- DNS records — A, AAAA, ALIAS, CNAME, MX, TXT, NS, SRV in managed zones
Deleting a website is blocked while any hostname is attached, and releasing a hostname is blocked while its DNS still resolves to PageWeave — hostname rows hold DNS claims (subdomain-takeover protection). Remove DNS records and wait out the TTL before releasing.
Security
Platform-level protections:
- Markdown sanitization — raw HTML in markdown source is neutralized
- SSRF protection — server-side fetches guarded
- Rate limiting — Rack::Attack on platform routes and form endpoints
- Spam shield — adaptive proof-of-work tiers on forms, auto-escalating under attack
- Email verification — form notifications require verified email
See Security.
Privacy & Data
- Hosting — Hetzner, Germany (EU)
- Data controller — the site owner; PageWeave is processor
- Google Fonts — proxied through PageWeave
- CDN libraries — proxied via
libs.pageweave.dev(no visitor IP/referrer to third-party CDNs) - Cloudflare — DNS only, no proxy
See Privacy.