How to Mask URL for Subdomain in WordPress
A visitor types blog.yourdomain.com into the address bar. What loads is really coming from a completely different server, maybe a subdomain on a different host, maybe a folder on a page builder platform, maybe a staging environment you’d rather not expose. That’s URL masking in a sentence: the address bar shows one thing, the actual source is somewhere else.
It sounds like a small trick. It isn’t, and the way most tutorials explain it glosses over a real problem: most “URL masking” techniques break in ways that aren’t obvious until weeks later, when a client asks why their site vanished from Google or why the checkout page won’t load over HTTPS. This guide walks through what actually works in 2026, what to avoid, and the tradeoffs nobody mentions in the two-minute version.
What people actually mean by “masking a subdomain”
The phrase gets used for at least three different techniques, and confusing them is where most WordPress site owners get stuck.
The first is true domain masking, sometimes called domain forwarding with masking or framed forwarding. The registrar keeps the visitor’s browser pointed at your chosen URL while quietly loading content from a second address behind an invisible iframe. Namecheap and a handful of other registrars still offer this. It is the oldest and, as covered below, the shakiest of the three.
The second is a reverse proxy. A visitor requests blog.yourdomain.com, your web server accepts that request directly, then internally fetches the page from wherever it actually lives and serves it back as if it were native content. No iframe, no visible trick. This is what serious agencies use when they need shop.yourdomain.com to point at a Shopify store, or blog.yourdomain.com to serve a Ghost instance, while keeping everything under one domain for SEO and cookie purposes.
The third is DNS-level pointing with CNAME or ALIAS records, which isn’t masking at all in the technical sense, it’s just routing, but people call it “masking” because the visible URL and the actual hosting provider end up decoupled from each other.
Picking the wrong one of these three for your actual goal is the single most common mistake in this whole topic.
Why you’d want this in the first place
Branding is the obvious one. A subdomain URL that reads store.brandname.com looks more deliberate than a raw hosting URL with a random subdirectory path, especially if the underlying platform (a help desk tool, a course platform, a booking system) generates ugly default URLs you don’t control.
There’s a consolidation reason too. If your blog runs on WordPress but your knowledge base runs on a separate SaaS tool, keeping both under yourdomain.com (via subdomains that route correctly) means cookies, analytics, and search engine trust concentrate on one domain instead of fragmenting across two.
And sometimes it’s genuinely about hiding infrastructure. An agency running a staging environment on a throwaway hosting subdomain doesn’t want that URL indexed or bookmarked by a client who might share it externally by accident.
None of these reasons justify deceiving a visitor about what site they’re actually on. Keep that line in mind, because it matters for the SEO and security sections further down.
Method 1: Domain forwarding with masking (and why it’s usually the wrong choice)
This is the method most beginner tutorials point to first because registrars make it a checkbox in the DNS panel. Go to your registrar’s domain forwarding settings, most support this at GoDaddy and Namecheap, point the subdomain at a destination URL, and toggle on “masking” or “frame forwarding.”
Under the hood, what actually happens is the registrar’s server responds to every request with a bare HTML page containing a full-screen iframe pointed at your real destination. The address bar keeps showing your subdomain because technically the browser never navigated away from it, it’s just displaying someone else’s content inside a frame.
This breaks in predictable ways. Modern browsers increasingly block cross-origin iframes from setting cookies by default (Chrome’s third-party cookie phase-out and Safari’s Intelligent Tracking Prevention both target exactly this pattern), so logged-in sessions, shopping carts, and any state-dependent feature can silently fail. SSL gets messy too: browsers show a padlock for the masking domain but the actual content inside the frame is served from a separate origin, and if that origin’s certificate doesn’t match, you get mixed-content warnings or an outright broken page. Search engines also see through it. Google’s crawler renders JavaScript and follows frames, but it generally attributes ranking signals to the framed content’s real URL, not your masked one, which defeats half the reason people wanted a clean subdomain in the first place.
There’s one narrow case where this is still fine: a short-lived internal redirect nobody needs to bookmark, log into, or find via search, like a temporary vanity link for a print ad. Outside that, skip it.
Method 2: Reverse proxy (the method that actually holds up)
A reverse proxy is what production sites use. Your web server (Nginx, Apache, or a CDN like Cloudflare) receives the request for blog.yourdomain.com, then internally forwards that request to the real backend, waits for the response, and passes it straight back to the visitor. The visitor’s browser only ever talks to your server. There’s no iframe, no separate origin, no cookie problem, and search engines index the content under the URL you actually want.
On Nginx, the core of this is a proxy_pass directive inside a server block scoped to the subdomain:
server {
listen 443 ssl;
server_name blog.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/blog.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.yourdomain.com/privkey.pem;
location / {
proxy_pass https://backend-server-ip-or-hostname;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
The proxy_set_header lines matter more than they look. Without X-Forwarded-Proto, a WordPress install behind the proxy can lose track of whether the original request was HTTPS, which causes the classic symptom of a site working fine in the browser but throwing mixed-content warnings on every asset. Without Host being passed through correctly, the backend may not recognize which site it’s supposed to serve if it’s hosting multiple domains.
If you’re on Apache instead of Nginx, the equivalent lives in a VirtualHost block using mod_proxy:
<VirtualHost *:443>
ServerName blog.yourdomain.com
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/blog.yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/blog.yourdomain.com/privkey.pem
ProxyPreserveHost On
ProxyPass / https://backend-server-ip-or-hostname/
ProxyPassReverse / https://backend-server-ip-or-hostname/
</VirtualHost>
mod_proxy and mod_ssl need to be enabled first (a2enmod proxy proxy_http ssl on Debian-based servers), which most managed WordPress hosts won’t let you touch directly. This is the real limitation: reverse proxy configuration needs server-level access, so it’s a fit for VPS hosting (DigitalOcean, Linode, a Cloudways server) or a Cloudflare Worker sitting in front of everything, not for shared cPanel hosting where you only get a file manager.
Doing it through Cloudflare instead of raw server config
If your domain’s DNS already runs through Cloudflare, a Cloudflare Worker is the more accessible version of the same idea, no VPS shell access required. A Worker script intercepts requests to the subdomain and fetches the real backend URL, then streams the response back:
export default {
async fetch(request) {
const url = new URL(request.url);
const backend = 'https://real-backend-host.com' + url.pathname + url.search;
const response = await fetch(backend, {
method: request.method,
headers: request.headers,
body: request.method !== 'GET' ? request.body : undefined,
});
return new Response(response.body, response);
},
};
You’d deploy this as a Worker route bound to blog.yourdomain.com/* in the Cloudflare dashboard. It’s the approach a lot of agencies use to sit a headless frontend or a third-party SaaS tool behind a client’s own domain without touching DNS records that would otherwise leak the real hosting provider.
One thing worth flagging about the Worker approach: Cloudflare’s free tier caps request volume and CPU time per invocation, which is plenty for a blog or documentation subdomain but worth checking against your traffic if the proxied subdomain is a full storefront. Paid Worker plans raise those ceilings, and the pricing is usage-based rather than a flat monthly charge, so cost scales with actual proxy traffic instead of a fixed tier.
Method 3: CNAME and DNS-level routing
This is the simplest option and the one most people actually need, even if it doesn’t technically “mask” anything. A CNAME record points a subdomain at another hostname at the DNS level:
- Log in to your DNS provider (this might be your registrar, or Cloudflare, or your hosting panel).
- Add a new CNAME record with the subdomain as the name (blog) and the target hostname as the value (something like your-shopify-store.myshopify.com or a load balancer hostname from your host).
- Wait for propagation, usually under an hour, occasionally up to 24-48 hours depending on your DNS provider’s TTL settings.
The visible URL becomes blog.yourdomain.com permanently, and technically savvy visitors can still discover the underlying host by running a DNS lookup, but casual visitors and search engines see a clean, first-party domain. This is exactly how most SaaS platforms handle white-label subdomains: Shopify’s custom domain setup, ConvertKit’s custom sending domains, and Intercom’s help center subdomains all work this way.
The catch is that the target service needs to actually support being reached via a custom hostname, which usually means configuring SSL on their end too. Most modern SaaS platforms handle this automatically once you add the CNAME and verify ownership. Older or smaller platforms sometimes don’t, and you’ll see certificate warnings until you provision SSL manually or switch to a reverse proxy instead.
Plugin options if you’re staying inside WordPress
If the subdomain content is another WordPress install, or you’re rewriting internal links rather than proxying an entirely separate platform, a few plugins handle the WordPress-side piece:
| Plugin | What it actually does | Fit for subdomain masking |
|---|---|---|
| Redirection | 301/302 redirects with logging and regex support | Good for permanent redirects; does not mask, the address bar changes |
| Pretty Links | Cloaked/branded short links, mainly built for affiliate links | Works as a lightweight iframe-style mask for individual links, not whole subdomains |
| WP Hide & Security Enhancer | Rewrites WordPress core paths (wp-admin, wp-content, login URL) | Solves a different problem: hiding WordPress’s identity, not subdomain routing |
Worth being precise here: none of these plugins do a true reverse proxy. Redirection changes the address bar (that’s a redirect, not a mask, and it’s the right tool when you actually want the URL to change). Pretty Links can iframe a single destination URL behind a clean link, which carries the same cookie and SEO caveats as registrar-level masking, just scoped to one link instead of a whole subdomain. WP Hide is solving WordPress fingerprinting, not cross-domain routing, it’s useful alongside a masking setup but isn’t a substitute for one.
The SEO reality check
Google’s own guidance on cloaking is unambiguous: showing search engines different content than what users see is a violation that can get a site manually penalized. Reverse proxying and CNAME routing don’t trigger this because the content Googlebot fetches is identical to what a visitor gets, same URL, same bytes. Iframe-based masking sits closer to the line because the address bar URL and the URL Google actually crawls and indexes are two different things, even though nothing is technically hidden from the crawler.
In practice this means: if the goal is a clean branded URL that should also rank in search, use a reverse proxy or CNAME. If the goal is a short-lived link that nobody needs to find organically, registrar-level masking is low-risk. Mixing the two up is where sites end up with content that never ranks despite being genuinely good, because the canonical URL search engines settled on isn’t the one anyone’s linking to.
Choosing between the three, based on what you’re actually trying to do
A quick way to sort this without re-reading the whole guide. If the destination needs logged-in sessions, a shopping cart, or anything stateful to survive, a reverse proxy is the only option that reliably holds up; iframe masking will drop sessions unpredictably depending on the visitor’s browser and privacy settings. If the destination is a SaaS platform with its own custom-domain feature already built in, use that platform’s documented CNAME flow instead of building your own proxy; you’ll fight less and get automatic SSL renewal as part of the deal. If you just need a clean, memorable link for something short-lived, like a campaign landing page hosted somewhere else for a few weeks, registrar-level masking is genuinely fine, since the downsides (cookies, SEO) don’t apply to something nobody’s meant to bookmark or find in search.
Where people get burned is applying the short-lived-link logic to something meant to be permanent. A help center, a store, a booking page: any of these will eventually need login state or search visibility, even if that’s not obvious on day one. Building those on iframe masking from the start just means migrating to a reverse proxy later, after the SEO gap has already cost months of indexing.
Testing before you call it done
A masked or proxied subdomain needs more verification than a normal DNS change, because the failure modes are quieter.
Check the SSL certificate on the new URL directly in the browser, not just “does the padlock show,” but click it and confirm the certificate actually covers blog.yourdomain.com and hasn’t silently fallen back to the backend’s own certificate. Log in to whatever account system runs on the backend and confirm sessions persist across a page reload; this is where iframe-based masking usually fails first. Run the URL through Google’s Rich Results Test or a plain curl -I request to see what headers and status codes are actually being returned, since a misconfigured proxy sometimes returns the backend’s original headers (including its real hostname) even though the page renders correctly. And check mobile Safari specifically if any part of your audience is on iOS, since Intelligent Tracking Prevention treats framed and proxied cross-origin content more aggressively than desktop browsers do.
Run this checklist again after any change to the backend platform, a plugin update, a theme switch, a migration to new hosting. Reverse proxy setups are stable but silent about breaking; nothing throws an obvious error when the Host header stops matching correctly, the site just starts behaving oddly for some visitors and not others.
Frequently Asked Questions
Does URL masking hurt SEO?
Iframe-based masking can, because it decouples the URL users see from the URL search engines index. A reverse proxy or CNAME setup does not, since the crawled URL and the visible URL are the same thing.
Can I mask a subdomain without server access?
Yes, through a Cloudflare Worker if your DNS runs through Cloudflare, or through registrar-level domain forwarding with masking if the destination doesn’t need cookies or login state to survive.
Why does my masked subdomain show a certificate warning?
Usually because the SSL certificate is issued for the backend’s real hostname, not the subdomain shown in the address bar. Reverse proxies need their own certificate for the subdomain (via Let’s Encrypt or your host’s SSL tool), separate from whatever certificate the backend uses.
Is a CNAME record the same as masking?
Not technically. A CNAME just tells DNS where to route a subdomain; the address bar updates to reflect the target once the browser follows the chain, unless the target is configured to answer specifically for your custom hostname (which is how most SaaS custom-domain features work). It gets called “masking” colloquially because the underlying hosting provider stays hidden from casual inspection.
Will this work if my subdomain points to a page builder platform like Shopify or Squarespace?
Yes, but only through their documented custom domain flow, which is almost always CNAME-based with their own SSL provisioning. Trying to reverse proxy a platform that doesn’t expect it usually breaks their asset loading and checkout flows.
What happens to existing bookmarks and backlinks if I switch from iframe masking to a reverse proxy?
Nothing breaks, since the visible URL stays the same in both cases; only the mechanism behind it changes. The main practical difference visitors and search engines will notice is that logins and cart state start working reliably, and (given time for re-crawling) the subdomain becomes eligible to rank on its own rather than having its ranking signals attributed to the framed page’s real address.
Interesting Reads