Skip to content

Set the Onion-Location Header

Created September 12, 2026 • Last updated September 12, 2026 • 3 min read • 197 views

Joshua

HackIndex Creator

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 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.

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.

<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.

user@host ~ $ curl -I https://$CLEARNET_DOMAIN/
HTTP/2 200
server: nginx
onion-location: http://ahxaebv2jyncy5u3xn7anbsgdamowr6mhcioyiiyblxec4ud5geaiy5d.onion/
content-type: text/html
Explain command
-I Fetches headers only, which is enough to confirm the header is present.

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. If you serve several addresses, set the header per site as covered in running multiple onion services on one host.

References