# Set the Onion-Location Header

> Set the Onion-Location header in Nginx or a meta tag so Tor Browser offers your onion site to clearnet visitors automatically.

- **URL:** https://hackindex.io/blog/onion-location-header
- **Authors:** [Joshua](https://hackindex.io/authors/joshua.md)
- **Published:** 2026-09-12
- **Updated:** 2026-09-12

The Onion-Location header tells Tor Browser that a clearnet site has an onion version, so visitors move over with one click. This page sets the header on the clearnet mirror from the [hardened onion service](https://hackindex.io/blog/hardened-onion-service-ubuntu) build. It applies only to the clearnet side, never the onion itself.

## How the Onion-Location header works

When Tor Browser loads a clearnet page that carries the header, it shows a purple pill in the address bar that reads onion available. The visitor clicks it to switch, or opts in once to redirect automatically on every visit. You set it as an HTTP header or as an HTML meta tag, and both behave the same.

## Requirements for the header

Tor Browser only honors the header when three conditions hold. The value is a valid URL with an http or https scheme and a .onion hostname. The page that sends it runs over HTTPS. The page that sends it is not itself an onion site. Set it on the clearnet vhost, so a visitor on the public site learns about the onion.

Add the header to the clearnet HTTPS server block in nginx. Here `$ONION_ADDRESS` is your onion hostname, while `$request_uri` is an nginx variable that carries the path across, so a visitor lands on the same page on the onion.

```nginx
add_header Onion-Location http://$ONION_ADDRESS$request_uri always;
```

The always flag sends the header on error responses too, not only on a 200. Watch the same inheritance rule as the base build: if a location block sets its own add_header, nginx drops the server level headers there, so repeat it where you override.

### Meta tag alternative

When you cannot set headers, put the same value in an HTML meta tag in the page head. This suits a static host or a CMS where the header is out of reach.

```xml
<meta http-equiv="onion-location" content="http://$ONION_ADDRESS/">
```

## Test the Onion-Location header

Fetch the clearnet site over HTTPS and look for the header in the response. In Tor Browser, the purple pill appears in the address bar.

```bash
curl -I https://$CLEARNET_DOMAIN/
# HTTP/2 200
# server: nginx
# onion-location: http://ahxaebv2jyncy5u3xn7anbsgdamowr6mhcioyiiyblxec4ud5geaiy5d.onion/
# content-type: text/html
```

Do not confuse this with Alt-Svc. Alt-Svc routes the connection over an onion in the background while the address bar keeps the clearnet name, so the visitor never sees the onion. Onion-Location does the opposite: it advertises the onion and moves the visitor onto it.

The onion this points at should be the hardened service from the [main build](https://hackindex.io/blog/hardened-onion-service-ubuntu). If you serve several addresses, set the header per site as covered in [running multiple onion services on one host](https://hackindex.io/blog/multiple-onion-services).

## References

- [Tor Onion-Location](https://community.torproject.org/onion-services/advanced/onion-location/) - Requirements and web server setup for the header and meta tag.
- [Nginx add_header](https://nginx.org/en/docs/http/ngx_http_headers_module.html) - Directive reference for setting response headers, including always.
