Наразі документація лише англійською мовою. Решта сайту відповідає вашій мові.
Static / edge export
Crawl your own running site and write every published page, asset, locale, sitemap, and the built stylesheet to a folder you can serve from object storage or a CDN — no Node origin required for those pages.
9 хв читання
The exporter crawls the site's own running server — over loopback, or its real domain on a proxied host — so the output is byte-for-byte what a visitor receives: the active theme, the template hierarchy, blocks, localized routes, the SEO <head>, favicon, and the /theme.css build all come out unchanged. Use it for marketing sites, documentation, and campaign pages that get far more reads than writes.
What a run produces
index.htmland<slug>/index.htmlfor every published page and post, in the default locale, plus<locale>/…/index.htmlfor each active non-default locale.sitemap.xml,robots.txt,favicon.ico, and the themed404.html.theme.css,/js/*,/uploads/*, plugin and custom-theme assets on their own paths (/ext/<plugin>/…,/themes/<theme>/…) — every same-origin sub-resource an exported page references._static-export.json— a manifest listing every file withbytes,sha256, and a suggestedcacheControl._headersfor Cloudflare Pages / Netlify, plus generated.htaccessand_nginx.confwith serving rules, hardening, security headers, and a commented hand-off for the dynamic surface.
Link discovery is breadth-first from the sitemap and published entries, so menu targets and /slug/page/N pagination are picked up automatically. STATIC_EXPORT_MAX_PAGES (default 2000) caps a runaway crawl.
Running an export
| How | Notes |
|---|---|
| Admin → System → Tools → “Static site export” | Run full export / Run incremental, with a live log. Administrator only. |
pnpm export:static [-- --incremental] [-- --base-url URL] | For CI / cron. Needs a compiled server and a running site. |
justflows export static [--incremental] | Posts to the admin API using the same auth rules as justflows cache clear. |
A full export always prunes: any file under the output directory that the run did not produce is deleted, so a full run is the way to recover from a divergent tree. Clear export (Tools card, or pnpm export:static -- --clear) deletes the whole output folder.
Configuration
| Variable | Default | Purpose |
|---|---|---|
STATIC_EXPORT_ENABLED | 1 | Master switch. 0 refuses the Run actions and auto-rebuild; existing files stay on disk. |
STATIC_EXPORT_DIR | ./static-export | Output directory, relative to the install root. With multisite, every site except the platform site writes to <STATIC_EXPORT_DIR>-sites/<hostname>/ instead. |
STATIC_EXPORT_BASE_URL | APP_URL | Public origin recorded in the manifest and used to recognise same-origin links while crawling. |
STATIC_EXPORT_CRAWL_URL | loopback / APP_URL | Origin the crawler fetches from. Set it to your public domain when the app runs behind Passenger / Plesk, where a loopback port is unreachable. |
STATIC_EXPORT_ORIGIN_URL | — | Origin that still serves form/comment POST. When set, <form action> in the output is rewritten to absolute URLs against it. |
STATIC_EXPORT_ALLOWED_ORIGINS | — | Extra origins allowed to cross-origin fetch() the submit endpoints (CORS), comma-separated. |
STATIC_EXPORT_AUTO | 0 | Rebuild incrementally after content, menu, theme, or settings changes (needs CACHE_REVALIDATE_ENABLED=1). |
STATIC_EXPORT_DEBOUNCE_MS | 5000 | Quiet period that coalesces a burst of changes. |
STATIC_EXPORT_MAX_PAGES / STATIC_EXPORT_CONCURRENCY | 2000 / 4 | Crawl ceiling and parallel fetches. |
Multisite
A run from any site crawls that site's own hostname and writes to its own folder, and auto-rebuild queues each site separately. The STATIC_EXPORT_* settings describe the installation and can only be changed on the platform site. Clear export on a customer site removes only that site's export.
All of these are editable from Admin → System → Tools → “Static site export” → Configuration — the admin writes them to .env and applies them in place, no restart. Absolute URLs *inside* the exported HTML/XML (<link rel="canonical">, og:url, every <loc> in sitemap.xml) are rendered by the origin from APP_URL and are not rewritten, so set APP_URL to the public origin the files will be served from.
Rebuild and invalidation
- Publish / unpublish / update a page → that page's routes (per the manifest
deps), its translation siblings, every route with a dynamic list (blog / archive / home), andsitemap.xml. - Delete or unpublish so a URL now 404s → that page's files are removed and
sitemap.xmlis rewritten. - Menu, theme, Customizer, CSS provider, or settings change → every route, plus
theme.cssand other assets. - Newly published page → picked up by the incremental run that publish triggers; discovery re-reads the live sitemap and published list.
Deploying the output
Point a static web server (nginx, Caddy, Apache) at the output directory with directory-index resolution, or use the generated .htaccess / _nginx.conf. The exporter uploads nothing itself — sync the folder with a tool you already run and drive CDN invalidation from the manifest.
# S3 + CloudFront
aws s3 sync ./static-export s3://my-bucket --delete
aws cloudfront create-invalidation --distribution-id XXXX --paths '/*'
# rclone (S3, GCS, R2, B2, …)
rclone sync ./static-export remote:my-bucket --checksum
# plain rsync to an edge box
rsync -a --delete ./static-export/ deploy@edge:/var/www/site/Register a staticExport.deploy action in a plugin to automate the push — it receives { outDir, publicUrl, manifest, summary } after every successful run. staticExport.routes, staticExport.assets, and staticExport.formAction filters and the staticExport.completed action are also available.
A plugin can keep per-visitor pages out of the export with the staticExport.exclude filter — a list of { path, match } entries, where match is prefix (the default, also covering everything below) or exact. Excluded paths are never crawled, even when linked; copies from earlier runs are removed; the generated .htaccess and _nginx.conf route them to the app; and with STATIC_EXPORT_ORIGIN_URL set, links and form actions pointing at them go to that origin. Shop uses it for its cart, checkout, order confirmation, customer account, and order tracking pages.
Deploy to object storage
Tools → Static site export → Configuration can send the export to Object storage (S3 / OVH) instead of a local folder (STATIC_EXPORT_STORAGE_DRIVER=s3; the default is local). It reuses the installation's STORAGE_S3_* connection without changing where media is stored. Each site gets its own folder in the bucket, based on its stable site id, so a new domain keeps the exported files.
<STORAGE_S3_PREFIX>/static-export/sites/root/ # the platform site and the CLI
<STORAGE_S3_PREFIX>/static-export/sites/<site-id>/ # every other site- HTML only. Images, media, styles, and scripts keep their existing URLs; only the exported pages are uploaded.
- All or nothing. Pages are stored by content hash, and one pointer file switches the site to the new export after every upload succeeded. A failed upload keeps the previous export live.
- Private bucket. Keep your CDN's origin pointed at the app. Before rendering a public page, the app streams the matching exported object with signed S3 requests, with its content type, cache policy, and conditional and range headers. No public bucket policy is needed.
- Live where it must be. Admin, APIs, plugin routes, signed-in visitors, query strings, and export crawls stay on the live app. A missing object or a storage outage falls back to live rendering.
- Identify it. Pages served from the export carry
X-Justflows-Render: static-export. - Clear export removes this site's pointer, objects, and interrupted uploads from the bucket, and leaves other sites, media, and private plugin files alone. Configured CDN caches are purged after a deploy or a clear.
Runs started from the admin happen in the background and report progress while you wait, so a long export no longer times out at a CDN or proxy. A page that answers 404 or 410 during the crawl, such as a broken footer link, is listed as a warning in the log and the summary's warnings and does not stop the deploy. Other errors still fail the run. Pages whose Cache-Control policy is private or no-store are left out of new exports.
Dynamic features off-origin
The exported pages are complete server-rendered HTML plus the site's client-side JavaScript. Menus, animations, the language switcher, and block / plugin / theme client code all run with no origin. A plugin's front-end needs no export-specific work: declare assets in its manifest and its script rides the /jf-plugins.<hash>.js bundle the exporter downloads.
| Feature | On a static host |
|---|---|
| Forms submission | In place via fetch() to /justflows-forms/submit — needs the endpoint reachable (hybrid proxy or STATIC_EXPORT_ORIGIN_URL); native POST is the no-JS fallback. |
| Comment submission | Native POST to /justflows-comments/submit; existing threads render at export time and are read-only otherwise. |
| Pageview analytics | Beacon to /justflows-analytics/collect — the Analytics plugin's jf-analytics.js rides the plugin bundle; needs the endpoint reachable. |
| Cookie consent | Banner, preference center, and script / embed gating work offline; the record beacon and cookie-disclosure fetch resolve against window.__JF_ORIGIN__ and need the endpoint reachable. |
| Login / register / password reset / search | Origin only — never route these to the static host. |
Tip
A same-origin hybrid deployment — the web server serves the static folder and the dynamic prefixes (/api, /admin, /justflows-forms/, …) fall through to the app — needs no CORS and no allow-list. Prefer it unless the host genuinely cannot proxy. See docs/STATIC-EXPORT.md in the CE repository for full nginx / Apache / Passenger examples.