Skip to content

Static sites

WebShield can host static sites without a separate origin server: files are stored in the WebShield infrastructure and served through the same protection layer as proxied sites — with CDN caching, WAF, and bot protection.

  • Static site hosting must be available on the domain plan. Storage size and the maximum file size depend on the plan.
  • A site is bound to the domain apex or to an existing A, AAAA, or CNAME record. For a subdomain, create the DNS record first.
  • Proxying must be disabled for the name. One hostname is either proxied or hosts a static site.
  1. Open the Sites section.
  2. Click Create and select a hostname from the list. Names that are already proxied or taken are marked and unavailable.
  3. The site is created in the Disabled state — it is not visible to visitors until you publish it.

index.html in the site root serves as the start page. Files can be uploaded in several ways:

  • Drag and drop — drag files or folders into the upload area. The subdirectory structure is preserved.
  • Pick files / Pick folder — upload via the selection dialog. When a folder is selected, relative paths are preserved.
  • Into a specific folder — the upload button on a folder row in the file list adds the selected files directly to it.
  • ZIP archive — uploading an archive completely replaces the current site content. The other methods work in merge mode: new files are added and matching paths are overwritten.

Files are displayed as a tree with subdirectories. Folders show the total size of their content.

  • Download: a file is downloaded as is; a folder or the whole site (the ZIP button in the list header) is downloaded as a ZIP archive.
  • View: text files (HTML, CSS, JS, JSON, and others, up to 512 KB) open in a preview window.
  • Delete: select files and folders and click Delete selected. A folder is deleted together with its content. A single item can be deleted with the button in its row.
  • Updating a file: upload a file with the same path — it overwrites the old one.

Uploaded files go into a draft (the working area) shown in the file manager. Visitors see the last published version, not the draft.

The Publish button:

  1. Takes an immutable snapshot of the draft as a new version (atomically — visitors never see a half-updated site).
  2. Switches the host DNS record to the WebShield infrastructure. The original record is saved and will be restored when the site is disabled.
  3. Issues a TLS certificate (if HTTPS is enabled and the domain is delegated).
  4. Makes the new version available to visitors.

Disable unpublishes the site and restores the original DNS record; the files are kept. Deleting the site removes the files and fully releases the hostname.

Content is cached on edge nodes. Every publish is a new version, so the cache is invalidated automatically: visitors receive the new content immediately after publishing, with no manual purge. If you changed draft files and want visitors to see them, click Publish.

  • Site generator — pick a preset (Hugo, Jekyll, Astro, Gatsby, Next.js export, SPA, plain HTML). The preset sets sensible defaults for the other options, which you can still tweak.
  • Clean URLs — how pretty paths resolve to files, matching your generator:
    • Directory index/about/about/index.html (Hugo, Jekyll, Astro, Eleventy, Gatsby);
    • HTML extension/about/about.html, then /about/index.html (Next.js export);
    • Exact path only — no guessing.
  • 404 page — document served for missing paths (e.g. 404.html), returned with a 404 status. Empty — pass the origin response through.
  • SPA mode — serve index.html (with a 200 status) for unknown paths. Enable it for single-page applications with client-side routing.
  • Serve over HTTPS — issue a certificate and serve the site over HTTPS with a redirect from HTTP.
  • Bot protectionOff, Browser check, or Captcha check. Works the same way as for proxied sites.

Settings changes for a published site are applied automatically.

To build and publish automatically, create a deploy token in the site card (the “Deploy tokens” section). The token is scoped to that one site; the full token is shown once — store it in your repository secrets.

Pass the token in the Authorization: Bearer <token> header. Archive upload and publish are available:

.github/workflows/deploy.yml
name: Deploy site
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
SITE_ID: "123" # site id (from the card URL)
WSP_TOKEN: ${{ secrets.WEBSHIELD_DEPLOY_TOKEN }}
API: https://webshield.pro/api
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build # your build → ./dist
- name: Pack
run: cd dist && zip -r ../site.zip . && cd ..
- name: Upload (replaces site content)
run: |
curl -fsS -X POST "$API/static-sites/$SITE_ID/archive" \
-H "Authorization: Bearer $WSP_TOKEN" \
-F "archive=@site.zip"
- name: Publish
run: |
curl -fsS -X POST "$API/static-sites/$SITE_ID/publish" \
-H "Authorization: Bearer $WSP_TOKEN"

A deploy token can only upload files and publish this site — it cannot manage the site, the domain, or other sites. Revoke it from the same card.

For large sites (thousands of files) re-uploading a full archive every time is slow. You can upload only the changed files: GET /static-sites/<id>/files returns the file list with an etag field (the content MD5). Compare it with the MD5 of your local files, then:

  • upload new/changed files via POST /static-sites/<id>/upload (fields files and paths; appends to the draft, does not replace the whole site);
  • remove deleted files via POST /static-sites/<id>/delete-files (JSON {"paths": [...]});
  • publish: POST /static-sites/<id>/publish.

The draft persists between publishes, so only the delta needs uploading. A ready-to-use, dependency-free script ships with WebShield — tools/publish_static_site.py:

Terminal window
WS_PUBLISH_TOKEN=<token> python3 tools/publish_static_site.py \
--site-id 123 --dir ./dist --api-base https://webshield.pro
  • Storage size and the maximum size of a single file are limited by the plan.
  • Uploading executable files and installers (.exe, .msi, .apk, .bat, and similar) is not allowed — this protects against malware distribution through the hosting.
  • ZIP archive: no more than 5000 files; archives with an abnormally high compression ratio are rejected.