Skip to content

Sites

Use Sites to publish a website at a Skippr hostname, with optional custom domains, preview URLs, and cache control. Create a Site, upload a deployment, and promote it when it is ready. Use Sites for a web app or marketing site; use Gateway when you want a standalone HTTP or WebSocket API.

Status: Preview. You can create a site, publish a deployment, and bind a custom domain after DNS validation. See the API action reference for the full command list.

At a glance

FactValue
CLIskippr-cloud sites <operation>
Target prefixCloudSites.
AuthenticationCloud JWT or SigV4 service sites
Stable hostname{site_id}.sites.skippr.io
Preview hostname{deployment_id}--{site_id}.sites.skippr.io
ContractAPI actions

What you can do

  • Create a stable Site identity and platform hostname.
  • Upload, complete, and inspect immutable static or SSR deployments.
  • Promote a ready deployment or roll back by promoting an earlier one.
  • Open public previews directly, or enable Site-level preview protection and mint scoped automation or share-link access.
  • Route same-origin APIs and Forms through declared bindings.
  • Purge cache entries, revalidate pages or tags, and optimize images.
  • Bind and verify a custom hostname.

How publication works

Complete a deployment, then wait until it is READY before you promote it. Promotion chooses which ready deployment the stable hostname serves.

Browser requests terminate TLS at the Sites CDN, which caches static and ISR responses in the Site's home region. Cache misses and server-rendered pages run at the regional origin. Same-origin API and Form routes declared on the Site are forwarded to your Gateway Api.

Sites web traffic uses the Sites edge. Cloud service APIs and Gateway Apis continue to use the gateway edge. A Site can bind to a Gateway Api; it does not create a second public path to Cloud APIs.

Custom Site hostnames use a Sites domain binding and Sites-managed TLS. They do not use a gateway domain name or a Certificates certificateId.

Create a Site

The same Site create is CLI, Terraform, CDKTF TypeScript, or CDKTF Python. For provider credentials and the shared cloud provider block, see Terraform and CDKTF. New Sites are public by default and preview protection defaults to DISABLED. Set previewProtection to PROTECTED when immutable preview hostnames should require scoped access. Omit region to use the Site's home region. The response includes the Site id, platform hostname, region, and starting revision.

bash
skippr-cloud sites create-site --name web
hcl
resource "cloud_site" "web" {
  name = "web"
}
ts
import { CloudProvider, CloudSite } from "@skippr/provider-cloud";

const cloud = new CloudProvider(this, "cloud", { region: "eu-central-1" });

const site = new CloudSite(this, "web", {
  name: "web",
  provider: cloud,
});
python
from skippr_cdktf import CloudProvider, CloudSite

cloud = CloudProvider(self, "cloud", region="eu-central-1")

site = CloudSite(
    self,
    "web",
    name="web",
    provider=cloud,
)
TaskCallable actions
CreateCreateSite
ReadGetSite, ListSites
UpdateUpdateSite
DeleteDeleteSite

cloud_site is the Terraform resource for a stable Site, including production access and preview-protection policy. Deployments and promotions are release actions and deliberately are not Terraform resources.

Complete and promote a deployment

  1. Call CreateDeployment with a SiteBundle manifest containing static assets and a typed clientToken. contentDigest must be the canonical SHA-256 digest of the normalized manifest, excluding the manifest's own contentDigest.
  2. Upload every declared asset to the returned put URLs.
  3. Call CompleteDeployment once with a clientToken, then read GetDeployment until operation.state is APPLIED, operation.edgePropagation is COMPLETE, and status is READY.
  4. Call PromoteDeployment with expectedRevision to make that deployment active. Read GetSite.operation until the effect and edge propagation are complete.
TaskCallable actions
Create and uploadCreateDeployment
Finish publishCompleteDeployment
InspectGetDeployment, ListDeployments
ActivatePromoteDeployment
Remove a non-active deploymentDeleteDeployment
Authorize a protected previewCreatePreviewToken

Static and SSR adapters under @skippr/sites-adapter-* consume official local framework build output and emit the generated SiteBundle contract. SSR profiles are next-ssr, astro-ssr, and nuxt-ssr. Every bundle names the fixed skippr-preview-2026-08 runtime profile. Runtime secrets reference exact Secret versionId values; changing one creates a new immutable Deployment. For same-origin API and Form routes, declare the typed OriginBinding or FormRoute Api and integration ids. SiteBundles do not accept an upstream URL or apiOrigin; Skippr Cloud selects the gateway endpoint. A FUNCTION OriginBinding returns the handler payload as the HTTP body, not the { "statusCode", "payload" } Invoke envelope.

The skippr-sites deploy command runs a local build, adapts the output, uploads artifacts through exact signed PUT URLs, completes the Deployment, and waits for READY. The first unqualified deploy promotes to production. Later unqualified deploys remain previews; use --prod to promote or --preview to prevent first-deploy promotion. Skippr Cloud does not run a managed remote build service.

Preview hostnames are public when preview protection is disabled. Protected previews accept a deployment-scoped Bearer token for automation. Share links are scoped, expiring, and revocable; opening one exchanges the query credential for an HttpOnly, Secure deployment-host cookie and redirects to a clean URL.

Bind a custom domain

Create the binding with CLI, Terraform, CDKTF TypeScript, or CDKTF Python. Then publish the returned routing CNAME (sites.skippr.io) and ownership TXT at your DNS provider. A zone apex cannot be a CNAME at some providers; flatten to A records of sites.skippr.io instead. Or use DNS when Skippr Cloud manages the zone. Call VerifyDomainBinding with the binding's current expectedRevision, then read GetDomainBinding until the binding reports its active status.

bash
skippr-cloud sites create-domain-binding --site-id '<siteId>' --hostname www.example.com
hcl
resource "cloud_site_domain_binding" "www" {
  site_id  = cloud_site.web.site_id
  hostname = "www.example.com"
}
ts
import { CloudSiteDomainBinding } from "@skippr/provider-cloud";

new CloudSiteDomainBinding(this, "www", {
  siteId: site.siteId,
  hostname: "www.example.com",
  provider: cloud,
});
python
from skippr_cdktf import CloudSiteDomainBinding

CloudSiteDomainBinding(
    self,
    "www",
    site_id=site.site_id,
    hostname="www.example.com",
    provider=cloud,
)
TaskCallable actions
Create and verifyCreateDomainBinding, VerifyDomainBinding
ReadGetDomainBinding, ListDomainBindings
RemoveDeleteDomainBinding

cloud_site_domain_binding is the Terraform resource for stable custom-domain configuration. It exposes the validation records and waits for asynchronous provider effects. Provider outages leave durable work pending or failed; they never produce passing release evidence. Do not send DNS provider credentials to Sites.

Cache and runtime features

PurgeCache is the emergency invalidation path and accepts at most 100 paths in one request. Use an optional deploymentId when the operation must target one immutable deployment.

RevalidatePath and RevalidateTag mark deployment-scoped page records stale, enqueue bounded regeneration work, publish the next page generation, and advance the corresponding edge pointer. Their responses include each durable operation. CDN invalidation is an optimization, not the publication boundary. The bounded same-site /_image transform route uses a declared source version in its cache key. Private sources require a path scope and a pinned credential Secret version.

Declare each imageSources entry with an HTTPS origin (scheme and host only), an allowedPathPrefix ending in /, and a non-empty contentVersion. Private sources also require both secretId and secretVersionId. Pass the exact normalized source path to CreateImageToken; the returned token cannot be reused for another path, source version, Deployment, or transform.

TaskCallable action
Purge selected paths or a scoped cachePurgeCache
Revalidate one pathRevalidatePath
Revalidate by tagRevalidateTag

Normal promotion uses immutable deployment assets, so broad cache purges should not be required for a routine release.

Limits and errors

Limit per DeploymentValue
Static files20,000
Individual static file25 MiB
Total uncompressed static assets1 GiB
Worker bundle10 MiB
Static redirects2,000
Dynamic redirects100
Response-header rules100
ISR tags100
ISR paths2,000
Private/public image sources32
  • 400: the SiteBundle, digest, hostname, or request shape is invalid.
  • 401: authentication is missing or invalid.
  • 403: the policy denies the operation or hostname.
  • 404: the Site, Deployment, or DomainBinding does not exist.
  • 409: an idempotency token, expected revision, active-deployment deletion, or domain ownership conflict prevents the mutation.
  • 500: the service could not persist state.

An oversized file or bundle returns a validation error. Fix the input before retrying. Durable create actions and CompleteDeployment require a 1–128 character clientToken; reuse it only for the identical request. Mutations of existing resources require the revision returned by the latest read as expectedRevision. A stale revision returns 409 instead of overwriting newer desired state.

Provider-backed mutations normally return 202 with operation. Effect states are PENDING, LEASED, APPLIED, TERMINAL_FAILED, and BLOCKED_PLATFORM; edge propagation is reported separately. A terminal failure is immutable. Operators redrive it as a new command generation rather than resetting the failed record.

Uploaded bundles must not contain path traversal, escaping symlinks, duplicate normalized paths, or files that do not match the declared digest.