{
  "path": "/3lyilxc6fe22n",
  "site": "at://did:plc:6ll5xi67lyuyovt6fiv4fnjo/site.standard.publication/3lyht3qgykk2g",
  "$type": "site.standard.document",
  "title": "Cloudflare atpages",
  "content": {
    "$type": "pub.leaflet.content",
    "pages": [
      {
        "$type": "pub.leaflet.pages.linearDocument",
        "blocks": [
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Hi!"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 29,
                    "byteStart": 23
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    },
                    {
                      "uri": "https://github.com/geesawra/atpage",
                      "$type": "pub.leaflet.richtext.facet#link"
                    }
                  ]
                },
                {
                  "index": {
                    "byteEnd": 88,
                    "byteStart": 81
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "I recently played with atpage again after a long hiatus (which was due mostly to $newjob, so it wasn't all that bad), and wanted to see if I could deploy it to GitHub Pages, as a treat."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "After some initial success, I quickly encountered the same issue I had during the first iteration: you can't easily hotlink a blog post online and expect it to work, because the Service Worker is only installed when visiting the website's root."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "src": "https://geesawra.leaflet.pub/3lyilpgnku22n",
              "$type": "pub.leaflet.blocks.website",
              "title": "Hosting a website on your ATProto PDS - geesawra's ramblings",
              "description": "",
              "previewImage": {
                "$type": "blob",
                "ref": {
                  "$link": "bafkreic33htdhyfxih4mil2mvfscw3xukwbroyjcr4fy335vci2tmvrwby"
                },
                "mimeType": "image/png",
                "size": 23052
              }
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": ""
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 23,
                    "byteStart": 2
                  },
                  "features": [
                    {
                      "uri": "https://bsky.app/profile/geesawra.industries/post/3lng6cbuqss2z",
                      "$type": "pub.leaflet.richtext.facet#link"
                    }
                  ]
                },
                {
                  "index": {
                    "byteEnd": 57,
                    "byteStart": 41
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ]
                }
              ],
              "plaintext": "I complained on Bluesky and it turns out Cloudflare Pages allows you to do custom redirects and stuff like that, for free, without hosting anything yourself."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.bskyPost",
              "postRef": {
                "cid": "bafyreib3cnctqtgqty67xenx2edw2lrzn3g26zwhqjw7mz4qvg4uxhm66u",
                "uri": "at://did:plc:6ll5xi67lyuyovt6fiv4fnjo/app.bsky.feed.post/3lng6cbuqss2z"
              }
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 95,
                    "byteStart": 85
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                },
                {
                  "index": {
                    "byteEnd": 105,
                    "byteStart": 97
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "I wanted to replicate the same workflow as any common Hugo user, which boils down to git commit, git push and poof, your new blogpost is available on your website."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 177,
                    "byteStart": 166
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "Setting up GitHub Actions wasn't as bad as I expected: I cloned the blog sources repo, cloned atpage in a subdirectory, called Hugo to obtain the rendered HTML, then atpage post to post it on my PDS, easy!"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Setting up Cloudflare Pages wasn't much harder to be fair, I don't like how they coerce you to move your domain's DNS servers to theirs if you want to use your own - you can probably set it up differently, but I can't see how."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 107,
                    "byteStart": 97
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "A neat feature of Pages is that you can specify custom redirects by including a text file called _redirects in your deployment bundle."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "This is how I do it with Caddy v2:"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.code",
              "language": "plaintext",
              "plaintext": "geesawra.industries {\n  handle /at/* {\n      root * /geesawra.industries\n  }\n\n  root * /geesawra.industries\n  file_server\n}"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 35,
                    "byteStart": 25
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "This is how I do it with _redirects:"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.code",
              "language": "plaintext",
              "plaintext": "/at/* / 200"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 142,
                    "byteStart": 138
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "By moving to Cloudflare Pages I also gained access to very business tooling, like staging and production environments: whatever isn't the main branch is automatically treated as staging, and you also get a deploy-specific URL to go look at your staging website!"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "I use GitHub environments to have all the fancy UI/UX goodies, like a \"click here to see your staging prod\" button in PRs, or the deus ex machina, branch protection rules."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Each environment is tied to a specific Bluesky account, so that I don't end up overwriting my main account's blog with the staging one."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 126,
                    "byteStart": 101
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ]
                }
              ],
              "plaintext": "I'm not a web developer, and I'm in awe at what we can achieve nowadays with great tooling available completely free of charge."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 14,
                    "byteStart": 2
                  },
                  "features": [
                    {
                      "uri": "https://github.com/geesawra/geesawra.industries",
                      "$type": "pub.leaflet.richtext.facet#link"
                    }
                  ]
                }
              ],
              "plaintext": "I open-sourced this blog, including the Pages configuration and the GitHub Action I wrote to automate the deployment."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "index": {
                    "byteEnd": 29,
                    "byteStart": 23
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                },
                {
                  "index": {
                    "byteEnd": 47,
                    "byteStart": 44
                  },
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#code"
                    }
                  ]
                }
              ],
              "plaintext": "I should also document atpage, shouldn't I? :^)"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Until next time!"
            }
          }
        ]
      }
    ]
  },
  "description": "",
  "publishedAt": "2025-04-24T15:57:32.744Z"
}