Configuration reference
blogwright reads one JSONC config file per environment. Only siteName is required — everything else has a default or is optional. This page lists every key in the schema: its type, default, validation rules, and what it controls.
Config files
Section titled “Config files”Config is loaded from config/<env>.jsonc at the repo root of the consuming site, falling back to ops.config.jsonc. Pass --config <path> to use an explicit file instead — it then becomes the only candidate. The repo root is found by walking up from the invocation directory to the nearest .git or .jj, so the CLI works from any subdirectory.
The environment defaults to production; pass another as the positional [env] or --env (see Environments). If no candidate file exists for the environment, the CLI errors and lists the paths it looked for.
Files are JSONC: // line comments, /* */ block comments, and trailing commas are all accepted.
The minimal config:
{ "region": "us-east-1", "siteName": "example", // required — the stable slug in every AWS resource name}blogwright init writes this file for you interactively. Without a TTY, write it by hand — the two lines above are enough to bootstrap and deploy.
How overrides merge
Section titled “How overrides merge”Your file is merged over the defaults. The nested objects microvm (including microvm.idle), retention, seo, and paths merge key-by-key, so you can override a single nested field and keep the rest of the defaults. Scalars and arrays replace their default outright — setting sourceIgnore replaces the default list, it does not extend it.
Core identity
Section titled “Core identity”siteName
Section titled “siteName”string · required
Stable slug used in every derived AWS resource name. Must be lowercase alphanumeric/dashes (^[a-z0-9-]+$). The per-environment S3 bucket is named <env>-<siteName>-<accountId> and must fit S3’s 63-character limit — the CLI rejects the combination otherwise, with a pointer to shorten the environment or site name.
region
Section titled “region”string · optional · default: "us-east-1"
Primary AWS region for S3, the builder MicroVM, and CloudWatch logs. ACM certificates and CloudFront resources are always managed in us-east-1 regardless of this setting (CloudFront requires it), including the CloudFront access-log group.
domain
Section titled “domain”string · optional · no default
Custom domain for the site. May also be supplied per-invocation with --domain, which takes precedence over the config value. When set, bootstrap requests an ACM certificate and prints the validation CNAMEs — see Custom domains. When unset, the site is served from its CloudFront domain.
string · optional · no default
Value of the app tag applied to every AWS resource blogwright creates (alongside an environment tag). When unset it falls back to the domain, then to the repo directory name — always something a human can trace back to the project from a billing or resource listing. Site files get the same tags as S3 object tags.
githubRepo
Section titled “githubRepo”string · optional · no default
GitHub owner/repo, used to scope the trust policy of the GitHub OIDC deploy roles that bootstrap (role <env>-<siteName>-gh) and preview bootstrap (role preview-<siteName>-gh) provision. When unset, bootstrap skips the OIDC role; preview bootstrap always creates one, so the preview stack requires this key. See CI deploys with GitHub OIDC and PR previews.
MicroVM builder
Section titled “MicroVM builder”Sizing and lifecycle of the Lambda MicroVM that runs pnpm install && pnpm build on every deploy.
{ "microvm": { "memory": 4, "maxDurationSeconds": 1800, "idle": { "autoResumeEnabled": false, "maxIdleDurationSeconds": 300, "suspendedDurationSeconds": 120, }, },}microvm.memory
Section titled “microvm.memory”number · optional · default: 4
Builder memory in GB. Must be one of 0.5, 1, 2, 4, 8. Applied to the builder image (converted to a minimum-MiB resource setting), so changing it takes effect through the image, not per-deploy.
microvm.maxDurationSeconds
Section titled “microvm.maxDurationSeconds”number · optional · default: 1800
Maximum run duration of a builder MicroVM, in seconds. Must be between 1 and 28800 (8 hours). Passed to each launch as its maximum duration; the CLI’s own wait deadline for a build is this value plus a 60-second grace period, anchored at VM launch.
microvm.idle
Section titled “microvm.idle”object · optional
Idle policy passed verbatim to each builder MicroVM launch:
autoResumeEnabled—boolean, defaultfalse. Whether the service may automatically resume a suspended MicroVM.maxIdleDurationSeconds—number, default300. How long the MicroVM may sit idle.suspendedDurationSeconds—number, default120. How long it stays suspended.
Log retention
Section titled “Log retention”CloudWatch log-group retention, in days. Both values must be positive.
retention.microvmDays
Section titled “retention.microvmDays”number · optional · default: 365
Retention for the builder MicroVM log group (/aws/lambda/microvms/<env>-<siteName>-builder), which holds the build logs that blogwright logs <hash> reads.
retention.cloudfrontDays
Section titled “retention.cloudfrontDays”number · optional · default: 90
Retention for the CloudFront access-log group (/<siteName>/<env>/cloudfront). This log group always lives in us-east-1, because CloudFront’s vended log delivery only exists there.
Deploy source and invalidation
Section titled “Deploy source and invalidation”Each deploy zips the repo (honoring .gitignore), builds it in the MicroVM, syncs the output to S3, and invalidates only the CloudFront paths that actually changed.
sourceIgnore
Section titled “sourceIgnore”string[] · optional · default: [".jj/", ".git/", "node_modules/", "dist/", ".astro/"]
Extra path prefixes excluded from the source zip, on top of what .gitignore already excludes. Setting this replaces the default list — include the defaults you still want.
sourceInclude
Section titled “sourceInclude”string[] · optional · default: []
Paths zipped into the deploy source even when gitignored — for artifacts a pre-deploy step builds outside the MicroVM (a wasm bundle, generated assets). Each entry must exist and be non-empty at deploy time, so a forgotten pre-build fails fast instead of shipping a broken site. Entries must be repo-relative, with no leading / and no .. segments.
{ "sourceInclude": ["web/src/lib/pkg/"], // built by CI before `blogwright deploy`}See Non-Astro sites for the pattern this supports.
invalidationMaxPaths
Section titled “invalidationMaxPaths”number · optional · default: 1000
If a deploy changes more CloudFront paths than this, the CLI invalidates /* instead of listing every path. Deploys that change fewer paths invalidate only the changed ones; an identical redeploy invalidates nothing.
CloudFront serving
Section titled “CloudFront serving”defaultRootObject
Section titled “defaultRootObject”string · optional · default: "index.html"
The CloudFront distribution’s default root object — the object served for requests to the bare origin root.
boolean · optional · default: false
Single-page app mode: CloudFront serves /index.html with a 200 for unknown paths (client-side routing) instead of the 404 page. Applies to the main distribution at creation. Previews are unaffected — the shared preview distribution’s error responses cannot be host-routed. See Non-Astro sites.
robots.txt and sitemap.xml policy, with environment-aware defaults: production is indexable with a sitemap; every other environment — including previews — blocks crawlers and skips the sitemap.
seo.robots
Section titled “seo.robots”"auto" | "index" | "noindex" | "off" · optional · default: "auto"
How the deploy pipeline writes robots.txt into the published site:
auto(default) — production gets an indexablerobots.txt(Allow: /, plus aSitemap:line when the sitemap is on); every other environment getsDisallow: /.index/noindex— force either policy regardless of environment.off— don’t managerobots.txtat all; whatever the build produced is left alone.
Preview deploys always count as non-production for auto, even when the preview stack deploys from a production config.
seo.robotsContent
Section titled “seo.robotsContent”string · optional · no default
Explicit robots.txt body, published verbatim in place of the generated one. Ignored when seo.robots is "off".
seo.sitemap
Section titled “seo.sitemap”"auto" | "on" | "off" · optional · default: "auto"
sitemap.xml generation, built from the site’s HTML pages with absolute URLs. auto turns it on in production and off everywhere else; on/off force it. Requires a resolvable site origin — the custom domain, or the CloudFront domain otherwise.
Site layout (paths)
Section titled “Site layout (paths)”Repo-relative paths describing the consuming site’s layout. The defaults match a stock Astro project; override them when yours differs.
// A SvelteKit SPA in a monorepo subdirectory:{ "spa": true, "paths": { "app": "web", "dist": "web/build" },}paths.app
Section titled “paths.app”string · optional · default: "."
Directory the MicroVM builds in — pnpm install && pnpm build run here. "." for an app at the repo root; "web" for a monorepo subdirectory. Must be repo-relative with no .. segments.
paths.dist
Section titled “paths.dist”string · optional · default: "dist"
Built output directory the MicroVM publishes, relative to the repo root (not to paths.app). Same repo-relative validation as paths.app.
paths.publicDir
Section titled “paths.publicDir”string · optional · default: "public"
The static-asset directory served at the site root (Astro’s public/). The pds commands write the OAuth client documents and the standard.site well-known file at protocol-fixed locations under this directory — their URL paths are part of the OAuth client id and the standard.site spec, so only the directory root varies.
paths.content
Section titled “paths.content”string · optional · default: "src/content/blog"
Content-collection directory pds sync enumerates for posts.
paths.atprotoJson
Section titled “paths.atprotoJson”string · optional · default: "src/data/atproto.json"
JSON file the site imports to render its document <link> tags, written by pds init.
standard.site publishing (pds)
Section titled “standard.site publishing (pds)”object · optional · no default
AT Protocol / standard.site publishing. When the section is absent, publishing is entirely inert. { "name": "My Blog" } is enough to enable it — see Publishing to standard.site.
{ "pds": { "name": "My Blog", "description": "Notes on things", // optional "handleResolver": "https://public.api.bsky.app", // optional; the default "secretName": "example/atproto", // optional; defaults to <siteName>/atproto },}pds.name
Section titled “pds.name”string · required (within pds)
Publication display name — the name on the site.standard.publication record. Must be non-blank.
pds.description
Section titled “pds.description”string · optional · no default
Optional publication description.
pds.handleResolver
Section titled “pds.handleResolver”string · optional · default: "https://public.api.bsky.app"
Resolver pds login uses to turn a handle into a DID. Must be an https: URL. Unused when logging in with a bare DID — the PDS endpoint itself is always discovered from the DID document during OAuth.
pds.secretName
Section titled “pds.secretName”string · optional · default: "<siteName>/atproto"
Name of the Secrets Manager secret holding the OAuth client key and session. Limited to the characters A-Z a-z 0-9 _ / + = . @ -.
Validation summary
Section titled “Validation summary”The CLI validates config at load time and fails with a specific error rather than deploying something broken:
| Key | Rule |
|---|---|
siteName |
required; ^[a-z0-9-]+$; derived bucket name ≤ 63 chars |
region |
must be non-empty |
microvm.memory |
one of 0.5, 1, 2, 4, 8 |
microvm.maxDurationSeconds |
1–28800 |
retention.*Days |
positive |
seo.robots |
auto, index, noindex, or off |
seo.sitemap |
auto, on, or off |
sourceInclude[] |
repo-relative, no leading /, no .. |
paths.app, paths.dist |
non-empty, repo-relative, no .. |
pds.name |
non-blank when pds is present |
pds.handleResolver |
valid https: URL |
pds.secretName |
characters [\w/+=.@-] only |
For the resource names derived from siteName and the environment, see the architecture reference. For the flags that interact with config (--config, --env, --domain), see the CLI reference.