The HSTS header (HTTP Strict Transport Security) tells browsers to only connect to your WordPress site over HTTPS. Without it, visitors could accidentally land on an insecure HTTP version of your page, leaving them vulnerable to man-in-the-middle attacks. Once the header is in place, browsers remember your preference and automatically upgrade every request to HTTPS for the duration you specify.
What Does the HSTS Header Actually Do?
When a browser receives the Strict-Transport-Security header, it stores that information locally. For every future visit within the specified max-age window, the browser will refuse to connect over plain HTTP. It does not even attempt an HTTP connection first; it goes straight to HTTPS. This eliminates the brief window where an attacker could intercept the initial HTTP request and redirect the user to a malicious page.
The header has three main parameters:
- max-age: how long (in seconds) the browser should remember to force HTTPS. A value of
31536000equals one year. - includeSubDomains: applies the rule to every subdomain as well (e.g., blog.example.com, shop.example.com).
- preload: signals that you want your domain included in the browser's built-in HSTS preload list, so the very first visit is also protected.
Before You Start: Make Sure HTTPS Works Everywhere
This step is critical. Once HSTS is active, browsers will not let visitors fall back to HTTP. If your SSL certificate is expired, misconfigured, or missing on a subdomain, those pages become completely unreachable for the duration of your max-age setting. Before enabling anything, verify the following:
- Your SSL certificate is valid and not close to expiring.
- All pages on your site load correctly over
https://. - There are no mixed-content warnings in the browser console (HTTP resources loaded on HTTPS pages).
- If you plan to use
includeSubDomains, every subdomain must have a valid certificate and serve content over HTTPS. - Your WordPress Site URL and WordPress Address (in Settings > General) both use
https://.
Adding HSTS via Apache .htaccess
If your WordPress site runs on Apache (most shared hosting providers use Apache), you can add the header directly in the .htaccess file located in your WordPress root directory. Open the file with a text editor or your hosting provider's file manager, and add the following block before the # BEGIN WordPress section:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>The IfModule wrapper ensures that Apache only processes this directive if mod_headers is enabled. On most hosts it is enabled by default, but the wrapper prevents a 500 error on servers where it is not available.
Adding HSTS via Nginx
For Nginx-based hosting (common with managed WordPress hosts like Kinsta, Cloudways, or SpinupWP), add the header inside your server block. The configuration file is usually located at /etc/nginx/sites-available/yourdomain.com or within a custom Nginx include directory provided by your host:
server {
listen 443 ssl;
server_name example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# ... rest of your server config
}The always keyword at the end is important. Without it, Nginx only sends the header on successful (2xx) responses. With always, it is included on error pages (4xx, 5xx) too, which is the correct behavior for security headers.
After editing the config, test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginxAdding HSTS via PHP in functions.php
If you do not have access to server configuration files (some managed hosts restrict this), you can send the header from PHP. Add the following to your active theme's functions.php file or, better yet, to a site-specific plugin so it survives theme updates:
function iwp_add_hsts_header() {
if ( ! is_admin() ) {
header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' );
}
}
add_action( 'send_headers', 'iwp_add_hsts_header' );Keep in mind that PHP-based headers only apply to pages processed by WordPress. Static files (images, CSS, JS) served directly by Apache or Nginx will not carry this header. For complete coverage, the server-level approach is always better.
Using a WordPress Plugin to Set HSTS
If you prefer a no-code approach, several plugins can handle HSTS for you:
- Really Simple SSL (Pro): the Pro version includes a security headers module where you can toggle HSTS on and configure
max-ageandincludeSubDomainsfrom the dashboard. - HTTP Headers: a free plugin that gives you a UI to set various security headers, including Strict-Transport-Security.
- Headers Security Advanced & HSTS WP: specifically built for security headers with an easy toggle for HSTS and preload.
Plugins are convenient, but they add an extra dependency. If the plugin is deactivated or removed, your headers disappear too. For something as fundamental as HSTS, a server-level configuration is more reliable.
Safe Rollout Strategy: Start Small, Then Increase
Jumping straight to a one-year max-age is risky if you have not tested everything. If something goes wrong, browsers will keep forcing HTTPS for an entire year, and there is no way to "undo" the header from the server side once a browser has cached it. Follow this gradual approach instead:
- 5 minutes: set
max-age=300and browse your site. Check that every page loads, forms submit correctly, and no mixed-content warnings appear. - 1 day: increase to
max-age=86400. Let it run for a day or two while monitoring your site. - 1 week: bump to
max-age=604800. At this point, you should feel confident that HTTPS works everywhere. - 1 year: set the final value of
max-age=31536000. This is the minimum required for HSTS preload submission. - Add includeSubDomains: only do this once all subdomains are confirmed to work on HTTPS.
- Add preload: add the
preloadflag and submit your domain at hstspreload.org.
Submitting Your Site to the HSTS Preload List
The HSTS preload list is a directory of domains that browsers ship with built-in HSTS enforcement. This means even the very first visit to your site will be over HTTPS, before the browser has ever seen your header. To qualify, your site must meet these requirements:
- Serve a valid SSL certificate.
- Redirect all HTTP traffic to HTTPS on the same host.
- Send the
Strict-Transport-Securityheader withmax-ageof at least31536000(one year). - Include the
includeSubDomainsdirective. - Include the
preloaddirective.
Visit hstspreload.org, enter your domain, and submit. Be aware that removal from the preload list takes months and requires a browser update cycle, so only submit when you are fully committed to HTTPS.
How to Verify Your HSTS Header with Browser DevTools
After adding the header, you can quickly confirm it is working:
- Open your site in Chrome or Firefox.
- Press F12 to open DevTools.
- Go to the Network tab and reload the page.
- Click on the main document request (usually the first one).
- Scroll down to Response Headers.
- Look for
Strict-Transport-Security. You should see your configured value.
You can also use the command line to check:
curl -sI https://example.com | grep -i strict-transportIf the header does not appear, double-check that you are visiting the HTTPS version (not HTTP) and that your server configuration changes have been saved and reloaded.
Common HSTS Mistakes and How to Avoid Them
- Setting HSTS on HTTP responses: the header is ignored by browsers when served over plain HTTP. It only takes effect on HTTPS responses.
- Forgetting static file coverage: if you set HSTS via PHP, static files bypass WordPress and will not carry the header. Use server-level configuration for full coverage.
- Using includeSubDomains without checking subdomains: if you have a subdomain that does not support HTTPS (e.g., an old staging server), it will become inaccessible.
- Jumping to a long max-age too quickly: always start with a short duration and work your way up.
- Forgetting to renew your SSL certificate: with HSTS active and an expired certificate, your site is completely unreachable. Set up auto-renewal with Let's Encrypt or your certificate provider.
Verify Your HSTS Setup with InspectWP
After adding the header, run a new InspectWP scan on your site. The security headers section of your report will show the Strict-Transport-Security header status. If everything is configured correctly, it will appear as green (present). If you have also set up other security headers, check those as well to get a complete picture of your site's security posture.