Hotlink protection helps prevent other websites from embedding images or directly linking to files hosted on your server. When a remote page loads your image, your server or CDN still delivers the file, even if the visitor never opens your website.
This can increase bandwidth use and hosting costs. The examples below show how to configure basic referrer-based protection on Apache and Nginx, while avoiding common redirect-loop and file-type mistakes.

What is hotlinking?
Hotlinking, also called inline linking or direct linking, occurs when another website embeds a media URL hosted on your site. The visitor sees the image on the other website, but your server or content delivery network supplies the file.
Hotlinking can increase bandwidth use, server requests, and hosting costs. It can also make it easier for another site to display your media without sending visitors to the original page.
Referrer-based hotlink protection checks the HTTP Referer header and allows requests that appear to come from your own domain. Requests with an unapproved referrer can be denied or redirected to a replacement image.

Before you enable hotlink protection
- Back up your current server configuration or
.htaccessfile. - Allow your main domain and any legitimate subdomains that serve your media.
- Decide how to handle requests with no referrer. Allowing them avoids blocking some privacy-conscious browsers and direct visits, but it also means a request without a referrer can still load the file.
- Remember that the
Refererheader can be omitted or forged. Referrer checks help reduce casual hotlinking, but they are not access control or a security boundary. - Test images, downloads, feeds, social previews, and your own site's pages after applying the rule.
Prevent hotlinking on Apache with .htaccess
This example protects common image formats and redirects an external hotlink to a replacement image. It deliberately excludes the replacement image itself to prevent a redirect loop. Replace example.com with your domain and upload nolink.webp to your document root.
RewriteEngine On
# Do not redirect the replacement image to itself.
RewriteCond %{REQUEST_URI} !^/nolink\.webp$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://([a-z0-9-]+\.)?example\.com(/|$) [NC]
RewriteRule \.(jpe?g|png|gif|webp|avif)$ /nolink.webp [R=302,L,NC]
The rule allows requests with an empty referrer and requests from your domain or its subdomains. The temporary 302 redirect is useful while testing. Once you have confirmed the behavior, you can decide whether a permanent redirect is appropriate. Do not use a permanent redirect while you are still testing or changing the rule.
If you also want to block hotlinked archives instead of displaying an image in place of a download, use a separate rule:
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://([a-z0-9-]+\.)?example\.com(/|$) [NC]
RewriteRule \.(zip|rar|7z)$ - [F,L,NC]
Apache must have mod_rewrite enabled and allow the relevant rewrite directives in that directory. If your host manages these rules for you, check with the host before editing .htaccess.
Prevent hotlinking on Nginx
Nginx does not read .htaccess. Configure hotlink protection in the appropriate server configuration, and make sure the locations do not conflict with existing image, upload, or cache rules.
The following example allows requests with no referrer and requests from example.com or its subdomains. It redirects external image requests to /nolink.webp, while blocking external archive requests with a 403 response.
# The replacement image must bypass the hotlink-checking regex.
location = /nolink.webp {
# Served normally from the site's document root.
}
location ~* \.(?:jpe?g|png|gif|webp|avif)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 302 /nolink.webp;
}
}
location ~* \.(?:zip|rar|7z)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
Replace the example domain with your own. The exact location blocks must be integrated with your existing Nginx configuration rather than pasted blindly, especially if you already have locations for media, uploads, PHP, or caching. The exact-match location for /nolink.webp is important because it prevents the replacement image from being redirected back to itself.
After editing, test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
If the configuration test reports an error, fix it before reloading. Do not reload a configuration that fails validation.
What about CDNs and caching?
If a CDN caches your images, an origin-server rule may not run for every request. A cached image can be served from the CDN without contacting your origin. When available, enable hotlink protection or an equivalent referrer rule at the CDN edge as well, and verify that the rule runs before the asset is served from cache.
After changing hotlink rules, purge relevant CDN and page caches if necessary. Test from an external page and from your own site to confirm that legitimate images still load.
Limitations of referrer-based protection
Referrer checks are a practical deterrent, not a guarantee. Some browsers and privacy tools omit the referrer, and non-browser clients can send a forged header. Allowing empty referrers preserves compatibility but also permits direct requests without a referrer. If the files must be private, use authentication or signed, expiring URLs rather than hotlink protection.
Final thoughts
Hotlink protection can reduce casual external embedding and unnecessary bandwidth use. Choose rules that match the files you want to protect, keep the replacement image outside the redirect rule, and test carefully with your actual Apache, Nginx, or CDN configuration.
