{
"$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"
}