Deploy a static site to WordPress

Why your existing hosting can already serve a build, what's actually left to set up, and a deploy guide for each builder.

Your WordPress hosting can already serve a static build. It has been serving files all along - every image in /wp-content/uploads/ is handed back by the web server without WordPress being involved. So deploying a React, Vite, Astro or Lovable build to WordPress comes down to two things: getting the build files onto that host, and deciding which URL gets which file.

Why a build output can live on WordPress hosting at all

Look at the rewrite rules WordPress writes into your own .htaccess:

# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

The two RewriteCond lines carry the whole argument. !-f means "only if the requested filename is not an existing file"; !-d means "and not an existing directory." A request reaches index.php - and only then boots PHP, connects to MySQL and renders a page - when nothing on disk answers it. Anything that does exist is returned directly. nginx hosts do the same thing with try_files.

A static build is nothing but things that exist: an index.html, hashed JS and CSS under /assets/, images, a favicon. Serving those asks nothing of your host it wasn't doing already, and skips the per-request PHP and database work a themed page does. That's the "static is faster" claim, minus the mysticism.

Which means hosting was never the hard part. The hard parts are: which build is live right now, what answers a URL that has no matching file (the deep-link problem every single-page app has), and what must stay with WordPress - wp-admin, wp-login.php, the REST API and cron all still need PHP. This is the gap Parkstatic sits in. Your host already serves files; the plugin decides which files. It pre-renders each route to real HTML so crawlers get content rather than an empty <div id="root">, keeps each deploy as a version you can roll back to, and leaves the admin paths alone.

The part that isn't automatic

Dragging dist/ over FTP after every change is why most people give up and pay a second host. The fix is to make the build a CI job: a workflow at .github/workflows/deploy.yml using ParkStatic/action@main, authenticated with a PARKSTATIC_SECRET repository secret, runs on every push to main, builds the project and uploads the output. GitHub Actions is free on public repositories and includes 2,000 minutes a month on the GitHub Free plan for private ones (checked August 2026) - a Vite build spends one or two. The setup walkthrough has the full sequence.

When you should not do this

  • You don't already pay for WordPress hosting

    Buying WordPress hosting to serve a static build is a worse deal than Cloudflare Pages or GitHub Pages, which will host it for nothing. It only saves money when the bill already exists.

  • Your app needs a server at request time

    API routes, Next.js Server Actions, a database, logins, anything reading a secret at runtime - a folder of files cannot do those. Keep them on a host that runs Node.

  • You want per-PR previews, edge functions or team seats

    Vercel and Netlify do those and I don't. The free WordPress.org version ships a bundled demo only - it won't deploy your project - and one licence covers one WordPress site, so ten sites means ten licences.

Weighing this against a dedicated frontend host? Compare all hosting options.

If your build is static and the hosting bill already exists

Parkstatic is $29.99 a year or $89.99 once, for one WordPress site (checked August 2026).