protocol-relative URIs

2026-04-07

what?

protocol-relative URIs (actually called relative references by RFC 3986) are a neat way of linking to a resource available over multiple protocols.

why?

in my particular case, i'm sharing stuff over both gemini and https, and would like to have references to an external page be consistent to the protocol the user is currently using.

now, if the page you are linking to is hosted on the same capsule/website as the page linking to it, it is trivial to have a script convert file extensions: you simply find all occurences of URIs that point to the same host, and replace the file extension, while ignoring URIs that point to external pages.

  • /lorem.xhtml → /lorem.xhtml
  • ../ipsum.gmi → ../ipsum.xhtml
  • gemini://example.net/dolor.xhtml → gemini://example.net/a.gmi
  • https://example.com/sit.html → https://example.com/sit.html

i actually already do this when i convert my gmi pages to xhtml:

%.xhtml:	%.gmi mk/pre mk/post
	...
	sed '/^=> /!n; /^=> [a-z]*:\/\// !s;\.gmi;\.xhtml;' $stem.gmi | gmitohtml
	...

the problem occurs when you're linking to an external host serving content over multiple protocols.
the way i see it, you would either have to keep track of all known multi-protocol hosts and apply some special transformation magic to them when deploying your pages to the server, or choose one protocol the main one, and make all URIs stick to it.

how?

however, i've recently discovered protocol-relative URIs: you simply omit the protocol part of the URI, and now you've got a protocol-agnostic link to a resource.

don't:
gemini://para.mohrie.net
also don't:
https://para.mohrie.net

instead do:
//para.mohrie.net

for the users browsing on gemini, the link points to:
gemini://para.mohrie.net
for the users browsing on the web, the link points to:
https://para.mohrie.net

but?

  • if you open a local file, these relative references won't work ("//example.com" would be interpreted as "file://example.com").
  • if the file has a different file extension on each protocol, it won't work.

still?

if you mirror stuff on multiple protocols and link to stuff also available on your multiple protocols, use protocol-relative URIs.