Skip to main content

Configuration Reference

Purpose

This page centralizes ReactWP values that are read outside normal theme code: Node environment variables, generator arguments, WordPress constants, runtime filters, build budgets, and configuration precedence.

Environment variables are read when the corresponding Node process starts. WordPress constants should be defined in src/core/wp-config.php or injected by the hosting environment before the ReactWP runtime loads.

Static Generation

The static generator accepts environment variables and equivalent command-line arguments.

Environment variableCLI argumentDefaultMeaning
RWP_SITE_URL--sitenone, requiredWordPress origin used for bootstrap and sitemap requests
RWP_THEME--themereactwptheme slug used to resolve render input/output paths
RWP_SSG_MAX_ROUTESnone5000maximum sitemap routes, clamped between 1 and 50000
RWP_SSG_MAX_JSON_BYTESnone10485760maximum API JSON response, clamped between 1 KiB and 50 MiB
RWP_SSG_MAX_HTML_BYTESnone5242880maximum rendered fragment, clamped between 1 KiB and 20 MiB
RWP_SSG_TIMEOUTnone15000request timeout in milliseconds, clamped between 1000 and 120000
RWP_SSG_ALLOW_EXTERNAL_OUTPUTnone0set to 1 only when a reviewed output path must leave the ReactWP project
none--outputdist/wp-content/themes/<theme>/assets/render/staticstatic manifest and fragment destination
none--rendererdist/wp-content/themes/<theme>/assets/render/server.cjsuniversal renderer bundle used during generation

Examples:

$env:RWP_SITE_URL = 'https://example.com'
$env:RWP_THEME = 'my-theme'
npm run generate
npm run generate -- --site=https://example.com --theme=my-theme

Advanced output override:

npm run generate -- \
--site=https://example.com \
--theme=my-theme \
--renderer=../dist/wp-content/themes/my-theme/assets/render/server.cjs \
--output=../tmp/reactwp-static

RWP_SITE_URL is also read by npm run prod. When present, the production theme pipeline runs static generation after successful asset and render builds. When absent, SSG is skipped without failing production.

The WordPress site must be reachable from the build process, and its public ReactWP bootstrap and sitemap endpoints must return the routes to generate.

Local HTTPS Certificates

On Node versions that expose the system certificate APIs, the generator adds the operating system's trusted CA certificates to Node's normal CA list before making requests. A Laragon or development root certificate installed in Windows can therefore validate normally without disabling TLS security.

Test the endpoint independently when HTTPS still fails:

node --use-system-ca -e "fetch('https://example.test/wp-json/reactwp/v1/bootstrap').then(r => console.log(r.status))"

For an older Node version or a CA that is not installed in the operating system, point Node at the CA certificate explicitly:

$env:NODE_EXTRA_CA_CERTS = 'C:\path\to\development-root-ca.pem'
npm run generate -- --site=https://example.test

Do not use NODE_TLS_REJECT_UNAUTHORIZED=0. It disables certificate verification instead of trusting one known development authority.

Node SSR Service

npm run serve:ssr starts the built serve.mjs runtime. It reads:

VariableDefaultUnitMeaning
RWP_RENDER_BUNDLEsibling server.cjspathalternate universal renderer bundle
RWP_SSR_HOST127.0.0.1hostinterface used by the Node HTTP server
RWP_SSR_PORT3100portlistening port
RWP_SSR_SECRETemptystringshared render-request secret
RWP_SSR_BODY_LIMIT5242880bytesmaximum JSON request body
RWP_SSR_RESPONSE_LIMIT5242880bytesmaximum JSON response body; the rendered HTML is checked before it is returned
RWP_SSR_TIMEOUT8000millisecondsmaximum duration of one Node render
RWP_SSR_CONCURRENCY8requestsmaximum simultaneous renders
RWP_SSR_ALLOW_INSECURE_LOOPBACK0boolean1 permits secretless loopback only when WordPress also explicitly permits local/development insecure loopback

The service exposes:

GET /health
POST /render

GET /health returns ok, the active render count, and the configured concurrency. Responses from the render service use Cache-Control: no-store because WordPress, not Node, owns HTML cache policy.

The Node service requires an RWP_SSR_SECRET of at least 32 characters on loopback and remote hosts. The only exception is an explicit local-development opt-in: the Node process must set RWP_SSR_ALLOW_INSECURE_LOOPBACK=1, WordPress must run as local or development, and rwp_ssr_allow_insecure_loopback must return true. Never use that exception in production.

Example process configuration:

$env:RWP_SSR_HOST = '127.0.0.1'
$env:RWP_SSR_PORT = '3100'
$env:RWP_SSR_SECRET = 'replace-with-a-long-random-value'
$env:RWP_SSR_CONCURRENCY = '8'
npm run serve:ssr

WordPress SSR Connection

Configure WordPress with:

define('RWP_SSR_ENDPOINT', 'http://127.0.0.1:3100/render');
define('RWP_SSR_SECRET', getenv('RWP_SSR_SECRET'));
ConstantDefaultMeaning
RWP_SSR_ENDPOINTemptycomplete Node /render URL; an empty value disables runtime SSR and static regeneration
RWP_SSR_SECRETenvironment fallbackvalue sent in X-ReactWP-Render-Secret

The WordPress secret and Node secret must match. Never commit a production secret directly to the repository.

WordPress accepts loopback renderer URLs by default. A remote renderer must use HTTPS and explicitly opt in through rwp_ssr_allow_remote_endpoint.

WordPress Render Filters

These filters control PHP-to-Node behavior:

FilterDefaultUnitPurpose
rwp_ssr_endpointRWP_SSR_ENDPOINTURLoverride the render endpoint
rwp_ssr_timeout2.5secondsWordPress HTTP request timeout
rwp_ssr_circuit_seconds20secondstemporary fallback period after a renderer failure
rwp_ssr_max_html_bytes5242880byteslargest accepted SSR HTML response
rwp_ssr_allow_remote_endpointfalsebooleanallow a non-loopback HTTPS renderer
rwp_ssr_allow_insecure_loopbackfalsebooleanallow secretless loopback only for local/development WordPress when Node also opts in
rwp_ssr_payloadcurrent payloadarrayadd request-specific render data
rwp_ssr_cache_identitycurrent user ID for authenticated private requestsstringpartition private SSR cache entries
rwp_ssr_cache_query_keys[]keysexact query keys that may participate in cached SSR identities
rwp_ssr_cache_max_query_bytes2048bytesmaximum normalized query string considered for SSR caching
rwp_static_render_max_html_bytes5242880byteslargest static fragment WordPress will read
rwp_static_regeneration_batch_size10routesroutes processed by one regeneration cron event
rwp_static_render_manifest_pathsruntime and theme manifestspathsreplace or extend static manifest lookup
rwp_initial_render_enabledtruebooleanglobally enable static/SSR initial HTML
rwp_prerender_skip_loadertruebooleanskip the initial loader for valid pre-rendered HTML

The Node timeout and WordPress timeout are separate. By default, WordPress stops waiting after 2.5 seconds even though Node allows a render to run for up to 8 seconds. Increase both deliberately when a project truly needs longer renders; first investigate slow payload construction or template work.

Bundle Budgets

Production bundle reporting reads:

VariableDefaultMeaning
RWP_MAX_JS_ASSET_KB250raw warning limit for one JavaScript asset
RWP_MAX_INITIAL_GZIP_KB170gzip warning limit for the complete initial JavaScript entry
RWP_BUNDLE_BUDGET_STRICT0set to 1 to turn budget warnings into build failures
$env:RWP_MAX_JS_ASSET_KB = '220'
$env:RWP_MAX_INITIAL_GZIP_KB = '150'
$env:RWP_BUNDLE_BUDGET_STRICT = '1'
npm run prod

A production bundle containing React's development JSX runtime fails regardless of budget strictness.

Core Download Variables

npm run get:core reads:

VariableDefaultMeaning
REACTWP_WORDPRESS_URLofficial WordPress ZIPalternate WordPress archive
REACTWP_WORDPRESS_SHA256empty for the official sourcerequired SHA-256 for a custom WordPress archive
REACTWP_WORDPRESS_LOCALEen_USlocale used for official WordPress checksum verification
REACTWP_ACF_EDITIONinteractive choice; free outside a TTYfree, pro, or none
REACTWP_ACF_LICENSE_KEYemptyACF PRO license supplied as the official Composer username
REACTWP_ACF_SITE_URLRWP_SITE_URL, then emptycomplete licensed site URL supplied as the Composer password
REACTWP_ACF_VERSIONlatestoptional exact ACF Free or PRO version
REACTWP_ACF_COMPOSER_REPOSITORYofficial ACF repositorycompatible PRO Composer repository override
REACTWP_ACF_URLemptyreviewed private ACF PRO ZIP override
REACTWP_ACF_SHA256emptyrequired SHA-256 for a private PRO archive
REACTWP_DOWNLOAD_HOSTSofficial WordPress hostscomma-separated additional hosts for custom archives or repositories
REACTWP_COMPOSER_BINARYcomposeralternate Composer executable or command
REACTWP_PHP_BINARYdetected PHP/Laragon PHPPHP executable made available to Composer
REACTWP_SKIP_ACF0legacy 1 alias for edition none

These variables affect source preparation, not the browser runtime. PRO credentials are passed only to the temporary Composer child process and are not written into dist, Composer files, or project configuration.

Optional First-Load Scaffold

The PHP starter scaffold is controlled separately from build environment variables:

define('RWP_FIRSTLOAD', true);

The default is false. It can be enabled before or after WordPress installation. When enabled, an administrator request can seed the missing home page, permalink structure, language rows, primary menu location, and starter menu. ACF repeaters stored as 0 are considered empty, and missing ACF field references are repaired without replacing populated rows. ReactWP records the successful scaffold schema version in rwp_firstload and serializes execution with rwp_firstload_lock.

Projects can calculate the opt-in through PHP with rwp_firstload_enabled, but should keep the default disabled in reusable packages:

add_filter('rwp_firstload_enabled', function($enabled){
return $enabled;
});

The default schema version is 1. A project that adds an idempotent first-load migration can request a later run by increasing the version:

add_filter('rwp_firstload_version', function(){
return 2;
});

The completion option is updated only after the home page, language repeater, and theme-location repeater are ready. Incrementing this version is not a replacement for a general database migration system.

Remove the constant after setup. Do not treat this scaffold as a migration, fixture, or content synchronization system.

Render Configuration Precedence

ReactWP resolves render configuration from general defaults to route-specific overrides:

  1. JavaScript template registry metadata written to templates.json
  2. PHP rwp_render_templates values for the template name
  3. render values already present on the route
  4. the queried object's React Rendering ACF fields
  5. rwp_render_config
  6. rwp_render_mode for the final mode only

Later values override earlier values. Cache objects are merged by property, but a later cache.tags array replaces the earlier custom tag array while PHP resolves the route. During universal rendering, ReactWP unions the JavaScript registry tags with the final route tags, then adds baseline tags such as render:all, menu:all, settings:all, and template:<name>.

Use the JavaScript registry for project defaults, ACF for editor-controlled per-route choices, and final PHP filters only when the decision requires server context.

Cache Scope Defaults

Normalized defaults depend on render mode:

Settingclientstaticserver
cache.htmlfalsetruefalse
cache.scopepublicpublicprivate
cache.ttl000
cache.payloadtruetruetrue
cache.mediatruetruetrue
cache.tags[]; no HTML entry[] plus baseline render tags[] plus baseline render tags when rendered

For SSR, HTML caching needs both cache.html: true and a positive cache.ttl. Public SSR cache is bypassed for logged-in users. Private anonymous cache is disabled unless rwp_ssr_cache_identity returns a project-controlled identity.

Configuration Safety

  • Keep renderer secrets outside source control.
  • Prefer loopback communication between PHP and Node.
  • Do not expose the render service directly as a public frontend endpoint.
  • Keep private output private or uncached; never use one shared identity for unrelated sessions.
  • Treat remote renderer opt-in as a deployment-security decision, not a convenience flag.
  • Verify units: Node render timeout is milliseconds, WordPress HTTP timeout is seconds, and body/HTML limits are bytes.

Continue with Client, Static, and Server Rendering, Cache Tags, Build Commands, and Hooks and Filters.