Proxying webmentions with nginx
Update 2023: I now use Caddy instead of nginx, and have an equivalent Caddy snippet here.
In my ever-continuing attempt to indiewebify my new static website, I wanted to share what I came up with for receiving webmentions. Being a static site, I have to use some kind of webmention sidecar to process and store the mentions themselves. I’m currently using Pelle Wessman’s webmention service on Heroku, which works pretty well. But I was also interested in having a “visible endpoint that teaches”, as well as one that had a web form for manually submitting webmentions. And of course, I like the idea of hosting it on my own site, so I can customize it exactly how I want.
What I ended up with is a hybrid approach. My new webmention endpoint is
https://willnorris.com/api/webmention. All HTTP GET
requests to that URL are served by a static
file on my webserver, while HTTP POST
requests are forwarded to Pelle’s webmention service using nginx’s proxy module.
I feel like this gives me the best of both worlds, and the configuration to do it was surprisingly simple:
location = /api/webmention {
if ($request_method = POST) {
proxy_pass https://webmention.herokuapp.com;
}
try_files $uri $uri.html $uri/ =404;
}
I did luck out in that Pelle chose /api/webmention
as the path for his webmention endpoint. This is exactly what I was
wanting to use, which means the proxy just works. Had I wanted to map a different path, it would have been a little more
complicated because nginx has some limits on how proxies can be configured inside if
blocks (this stackoverflow
post has some details).
Still to do: Currently, when you submit the form on my webmention page it just returns a plaintext success
message, since that’s what the webmention service returns. I need to add a little javascript to the form so that it is
submitted in an XHR request and a nicer success message can be displayed. (fixed)
I’m also still not displaying received webmentions, but I’ll get to that eventually.