Hi, after days of trying about 5 different approaches to solving this I come here in defeat hoping for some help from you fine people. I can think of several possible solutions, and im not sure it can be solved purely in Hugo, most of my solutions involve huge and my server (Vercel) working together, but even then i keep reaching deadends. Let me start by explaining the problem im trying to solve, then I will explain the few solutions I tried.
If it helps the full code for this project as I describe is here, its open source. I will try to leave the relevant parts here though: Fedipage / Fedipage · GitLab
The problem
The problem is rather simple… I am using default permalinks and my page posts have the default format of /:section/:slug
. For example one such page is https://fedipage.com/news/fedipage-v1-0-1-released/
My problem is I need every page, using the same url, to be able to serve up either an html version, or a json version, depending on what the client sends in the request header.
For example the following should return the html (and does):
curl -X GET -H "Accept: text/html" https://fedipage.com/news/fedipage-v1-0-1-released/
And the following should return json (it doesnt):
curl -X GET -H "Accept: application/activity+json" https://fedipage.com/news/fedipage-v1-0-1-released/
I should point out the json version has its own template and obviously looks very different from the html version… all that is working fine when their entirely separate urls… i just cant get them both to work with the same url depending on the accept parameter.
The attempts
Now I should point out that I dont expect to fully get to a solution using pure Hugo, if I am wrong about this that is great and I welcome any such solutions,
Instead I am trying to solve this by a combination of using hugo and a feature from vercel called rewrites which let you direct a url that goes nowhere to one that goes somewhere, transparently. The priomary challenge with using rewrites has to do with the structure, ill explain. Right now when I compile the page i am able to successfully produce something like this:
/public/news/fedipage-v1-0-1-released/index.html
/public/news/fedipage-v1-0-1-released/index.json
as is this means when i curl https://fedipage.com/news/fedipage-v1-0-1-released/
, regardless of what I set in the accept parameter, it will always just return the html version. If I want the json version I can get it by curling https://fedipage.com/news/fedipage-v1-0-1-released/index.json
instead.
Coming back to the vercel rewrite unfortunately it doesnt work when there is an index.html in the directory. So while it does have the support to rewrite conditionally and only rewrite when the accept parameter is json, it wont work because the index.html file is there.
Another thing I tried was to change the baseName produced to something other than “index” so now the directory structure looks like this:
/public/news/fedipage-v1-0-1-released/status.html
/public/news/fedipage-v1-0-1-released/status.json
When i do this the rewrite through vercel works great and i can make it so one of those two files is served up based on what I put in the accept header. However this gives rise to a new problem… all the permalinks now point to https://fedipage.com/news/fedipage-v1-0-1-released/status.html
instead of the actual url I want them to point to, which is https://fedipage.com/news/fedipage-v1-0-1-released/
. So while this does sort of give me what I am asking for it literally breaks everything else.
I tried several ways to approach this, all similar ideas… i tried finding ways to explicitly configure permalinks, and all sorts of weird hacks… nothing
I am willing to consider any reasonable solution that gets me to my goal, any ideas?