Show HN: Pages CMS – A CMS for GitHub (pagescms.org)

351 points by hunvreus ↗ HN
In a nutshell:

1. You log in with your GitHub account.

2. You select the GitHub repo where your site/app is at (whether it's Next.js, 11ty, Hugo, Nuxt... as long as you're using flat files for content).

3. You add a single config file to your repo to define the content types and other settings (e.g. media folder).

4. Congrats: you now have a user friendly CMS to manage content + media BUT all changes are still tracked like regular commits (under your account) on GitHub.

I started using Jekyll around 2009 and over the course of the past 10+ years, I've helped build major sites and tiny blogs with Hugo, Gatsby, Next.js and more recently 11ty.

I still love it.

BUT once you're done building, managing content and media can be a bit of a pain. You have a few options:

- Edit files directly (on GitHub or your local). Good luck getting your colleagues on the marketing team to do that.

- Hook up a headless CMS like Contentful, Sanity, or Strapi. That works, but it's one more dependency and (IMHO) overkill in most cases.

- OR you could use something like [Decap CMS](https://decapcms.org/). Really cool project, but I've never been a fan of the UI/UX, and it's been a bit of a pain to setup (maybe that's just me).

I wanted something as simple as possible, preferably with nothing to install or deploy.

Back in 2018, I had built a prototype (Jekyll+) [1] with the idea of getting a CMS set up by just adding a single configuration file to your GitHub repository.

Pages CMS [2] is a continuation of that idea. It's 100% free and Open Source: https://github.com/pages-cms/pages-cms.

If you don't want to use the online version because you're not comfortable signing up with your GitHub account, consider the following options:

- Use a fine-grained personal access token [3], there's an option on the login screen. There is still a bug if you try to access a repo that isn't part of your token scope, but I'll get it fixed in the next couple of days.

- Deploy it yourself (for free) on Cloudflare Pages. Literally 5 minutes of work max. I made a video walking you through the process [4].

- Check out the intro video on the front page [2] (a bit crap, but I'll get a better one up in the next few days).

I use it actively with a few other teams, I hope it will be of use to some of you.

I'm already working on adding a few nicer features, like collaborative editing and email invites (to let non-developers login without a GitHub account).

PS: I've spent the past 8+ years building a business and only recently got back into coding. I'd love pointers as to what I could do better (and how I can manage my Powerpoint PTSD).

[1]: https://github.com/hunvreus/jekyllplus/

[2]: https://pagescms.org

[3]: https://docs.github.com/en/authentication/keeping-your-accou...

[4]: https://pagescms.org/docs/development/

121 comments

[ 2.8 ms ] story [ 166 ms ] thread
Nice, i've been looking for something like this in a long time! Will play with it later today
This is super cool!

Tried to set it up for our open source Changelog though and getting some errors, it doesn't seem to work with .mdx files

https://github.com/juneHQ/changelog

Anyways this looks super promising

I have a very surface understanding of mdx, but basically it's a mix of markdown and JSX syntax, no? Didn't know you could define some sort of fields like you seem to do with:

  import { MdxLayout } from "components/mdx-layout.tsx";
  
  export const meta = {
    slug: "all-time-high",
    publishedAt: "2022-09-16T10:00:00.000Z",
    title: "All time high",
    headerImage: "https://june-changelog.s3.eu-central-1.amazonaws.com/changelog_ath_cd256d0719.png",
    authors: [
    (...)
I suppose I should be able to hack it by defining it as a JSON frontmatter and some custom delimiters.

If you let me know how you would see this working, I'll try and get something working tomorrow.

Honestly as a v1, I'd just love for you to parse out the whole text file and give me a basic markdown editor!

I don't particularly care about having advanced filtering or of parsing my "meta" data

The editor will kinda work for individual mdx files, just not collections. I guess you could try the following to see:

  media: public
  content:
    - name: changelog
      label: Changelog
      type: file
      path: pages/changelogs/2022-in-review.mdx
      format: code
Obviously not super useful at this stage, especially since I haven't figured out mdx support in Codemirror yet.

I can probably get collections to work though in the next few days. I'll let you know.

So the site has to hosted on GitHub Pages or just the website code needs to be using GitHub? Eg what if I have the site hosted elsewhere that just relies on GitHub commits?
Nice to see a new entry in the git based CMS realm, I really appreciate that you seem to understand the importance of a good user experience for editing content!

Am I gathering correctly that this does not actually require you to host a backend somewhere? The GitHub OAuth will work even if the CMS is just statically hosted on Cloudflare Pages / Netlify? This was something I always found a little strange about Netlify CMS / Decap, the fact that it required you to either use Netlify or self host their git-gateway.

Edit: Nevermind, I saw it does the auth through serverless functions https://github.com/pages-cms/pages-cms/tree/main/functions/a... I guess it's impossible to do it frontend-only, looks like a fair compromise to me

That's the lightest I could figure out to get OAuth rolling, but it does almost nothing and doesn't store your token.

You don't have to host anything if you use the online version, but you can self host it fairly easily for free on Cloudflare Pages: https://pagescms.org/docs/development/#deploy-on-cloudflare

Yeah, github OAuth doesnt support a web client only flow, so you at least need a backend to forward along the response to the client.

It's pretty much just that cross site requests are disabled.

What the hell is going on with the little sentences in that example? I thought it was supposed to be like, a bad VC rap joke song or something? I was looking for rhymes. It's really lame.
They're the titles of the author's blog posts: https://ronanberder.com/ (see bottom of page) - i.e. it's a screenshot of them using it for their own blog.
Sorry for that: the titles are indeed lame. But they're mine. And I kinda like them.
This is really cool! I was sad when Forestry went down and this looks better than TinaCMS.

I'm trying to set it up with my Eleventy blog (paavandesign.com/blog) and struggling to get the body field working

Is your repo public? Happy to have a look if it is.

Have you also checked the examples: https://pagescms.org/docs/examples/

edit: this was the bug which I think you're already on top of! https://news.ycombinator.com/item?id=39468906

---

So 'body' is working if I set the type to text but when I set it to rich-text there's no input generated for body

Repo is private (sorry!) but here's the settings YAML file as it stands

     content:
      - name: blog
        label: Blog
        type: collection
        path: 'src/blog'
        view:
          fields: [ title, date]
        fields:
          - name: date
            label: Date
            type: date
          - name: title
            label: Title
            type: string
          - name: description
            label: Description
            type: string
          - name: tags
            label: Tags
            type: string
          - name: body
            label: Body
            type: rich-text
Yep, seems to be the same bug as what somebody else reported: if you don't specify a `media` attribute, when the rich-text editor tries to load it fails as it is attempting to load the media related features (to insert images).

Publishing a hotfix in the next hour, in the meantime it should work if you add a media attribute (you can set it as `media: ""` if you don't have an image folder).

I rolled out a hotfix, this should be fixed.

I also found another couple edge cases that are unlikely but that I will patch in the coming days.

Thanks for that.

EDIT:

I didn't have a `media` entry in my pages.yml, which meant the rich text editor wasn't loading (JS error was being thrown). When I added that entry, it started working! Brilliant work!

I'm using Jekyll, with yaml frontmatter, and it's not clear how to specify the body. The documentation says that a rich text field could be set up with a "name" option (and gives "body") as an example but my Markdown files don't specify a name for the body.. it's just... there:

https://github.com/colinramsay/colinramsay.github.io/blob/ma...

I'm probably missing something but happy to open an issue if not.

Thanks a lot for finding that bug. I'm adding a hotfix and will release in the next hour.
this solved my issue, thanks!
I rolled out a hotfix, this should be fixed. Thanks for the feedback.
This looks cool but I moved all my repos to a self-hosted forge when GitHub openly and notoriously refused to stop collaborating with ICE (that runs concentration camps in Texas).

It would be nice to have this support generic/arbitrary git servers. I’ve been feeling this pain point for a while and have been considering building something like this myself.

I am looking into GitLab and Bitbucket, but I don't plan on supporting generic Git, unless I can find a way to slap an API in front of it. I'll add that to the backlog.
Maybe you could add support for Gitea? It’s a pretty handy way to slap an API in front of git and it’s much simpler to self host than GitLab.
Aspects of the API look fairly similar to GitHub actually. I'll look into it.
How much of your API is dependant on GIT like semantics and how much could work with "plain files" storage?

It's neat to be able to transplant a CMS on top of other services that don't necessarily deploy by CI pipes, I made a DAV plugin(basic auth) for Netlify (back before the forks) so as long as a server supported listing(only DAV dependency really), GET, PUT and DELETE you could just plunk down the CMS files somewhere and point to the DAV share.

I believe Netlify CMS has an actual backend interfacing with the various Git systems they supported. Pages CMS is different in that it's a pure front-end app. I have a couple tiny serverless functions to help authenticate you with GitHub, but then after that there is no backend involved. That means I need some API for the front-end to interact with, at least for now.
This is awesome! It's exactly what I've been looking for. Can you have multiple types of Jekyll collections (posts)?
Yeah, as many collections and single files as you want.
Very nice! It looks a bit like Publii [0], but the editor part is cloud hosted instead of running as an app on your machine.

[0] https://getpublii.com/

I've not tried it yet, it looks pretty slick.
It is quite nice, but since there is no way to configure URLs, it‘s best used for greenfield projects, not moving from some other CMS with a differing URL structure.
Supremely cool. So this can supplement e.g. my eleventy sites and provide a way for clients of those sites to easily interact with the content and static asset portions of the site? Seems like there's tons of potential here. Kudos, def will give it a whirl!
Yes it does HOWEVER for now you need to log in with GitHub. I don't think it's too huge of a hassle with most people, but there is a bit of friction.

I am planning to add an "invite by email" feature that will allow you to add users by entering their email address. They can then log in without a GitHub account and use it the same way you do (although the commit will be associated to a Pages CMS GitHub app).

The invite by email feature sounds great, but as you say setting up a github account for a client isn't that much friction. It's not something I'm bothered by at all, but being able to use just an email is definitely supremely more preferable.

Very exciting work.

As I'm quite enthused by the project, I hope you don't mind if I offer some hopefully helpful feedback:

- For the video on your landing page, ideally the youtube would be embedded so it doesn't open another window

- In regards to the video, while I love the content and info, it's not the most marketing friendly. It's over 2 minutes before the background of the video even changes. Ideally the video would get into the demo portion muuuch quicker.

- I clicked on this hackernews link, clicked through to your landing page, scrolled around, but really didn't get a grasp of what it was offering or how it worked or who or what it was for (admittedly I was prly lazy reading). Only after I watched the video, heard you specifically mention eleventy (which I personally use a lot) was my interest piqued enough to actually engage in the content and understand it more. Glad I did, but I gotta feel there's some better way of presenting what you're doing. I quite liked your calling it a wordpress-like CMS over top an existing static site stack.

Those are just the thoughts that came to me. I absolutely love the project, thrilled it's MIT too. Though I'm not really a javascript dev I could definitely see myself using and contributing!

> For the video on your landing page, ideally the youtube would be embedded so it doesn't open another window

Yep.

> In regards to the video, while I love the content and info, it's not the most marketing friendly. It's over 2 minutes before the background of the video even changes. Ideally the video would get into the demo portion muuuch quicker.

Yep. I also recorded it when I was sick, and my mic is pretty horrid.

> I clicked on this hackernews link, clicked through to your landing page, scrolled around, but really didn't get a grasp of what it was offering or how it worked or who or what it was for (admittedly I was prly lazy reading). Only after I watched the video, heard you specifically mention eleventy (which I personally use a lot) was my interest piqued enough to actually engage in the content and understand it more. Glad I did, but I gotta feel there's some better way of presenting what you're doing. I quite liked your calling it a wordpress-like CMS over top an existing static site stack.

I definitely need to level up my marketing game.

Thanks a lot for the input.

I was just thinking this morning how I wanted something like Decap CMS but a bit simpler. Got this running on Cloudflare in ten mins and it seems great so far. Thanks!
why this over keystatic or statamic or (insert upcoming decap replacement)?
They all look great, but if you were pressing me for a comment:

- Keystatic: I want it to run online, not as a local app.

- Statamic: I don't want an opinionated, full-stack CMS + SSG. I want to manage content in whatever app/website I'm building whether it's Next.js, Astro, 11ty...

- Decap CMS: I mentioned it in my post, I always found Decap's UI/UX pretty lacking, and the DX wasn't that smooth either.

With that being said, each one of these projects have been around for much longer, I don't necessarily expect to compete (yet).

> (inset upcoming decap replacement)

What's wrong with DecapCMS?

ask op, or the dozen or so companies making a similar product
Looks very nice.

Any comparisons against other github based CMS?

Personally I've been using Keystatic.

I've not tried it yet, but isn't that running on your local machine? Looks pretty good though.
there is a cloud version for free up to three users that supports multiple simultaneous editors. paid beyond that.
Nice, thanks for the tip. Signing up.
You can also self host with your blog. I have it running as part of my astro deploy on vercel.
I've setup Decap CMS before, back when it was still called Netlify CMS. I loved the core idea of keeping all your files in Git and tracking them normally but like you said, it was just too hard get up and running and was very quirky, always thought to myself: "I wish someone would make a git based CMS like this but something that's easier to run with a less wired config / UI, seems like you did just that. Congrats!
I found DecapCMS setup quite easy the last time I did it. What roadblocks did you hit?
Nice. Does it support multi-projects? I got a lot of sites and dont like to have to have a seperate CMS for each.
Yes:

- There's an online version, you can just go to https://app.pagescms.org

- You can switch between repos and branches straight from the interface (just click on the repo menu in the top left corner).

Tried it out,

"the branch master doesn't exist, redirecting you to the default branch (master)"

master exists

Ouch!

Is it a public repo? I'd love to have a look.

Any word on S3 media support? I have a few content heavy sites. And that would be essential to be practical to switch to.
I've started looking into the APIs for it, I am rebuilding a site that has a lot of heavy media so kind of need it too. Realistically, 4 to 6 weeks.
Good to see further development in this space. Would be interesting to see how it compares to Decap CMS https://decapcms.org/ and Static CMS https://www.staticcms.org/

Me personally I'd like to see something that supports easily creating and using different types of objects besides pages (such as: events, books, recipes, etc.), like content types and fields and views in wordpress or drupal, ideally aligned with schema.org like https://www.drupal.org/project/schemadotorg I think Hugo might support content types in YAML or something.

You can configure whatever content type you want with nested fields, lists, etc. [1]

Disclaimer: I used to work a lot with Drupal 10+ years ago. I more or less wanted the same kinds of features in Pages CMS.

[1]: https://pagescms.org/docs/configuration/

Also try Tina CMS or ProcessWire.
Why do I have to give access to all my public and private repos instead of selecting the ones I want to give it access to?
I have an explanation in the FAQ section on the front page:

  Why do you need full access to all of my GitHub repositories?
  
  Well, the GitHub API kinda sucks when it comes to OAuth scoping. Pages CMS relies on the OAuth App flow, which doesn't allow for granular permissions. The alternative would be to use the GitHub App flow instead, but:
  
  It's a lot more complicated and would require us to store and orchestrate a lot more in the backend.
  
  Since we need to impersonate users (for things like commits), we anyway need to request user tokens, which technically would give us the same access as with the OAuth App flow.
  
  However, we do not store your GitHub OAuth tokens in the backend. The serverless functions used to facilitate the OAuth login pass the OAuth token to the front-end, allowing it to directly communicate with the GitHub API.
  
  And if you still don't trust the online version, you can deploy your own version for free in less than 10 minutes our Cloudflare Pages.
  
  Do let me know if I got some of this wrong (@hunvreus), and feel free to suggest improvements in the issue queue.
Additionally I've added the support for Fine-grained PATs [1], allowing you to use a repository specific token. You'll see the button that reads "Sign in with a Fine-Grained PAT" on the login screen.

[1] https://github.blog/2022-10-18-introducing-fine-grained-pers...

Got it; I hadn't heard of "Fine-Grained PATs" before so I just ignored it. My personal blog is open source already: https://github.com/FanaHOVA/2024-blog, so I was hoping to just OAuth and try it out, but I understand. Will try the self hosting at some point. Good luck with the project, looks slick.
"Fine-grained pats" is what a herd of cows produces when their feed contains too much fiber.
Check the FAQs at the bottom.

TLDR:

> Well, the GitHub API kinda sucks when it comes to OAuth scoping. Pages CMS relies on the OAuth App flow, which doesn't allow for granular permissions.

(comment deleted)
This is awesome however, I’m hesitant due to the pro pricing. I get it, but I’m definitely looking for something we can host that can do this for our customer support team who aren’t the best at git, or markdown for that matter, but have valuable knowledge of setup and configuration of our apps.

Any plans to just go full OSS with it and do sponsorships or OSI model foundation support? If this is yet another SaaS product then we’ll have to stick with our current methods.

Very cool stuff though. Keep going! GitHub or GitLab should just buy this for their platform.

- It's 100% Open Source: https://github.com/pages-cms/pages-cms

- You can self-host it for free on Cloudflare Pages: https://pagescms.org/docs/development/#deploy-on-cloudflare

- The online version is 100% free as well: https://app.pagescms.org

There may be a pro plan at some point for some more complex features. From the FAQ on the front page:

  What's the "Pro" plan?
  
  I haven't completely figured it out, but there are a few features I'm working on that I believe would only be relevant to larger teams or professional use. Things like real-time collaboration, advanced media management (e.g., image manipulation), or S3 integration. This not only requires a lot more work but also hosting costs. If you're interested, drop me a line: hunvreus@gmail.com (@hunvreus).
> The online version is 100% free

> What's the "Pro" plan? I haven't completely figured it out

Sounds like it's free until it isn't.

I feel your frustration, it should either be free or not-free. Stop pretending to be both, while ending up being neither!

Maybe we can start to refer to these types of projects as GOSS (Gated Open Source Software) or maybe COSS (Crippled Open Source Software)? :-)

you can download the code and self host it. how is that not open source software?
Tried it out [1], and with a bit of work got it to function. Media, posts, all seem to upload and be viewable. With the lead-in, kind of thought it was going to be "click-a-button, you're done." However, had to wander around a bit figuring out what format zones in the blog example were, and where they needed to be. Also kind of thought it was going to restyle my GitHub page or something, which did not seem to be the case (probably just false expectations)

[1] Uploaded Media using Pages interface: https://github.com/conceptualGabrielPutnam/JAMA4JS/blob/main...

Might be kind of nice if it allowed file upload/delete on folders you have not specifically called out for a function.

On my desktop at least, the user icon is also in the lower left, and then opens the choice window off the screen to the right.

If you can send me screenshots at hunvreus@gmail.com or file an issue on GitHub (https://github.com/pages-cms/pages-cms/issues), I'd love to fix it.

> Tried it out [1], and with a bit of work got it to function. Media, posts, all seem to upload and be viewable. With the lead-in, kind of thought it was going to be "click-a-button, you're done." However, had to wander around a bit figuring out what format zones in the blog example were, and where they needed to be. Also kind of thought it was going to restyle my GitHub page or something, which did not seem to be the case (probably just false expectations)

Agreed. For the 1.0.0 release, I want to have a configuration wizard that does most of it for you: select where your files/collections are and it infers the configuration from existing entries.

Hopefully I get it working in the next couple of weeks.

Opened new issue at https://github.com/pages-cms/pages-cms/issues/3 with documentation.

On the second comment, kind of figure it was a WIP currently, hence suggestions. Thanks for the work, as its a fairly light weight way to have a quick little CMS.

I rolled out a hotfix release, let me know if that fixed it.
This is very cool! I recently started managing my Astro site content with Notion as a CMS, thanks to `notion-to-md` [1] and `@notionhq/client` [2] but media management is a hassle.

I had been planning to re-host Notion media files to Cloudflare R2 and rewrite content, but it might just be simpler to use Pages CMS due to built-in R2 support.

But also, I like using Notion apps on the go. Hmm.

[1] https://github.com/souvikinator/notion-to-md

[2] https://github.com/makenotion/notion-sdk-js