Kwisple
Browse the docs

Start here

Concepts

Short definitions of everything you meet when building on Kwisple, with links to the detailed pages.

One or two paragraphs per concept. Each one links to the page that goes into detail.

Tenancy

Agency

The reseller: an agency, studio or freelancer. Agency members open every workspace of their agency and carry the rights that matter to you: linking a site, pushing a content model, creating tokens (site.advanced), connecting hosting and creating a staging environment (site.deploy). Agencies are white-label: their clients see the agency's name and colours, not the product's. An agency can serve the dashboard on its own host; then its developers log in there with kwisple login.

Workspace (client)

One client. Everything the client owns (sites, entries, assets, forms, brand kit, posts) carries its workspace_id. In the CLI a workspace is called a Klant (client) and is identified by its slug (kwisple link --client <slug>). Client users see only their workspace, with rights from the agency-configured access policy. The details are in Tenancy and permissions.

Sites

Site

A website of a client. It has a mode (headless for custom code, hosted for legacy block sites, external for sites built elsewhere) and, for custom code, an environment (production or staging). A site has a name, a slug (the first part of its temporary platform address), one or more locales with a default locale, an isLive flag (Online zetten / Offline halen) and domains. The SDK's client.site() returns these as SiteInfo. See What Kwisple is.

Site settings for developers

Under Website → Instellingen → Ontwikkeling the Site card holds what your code and the platform need to find each other:

SettingDashboard labelUsed for
Site URLSite-URLCanonicals, Open Graph, JSON-LD, sitemap and robots. The custom domain wins over the deployment URL.
Preview URLPreview-URLWhere the dashboard opens live preview: your site's /api/preview. Locally http://localhost:<port>/api/preview, filled in by kwisple link.
Webhook URLWebhook bij publicerenWhere the platform POSTs the signed revalidation webhook after every publish: your site's /api/revalidate, or a host's deploy hook for static builds.
Webhook secretWebhook-geheimSigns the webhook and app sessions. Goes into KWISPLE_WEBHOOK_SECRET. Vernieuwen (renew) makes a new one.
ModeSoort siteOp maat (eigen code) or Gehoste site (blokken).

Live preview and revalidation covers the first three in depth.

Environment: production and staging

A staging environment is a second site (environment = staging) linked to its production site, with its own content, its own token and webhook secret and its own deployment of the staging branch, behind a password and never indexed. Nothing is copied back and forth after creation; Naar productie (to production) merges code, not content. The deployment runs with KWISPLE_ENV=staging. See Staging.

Content

Content model as code

cms.config.ts in your repository is the single source of the content model: defineSchema({ sections, globals, forms, apps }) built from defineSection, defineEntryType, defineGlobalSet, defineForm, defineApp and the field builders on f. kwisple dev pushes it to the development model on every save; kwisple push promotes it to the live model. Types come straight from the file: Entry<typeof schema, "news"> is a fully typed news entry. See Schema as code, Fields reference and Workflow: dev, push and changes.

Entry

One piece of content in a section: a page, a news article, a service. Every entry has system fields (id, section, type, title, slug, uri, url, locale, postDate, expiryDate, parentId, level, seo, updatedAt) and the fields of its entry type, flattened Craft-style (entry.heroHeading). url is the public path with locale prefix (/over-ons, /fr/a-propos); uri is the stored URI (over-ons, __home__ for the homepage).

Entry type

The shape of an entry: a handle, a name, an icon, fields and optional tabs. The same entry type can be used in a section and inside a Matrix field (a block). title: false hides the title field; titleFormat: "{question}" derives it.

Section

A container of entries with a URI format. single (one entry, e.g. the homepage with uri: "__home__"), channel (a flat list, e.g. news with uri: "nieuws/{slug}") or structure (a tree with maxLevels, e.g. pages with uri: "{parent.uri}/{slug}"). Sections are what you query: client.entries({ section: "news" }), client.tree("pages"). See Localisation and URIs for URI formats and locale prefixes.

Block (Matrix)

A nested entry inside a Matrix field (f.matrix({ entryTypes })), the page builder. Blocks have stable ids, can be reordered and disabled, and can nest. Your builder component switches on block.type; a block type without a component is a type error. See Blocks and relations.

Global set

Site-wide values outside any section: contact details, footer text, opening hours. client.globals() returns all of them typed by handle. Fields are per locale unless translation: "none".

Form

A typed form declared with defineForm({ handle, name, fields }): client.submitForm({ form, values }) is then typed and validated by the platform. Undeclared forms keep working untyped. Submissions have a follow-up status and may claim a booking slot and send a confirm mail. See Forms, bookings and confirmations.

Asset

An uploaded file: id, url, kind (image, svg, video, document), mimeType, filename, width, height, alt, focalPoint (0..1 from the top-left, or null) and placeholder (a tiny base64 image for blur-up). Images need alt text to be publishable. The SDK's image helpers turn an asset into a responsive image. See Rendering content.

Drafts, publishing and revisions

The dashboard autosaves a provisional draft per editor. Publishing applies the draft to the live rows, validates (required fields, limits, unique URIs), creates a revision, creates a 301 when a URI changed, purges caches and sends the webhook. Your site reads live content through the delivery API; it reads drafts only during live preview, with a preview token. Scheduled entries (online vanaf / offline vanaf) are purged and webhooked at that moment. See The content engine.

Redirects and the 404 log

The dashboard manages redirects (manual ones, and automatic ones when a live entry's URI changes). Your site follows them when a path has no entry (handleNotFound in Next, resolveEntry in Astro) and reports 404s from the browser so the agency can add a redirect with one click. See Rendering content.

Access

Tokens and scopes

A site API token (kwi_…) authenticates the SDK against the delivery API (Authorization: Bearer). It has one or more scopes:

ScopeDashboard labelAllows
readLezen (gepubliceerd)Every read of published content, brand, globals, forms, redirects, 404 reports.
previewPreview (concepten)Draft content for a previewed entry (x-kwisple-preview) and GET /preview/verify.
schemaContentmodel pushenPOST /schema (kwisple push, kwisple dev), kwisple seed and kwisple export.

Where tokens come from: kwisple link (read + preview + schema, for a developer's machine), kwisple ci-token or Hosting & deploys → Geavanceerd → CI-token maken (read + schema, for CI), the Cloudflare hosting connection (read + preview, named Hosting · Cloudflare), or by hand under Website → Instellingen → Ontwikkeling → API-tokens with Naam, Rechten and Token aanmaken. A token is shown once. Production tokens should not have schema. See Environment variables and tokens.

CLI token

A personal token (kwicli_…) kwisple login stores in ~/.config/kwisple/credentials.json. It works with your rights on the dashboard and is used only by kwisple login, link, ci-token, whoami and logout. It is listed and revocable under Instellingen → Koppelingen → Terminal. See CLI reference.

Webhook secret

A per-site secret the platform uses to sign the revalidation webhook (x-kwisple-signature, HMAC-SHA256 of the raw body) and, through a derived key, app sessions and staging tickets. It lives in KWISPLE_WEBHOOK_SECRET and is shown under Webhook-geheim in the dashboard.

Delivery

Delivery API

GET /api/v1/* on the platform's web app (KWISPLE_URL), bearer-authenticated, JSON, { error: { code, message } } on failure. GET /site, /entries, /entry, /tree, /globals, /brand, /consent, /redirects/match, /preview/verify, /schema; POST /forms, /not-found, /agent, /schema, /seed, /staging/login. See Delivery API.

SDK client

createClient<typeof schema>({ url, token }) from @kwisple/sdk (Next), or createKwispleClient<typeof schema>({ schema }) from @kwisple/sdk/astro/server (Astro, reads env lazily). Methods: site(), entries(), entry(), entryByPath(), tree(), globals(), brand(), privacy(), matchRedirect(), reportNotFound(), submitForm(), formSlots(), withPreview() and more. Pass schema to get a one-time warning when the platform serves another model than your code. See SDK client and Querying entries.

Caching and revalidation

Every SDK read is cached: in Next's data cache with the tag kwisple:all (revalidate 3600 s by default), in Astro in memory (cacheTtl, 3600 s). After every publish, trash, scheduled change or Cache legen (clear cache) the platform POSTs a signed webhook to the site's webhook URL with { tags, event, siteId, at }; the SDK's /api/revalidate route verifies it and purges everything. Static builds point the webhook at a deploy hook instead. See Caching and Live preview and revalidation.

Live preview

The dashboard opens <preview URL>?token=… in an iframe. The site's /api/preview route verifies the token with the platform, stores it in a cookie (site_preview, one hour) and redirects to the entry (or to /__preview?entry=…&locale=… for entries that were never published). The per-request client then reads the previewed entry from its draft. <LivePreview /> listens for kwisple:preview:refresh messages from the dashboard and re-renders in place. See Live preview and revalidation.

Brand kit

Colours, fonts, logos, voice and brand elements, managed by people in the dashboard. client.brand() returns tokens, a css string with --brand-* custom properties, fontsHref or fontPreloads, colors, logos and elements. The starters map --brand-* onto Tailwind in globals.css. See Brand kit and privacy data.

Beyond content

Hosting connection

The link between a site and where it is built: Cloudflare (the platform creates the Pages project, sets the variables, attaches domains, reads deploy states and imports PR previews), Eigen host (deploy hook) (you keep Vercel/Netlify/Cloudflare; the platform POSTs the hook and optionally reads a status URL), or the platform's own server (a Docker image built from your repository). Als inhoud verandert decides whether a publish only refreshes (Alleen verversen) or rebuilds (Opnieuw bouwen). See Hosting and deploys.

Domain

A hostname attached to a site, verified by a TXT record on _site-verify.<domain> plus A/AAAA records (platform server) or a CNAME (own host). Controleer records checks them; Maak hoofdadres makes one the primary address for search engines. See Domains and DNS.

App

A custom module for one client, living in the client's site repository and declared with defineApp in cms.config.ts. The dashboard frames the page at its path under Apps and hands it a signed session (connectApp in the browser, appSessionFrom / appPlatform on the server). Other clients never see it. See Apps overview.

Webhooks (outgoing)

Besides the revalidation webhook, agencies can configure outgoing webhooks for platform events. See Outgoing webhooks.

Websitecheck

The assistant's monthly review of a site's statistics and texts. Text proposals go to the editor; code suggestions go to the agency as requests when the client asks for them. See What Kwisple is.

Site kit

A site's starting content as one JSON file without ids (cms/seed.json): entries and global values. kwisple seed writes it into an empty site; kwisple export saves a site's live content as a kit (files and links between pages left out). See Site kits: seed and export.

Last updated 2026-10-30