{
  "$type": "site.standard.document",
  "author": "did:plc:ticz2qmqh2vqxnehf5zalkpl",
  "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": "So many updates over the weekend I've lost count. Improved standard.site support, Leaflet, WhiteWind, and other lexicons."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "It's coming along."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.header",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 10,
                    "byteStart": 0
                  }
                }
              ],
              "level": 2,
              "plaintext": "The Reader"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "I added reader views with so-so block support, markdown rendering, for those posts, even one's that deviate from the spec. We support index multiple document formats natively:  Leaflet's block-based structure, WhiteWind's markdown entries, and other site.standard.document formats. If we can't render something yet, we tell you and link to the original. (Note, I made a judgement call and we only display posts with > 100 words. How do others handle the thousands and thousands of non-native aggregator and forum links coming over the firehose? Let me know @librenews.bsky.social )"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Each article shows the author's profile, a publication badge if it belongs to one, and the publish date. You can like or repost directly from the reader. There's also a \"View Source\" link if you're curious about the raw AT Protocol record behind the article. I did that to help me debug but I think I'll leave it."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Below the article, we pull in discussion from the ATmosphere — any Bluesky posts that reference the article URL show up as comments, with their own like and repost counts."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 31,
                    "byteStart": 18
                  }
                }
              ],
              "plaintext": "And now there's a Related Posts section in the right column powered by OpenSearch's more_like_this query against our full article index. Each related post shows the author's avatar so you can see it's from different writers across the network."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.header",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 8,
                    "byteStart": 0
                  }
                }
              ],
              "level": 2,
              "plaintext": "The Feed"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "The home page is a three-column layout. The center column shows a chronological feed of long-form articles from across the AT Protocol. We filter for English-language content over 100 words — this keeps out stub records but this needs work and customization."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 40,
                    "byteStart": 31
                  }
                }
              ],
              "plaintext": "If you're signed in, you get a Following tab. Follow a publication from any article card and its new posts show up there. The follow relationship is stored as a site.standard.graph.subscription record on your own PDS — it's your data."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 35,
                    "byteStart": 28
                  }
                }
              ],
              "plaintext": "The right sidebar now shows Popular posts, ranked by engagement (likes and reposts) with exponential time decay. A post from yesterday with 3 likes ranks higher than a week-old post with the same count. It's a simple formula but it keeps things fresh."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.header",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 23,
                    "byteStart": 0
                  }
                }
              ],
              "level": 2,
              "plaintext": "Writing & Collaboration"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Longform isn't just a reader. You can write here too. The editor uses Yjs for real-time collaborative editing — multiple people can work on the same document simultaneously with conflict-free merging."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 21,
                    "byteStart": 11
                  }
                }
              ],
              "plaintext": "There's an ACL system backing it. When you create a document, you own it. You can share it with other AT Protocol users by their DID or handle, granting either read or write permission. There's also a wildcard (*) permission for public access. The permissions are checked on every WebSocket connection and HTTP request, so it's not just UI-level gating."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "When you're ready, publishing writes the document as a site.standard.document record to your PDS. It's yours. (Did I mention that already? I't obvious in this community but not the rest of the world. ; ) If you delete it from Longform, it's gone from your PDS too."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.header",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 6,
                    "byteStart": 0
                  }
                }
              ],
              "level": 2,
              "plaintext": "Search"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "The search bar in the header hits our OpenSearch index, which has the full text of every indexed article with multi-language analyzers (English, Spanish, French, German, CJK). You can search by content, not just titles. Results show highlighted snippets so you can find what you're actually looking for."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.header",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 21,
                    "byteStart": 0
                  }
                }
              ],
              "level": 2,
              "plaintext": "What's Under the Hood"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "The whole thing runs on a single VPS. Hono for the web server, PostgreSQL for state, OpenSearch for full-text search and recommendations, Redis for caching, PM2 for process management. A Jetstream consumer watches the AT Protocol firehose for new documents and indexes them in near real-time."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "There's no React. No client-side framework. It's server-rendered JSX with Hono's built-in JSX support. Pages load fast because there's nothing to hydrate."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.header",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#bold"
                    }
                  ],
                  "index": {
                    "byteEnd": 11,
                    "byteStart": 0
                  }
                }
              ],
              "level": 2,
              "plaintext": "What's Next"
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "Honestly, I'm not sure yet. The \"For You\" tab is gone for now because I didn't want to ship something half-baked. There's groundwork laid for topic clustering, and the OpenSearch index could support semantic search if we add embeddings. The collaborative editor could grow into something more substantial, or another product itself."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [],
              "plaintext": "But for now, it reads well, it writes well, and it's built on open protocols. That feels like enough to keep me going for a bit more."
            }
          },
          {
            "$type": "pub.leaflet.pages.linearDocument#block",
            "block": {
              "$type": "pub.leaflet.blocks.text",
              "facets": [
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#italic"
                    }
                  ],
                  "index": {
                    "byteEnd": 71,
                    "byteStart": 0
                  }
                },
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#italic"
                    }
                  ],
                  "index": {
                    "byteEnd": 78,
                    "byteStart": 71
                  }
                },
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#strikethrough"
                    }
                  ],
                  "index": {
                    "byteEnd": 78,
                    "byteStart": 71
                  }
                },
                {
                  "features": [
                    {
                      "$type": "pub.leaflet.richtext.facet#italic"
                    }
                  ],
                  "index": {
                    "byteEnd": 123,
                    "byteStart": 78
                  }
                }
              ],
              "plaintext": "Longform is open source and runs at longform.social. Sign in with your Bluesky AtProto account to start reading or writing."
            }
          }
        ],
        "id": "5c95675c-6ae6-4541-882b-02e573347a31"
      }
    ]
  },
  "description": "",
  "path": "/5946ukvfg5",
  "publishedAt": "2026-05-12T02:32:28.988Z",
  "site": "at://did:plc:ticz2qmqh2vqxnehf5zalkpl/site.standard.publication/self",
  "tags": [],
  "title": "Longform.social updates"
}