Is there any way to create a paywall with Hugo? I know Netlify recently published an article about doing something similar to a paywall, but I’m not sure if there’s something easier around.
No, it is not possible with just Hugo.
You would need either a third party service (like Netlify) or configure the paywall yourself either on the front-end or server-side.
bep
November 18, 2021, 7:36am
3
@alexandros is right. I think in general (even outside of Hugo) that this is much harder than it should be, especially for smaller member sites. Some time ago I wrote this issue, which I thinks is more or less also valid today (and something that I really want to do):
opened 06:58AM - 30 Aug 18 UTC
Keep
Proposal
Note that this proposal isn't a "ready to implement" one. These are some initial… thoughts. And these thoughts skip the parts that live outside of Hugo (authentication etc.).
The current options for this with Hugo include
* Something like `htaccess` with Apache. Configuration can be managed and generated by Hugo, but you need to map that model yourself.
* Some third party service like [Google CLOUD IDENTITY-AWARE PROXY
](https://cloud.google.com/iap/) or [Netlify Access Control](https://www.netlify.com/docs/visitor-access-control/) or you build your own using the mechanisms in [AWS](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html)
The downsides of the above are
* It can be very complex and potentially very expensive
* It only allows you to allow or restrict access to a set of resources, i.e. URLs. E.g.: "You have to have the role MEMBER to view pages below /member", "You have to be ADMIN to view pages below /admin" etc.
If you want to, say, show a different home page for members, you will have to go the cumbersome route of somehow building your pages with secured server-side services. Which partially removes the static part and you end up with some ... **[jam](https://jamstack.org/)**.
This proposal is simple:
* Add **Role** as a new concept in Hugo
* There should be a **Role** [hierarchy](https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/htmlsingle/#authz-hierarchical-roles)
* It should be possible to override templates for a given role, e.g. `home.member.html`.
* It should be possible to do role membership checking in the template: `{{ if .Site.HasRole "member" }}{{ end }}`
* A way to restrict output for roles.
The above is simplified. There are some questions on how to do this effectively with many roles to avoid duplication etc., but in it's simplest form with 2 roles you may end up with something like this:
```bash
site
└── public
├── member
│ └── index.html
└── user
└── index.html
```
The above will solve both `authorization` (_you need to be a member to have access to resource x_) and `presentation` (_if not a member, show the registration link_).
The above would still need **something** outside of Hugo to do the switching (possible solutions include [Cloudflare Workers](https://blog.cloudflare.com/using-workers-to-make-static-sites-dynamic/) or [Cloudfront Lambda@Edge](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html)). But the above is a much simpler model to reason about than what we have today. You could possibly set up a Amazon S3 bucket per role?
---
Some additional notes:
Adding `roles` as a front matter attribute to restrict access would work and would be the to go for many situations, but it would not be very convenient for "big" sites, and it would also not cover static assets.
So I suggest that we **also** add some "access patterns", e.g.,´/members/**` etc.
2 Likes
Roles can most definitely be something Hugo would benefit from. Currently, the only way to achieve this is by either using Netlify (not bad, but expensive at $99 per month) or by doing a mixed installation in a hosting capable of serving dynamic pages.
I’m writing this to let everyone know Hugo might not be made of stone, but it rocks. I am trying to build a paywall, with a member’s area.
This is what I’m going to be doing:
Static site with Hugo
PHP server to authenticate users
User goes to the static HUGO site.
User clicks the sign-up button.
User username and password travels through the cyberweb to the PHP site via AJAX, thus, registering an account on the PHP site.
Then, the user gets taken to the HUGO static site again.
The user enters his username and password.
Ajax to the PHP site.
Returns a cookie.
User stays logged in for the session.
Pages that need to be protected make an Ajax call before loading the content.
The only issue I see with this is, well, the content can be read via the source code.
This is beyond Hugo scope, but then again, I’m trying to build something here! Maybe I can come up with a solution that can help others.
There are other ways to create a paywall for a JAMStack site.
Have a look at this step-by-step that involves authentication via AWS.