Applies to: websites on any host, cPanel Redirects, Nginx and Apache; tested with Nginx 1.31.6 and Apache 2.4.68 (mod_rewrite) in Docker
“Hiding a URL” usually means one of two things: showing your domain in the address bar while the content comes from somewhere else (URL masking or domain masking), or showing clean addresses on your own site without file names such as about.php or ?id=42. The second is easy and safe. The first is possible, but often the wrong fix: if the other site is also yours, pointing the domain at it or redirecting is better.
Option 1: frame masking (fragile)
“Masked forwarding”, offered by some domain panels, serves a page on your domain that loads the other site in a full-screen frame:
<!DOCTYPE html> <html><head><title>Example</title></head> <body style="margin:0"> <iframe src="https://target.example.com/" style="border:0;width:100%;height:100vh"></iframe> </body></html>
Why it often fails:
- Many sites refuse to be framed. A site that sends
X-Frame-Options: DENYorSAMEORIGIN, or aContent-Security-Policywithframe-ancestors, is not shown inside your frame. When we checked, Google sentSAMEORIGINand GitHub sentdeny. - HTTP inside HTTPS is blocked. If your page uses HTTPS and the framed site only HTTP, browsers block it as mixed content.
- The address never changes. Visitors can’t bookmark or share an inner page; every link they copy is your home page.
- Nothing is really hidden. The real address is in the page source, and your domain has no content of its own for search engines.
cPanel’s own Redirects page doesn’t offer masking: according to cPanel, it creates Permanent (301) or Temporary (302) redirects only.
Option 2: reverse proxy (works, but only for content you control)
On a server where you manage the web server, Nginx can fetch the other site and serve it under your domain. The address bar shows your domain and inner pages keep their own paths:
server {
listen 80;
server_name www.example.net;
location / {
proxy_pass https://target.example.com;
proxy_set_header Host target.example.com;
proxy_ssl_server_name on;
}
}
In our test, a request to our Nginx returned the target site’s page with 200 OK. Things to know:
- Only do this for sites you own or have permission to use. Serving someone else’s site under your domain can break their terms and copyright.
- Absolute links inside the pages still point to the original domain, so visitors can end up there after one click.
- Add HTTPS for your domain on the proxy, as for any site.
With Apache the same is done with mod_proxy: see Apache as a reverse proxy.
Better: point or redirect the domain
- Same site, extra domain: point the domain’s DNS at the server that hosts the site and add it as an alias there, so the site answers on both names. In cPanel: park a domain.
- Moving to a new address: use a 301 redirect. Visitors see the new address, and search engines are told the page has moved permanently. See redirect a website in cPanel or permanent 301 redirects.
Hide file names and query strings on your own site
To show /about instead of /about.php, or /product/42 instead of /about.php?id=42, use an internal rewrite. The visitor’s address stays as typed, because Apache fetches the other file on the server without sending a redirect. In .htaccess (Apache with mod_rewrite enabled):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^/]+)$ $1.php [L]
RewriteRule ^product/([0-9]+)$ about.php?id=$1 [L,QSA]
In our test, /about answered 200 OK with the output of about.php and no Location header, and /product/42 printed id=42. Adding R=301 to a rule turns it into a visible redirect instead, which is not what you want here. Update the links in your pages to the new short addresses too.
For WordPress, use Settings, Permalinks instead of your own rules.
Related: redirect URLs with the Apache web server and redirect HTTP to HTTPS with .htaccess.
Official documentation: MDN: X-Frame-Options, cPanel: Redirects and Apache: RewriteRule flags.