Statamic sits on top of Laravel, but its content model is unusual for a CMS: pages, entries, collections, and taxonomies live as YAML and Markdown files inside content/, not in a database. That single fact reshapes every migration. A move that would be a database export-and-import job on WordPress becomes primarily a file transfer here, and the pieces that actually break during a domain change are the environment file, the application cache, and the compiled Stache index that Statamic uses to read all those flat files quickly.

Understanding what is stateful and what is disposable prevents most migration failures. Your content and configuration are stateful and must move intact. The bootstrap/cache/, storage/framework/cache/, and the Stache under storage/statamic/ are disposable and, if copied across a domain change without being cleared, will actively serve the wrong URLs and cached fragments.

What actually moves in a Statamic migration

Before touching anything, map the moving parts. On a standard install the important directories inside your document root (for example /home/user/public_html or a subfolder you point the domain at) are:

  • content/ — all entries, pages, collections, taxonomies, globals, and navigation as flat files. This is the heart of the site.
  • resources/ — Antlers/Blade templates, views, and blueprints.
  • public/ — the web-facing entry point containing index.php and compiled assets.
  • storage/ — logs, sessions, compiled views, and the Stache cache.
  • .env — the environment file holding APP_URL, APP_KEY, database credentials (if used), and mail settings.
  • users/ — control panel user accounts, when you are not using database-backed users.
  • Any asset containers, commonly under public/assets/ or a path defined in content/assets/.

If your site uses database features (a database session driver, cache driver, or the Eloquent users driver), you will also have a MySQL database to export. Most content-only Statamic sites do not, and the migration is purely files. Confirm which case you are in by opening .env and checking SESSION_DRIVER, CACHE_STORE, and DB_CONNECTION. If DB_CONNECTION is set to mysql and it is referenced by drivers, treat the database as part of the payload.

To transfer files with an unprivileged account, use cPanel File Manager or DirectAdmin File Manager to compress the entire Statamic root into a single archive, then download it or move it. In cPanel Jupiter, select the top-level Statamic folder, choose Compress, pick Zip Archive, download the resulting file, and upload it into the new account before extracting. Compressing first preserves the directory structure and dotfiles like .env and .htaccess that individual drag-and-drop uploads often skip. After extraction on the destination, confirm the hidden files arrived by enabling Settings > Show Hidden Files (dotfiles) in File Manager.

Rewriting .env, APP_URL, and the APP_KEY trap

The .env file is where a domain change lives or dies. Open it in File Manager's editor and update APP_URL to the exact new address, including the scheme:

APP_ENV=production
APP_DEBUG=false
APP_URL=https://newdomain.com
APP_KEY=base64:existing-key-do-not-regenerate

Match the URL to how visitors actually reach the site. If your certificate covers www and you canonicalize to it, write https://www.newdomain.com. A mismatch here produces mixed-content warnings, broken control panel logins, and asset URLs pointing at the old host.

The single most damaging mistake during a Statamic migration is regenerating or losing the APP_KEY. That key encrypts sessions and any encrypted values. If you copy the site but let the new environment generate a fresh key, existing encrypted data and sessions become unreadable, and control panel logins can fail with decryption errors. Carry the exact APP_KEY string from the old .env to the new one. If you genuinely have no key (a brand-new build), that is a different situation, but a migration must preserve it verbatim.

When your PHP version differs between the old and new accounts, set it in the panel before loading the site. In cPanel use MultiPHP Manager to assign the domain to a supported release (Statamic 5 needs PHP 8.2 or newer; Statamic 4 wants 8.1+), and use PHP Selector under CloudLinux to enable required extensions such as gd, intl, mbstring, curl, and fileinfo. If you need a higher memory ceiling or larger upload limits during the transfer, add them through a .user.ini file in the document root rather than any server-wide file:

memory_limit = 512M
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 120

The .user.ini is honored by LiteSpeed for the account and takes a few minutes (or a PHP process recycle) to apply. If you edited database credentials because the site uses MySQL, import your SQL dump through phpMyAdmin into a database you create in cPanel's MySQL Databases tool, then point DB_HOST=localhost, DB_DATABASE, DB_USERNAME, and DB_PASSWORD at the new credentials.

Clearing the Stache, static cache, and stale rewrites

After files and environment are in place, the site may still serve old URLs or 500 errors because the Stache and Laravel caches were copied from the source. Since you have no SSH access to run php please cache:clear, delete the disposable cache directories through File Manager. Remove the contents of:

  • bootstrap/cache/ — delete config.php, routes-*.php, and packages.php if present. These pin the old APP_URL.
  • storage/framework/cache/data/ — clear cached application data.
  • storage/framework/views/ — remove compiled Blade/Antlers views.
  • storage/statamic/stache/ — delete the Stache index so Statamic rebuilds it from your flat files on the next request.
  • Any static cache output, typically storage/statamic/static/ or a public/static/ path if full static caching was enabled.

Delete the files inside these folders, not the folders themselves, and confirm the remaining structure stays writable. The first page load after clearing will be slow while the Stache rebuilds, which is expected. If the control panel throws a decryption or session error even after clearing, revisit the APP_KEY and also clear storage/framework/sessions/.

Check the document root's .htaccess, which for Statamic normally lives in public/. If your account serves the domain directly from public_html and the Statamic public/ contents were merged in, verify the rewrite still routes everything to index.php:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

If you are forcing HTTPS or a canonical host after the domain swap, add the redirect above the front-controller rule so it runs first:

RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} !^www\.newdomain\.com$ [NC]
RewriteRule ^ https://www.newdomain.com%{REQUEST_URI} [L,R=301]

When a page still fails, open storage/logs/laravel.log in File Manager. That log records the real fatal error—missing extension, unwritable Stache directory, or a stale absolute path—far more usefully than the browser's generic 500. Once APP_URL is correct, the APP_KEY is preserved, the caches are cleared, and permissions on storage/ and content/ allow the web user to read and write, the migrated Statamic site should render on the new domain with its full content intact.