Personal blog finxol.io
blog

chore: improve README, with detailed atproto integration explanation

finxol.io 42d16dcd ec66981c

verified
+103 -26
+103 -26
README.md
··· 1 - # Nuxt Minimal Starter 1 + # finxol blog 2 + 3 + This is the repo for finxol's blog. 4 + 5 + All posts are in `content/`. 6 + Configuration is in `blog.config.ts`. 7 + 8 + ## Technology stack 9 + 10 + - Nuxt v4 11 + - Nuxt Content 12 + - TailwindCSS 13 + - Deno (Deploy EA) 14 + 15 + ## Bluesky integration 16 + 17 + Tracking PR: [#1](https://tangled.org/finxol.io/blog/pulls/1/) 18 + 19 + Comments on this blog are directly integrated with Bluesky, the atproto-based micro-blogging social network. 20 + 21 + This integration relies on the `@atcute/` library collection for interaction with Bluesky/atproto. 22 + 23 + The idea was originally inspired from [natalie's blog](https://natalie.sh/posts/bluesky-comments/). 24 + Although I ended up using mostly the same tools and strategies, I didn't follow her post to build it here. 25 + 26 + ### How it works in practice 27 + 28 + The author of the blog writes a post and publishes it. 29 + They can then post about it on Bluesky, find the post id, and add it to the `bskyCid` field in the post frontmatter. 30 + Any Bluesky post below the one identified will now be displayed at the bottom of the blog post, allowing for integrated conversation about the post. 31 + 32 + ### How it works technically 33 + 34 + The [AT Protocol](https://atproto.com/) is an open internet protocol for social applications. 35 + All the data is decentralised and public ([for now](https://pfrazee.leaflet.pub/3lzhui2zbxk2b)). 36 + This openness allows us to reuse and build things based on that data very easily, in a built-in way, without hacky workarounds. 37 + 38 + This integration works in several parts: 39 + 40 + #### `app/util/atproto.ts` 41 + 42 + Contains the utility functions for retrieving all replies to a post, and extracting a post id from an atproto uri. 43 + 44 + Uses `@atcute/client` to fetch using the `app.bsky.feed.getPostThread` RPC on the Bluesky public API. 45 + Everything is strongly typed, although fetch errors are handled as `post not found` to make handling simpler in the Vue component. 46 + 47 + #### `blog.config.ts` 48 + 49 + The author DID is set blog-wide in the config file through `authorDid`, as it is primarily intended as a personal blog. 50 + If need be, I can always move the DID parameter to the post frontmatter, allowing for guest authors or secondary accounts too. 51 + 52 + #### `content.config.ts` 53 + 54 + Since the Bluesky post CID needs to be set for each blog post independently, 55 + I added a `bskyCid` field in the post frontmatter. 56 + 57 + #### `app/components/BskyComments.vue` 58 + 59 + This is the core component to display the replies. 60 + 61 + The component simply fetches the replies by calling `getBskyReplies`, passing in the post CID passed as prop, 62 + and displays the content using the `BskyPost` component. 63 + 64 + The reply, like, repost, and bookmark counts of the original Bluesky post are also displayed. 65 + 2 66 3 - Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. 67 + #### `app/components/BskyPost.vue` 4 68 5 - ## Setup 69 + This component displays the post author, their avatar, the post content, and its stats beautifully. 6 70 7 - Make sure to install dependencies: 71 + Replies to replies are indented accordingly to visually thread replies together, using `BskyPost` recursively, 72 + with a `MAX_DEPTH` to set a limit to the number of replies to show. 8 73 9 - ```bash 10 - # pnpm 11 - pnpm install 12 - ``` 13 74 14 - ## Development Server 75 + #### `app/pages/posts/[...slug].vue` 15 76 16 - Start the development server on `http://localhost:3000`: 77 + The actual post page only had some minor adjustments to integrate the `BskyComments` component, 78 + using a `Suspense` boundary with a fallback to avoid blocking the rendering of the actual content. 17 79 18 - ```bash 19 - # pnpm 20 - pnpm dev 21 - ``` 80 + #### Others 22 81 23 - ## Production 82 + Some other files saw modifications, to adapt to this integration addition, allowing for visual consistency. 24 83 25 - Build the application for production: 84 + ### Advantages of the approach 26 85 27 - ```bash 28 - # pnpm 29 - pnpm build 30 - ``` 86 + Since this blog is built with Nuxt, everything is SSRed. 87 + This makes the Bluesky integration a wonderful progressive enhancement. 88 + The comments will still display and show up as intended if the client has Javascript disabled, 89 + without blocking rendering of the actual content through the use of a `Suspense` boundary. 31 90 32 - Locally preview production build: 91 + Using Bluesky as a comment platform allows me to integrate conversations about my posts directly alongside them, 92 + without bearing the load of moderation and user accounts. 33 93 34 - ```bash 35 - # pnpm 36 - pnpm preview 37 - ``` 94 + ### Limitations 38 95 39 - Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. 96 + As briefly mentioned, fetch errors are normalised to `#notFoundPost`, 97 + this could be refined for better reporting in the UI. 98 + 99 + This integration also only handles plain text content. 100 + All embedded and rich media is effectively ignored for now. 101 + 102 + ## Install locally 103 + 104 + ```sh 105 + # Install dependencies 106 + pnpm i 107 + 108 + # Run the development server 109 + deno task dev 110 + 111 + # Build for production 112 + deno task build 113 + 114 + # Deploy to Deno Deploy EA. Add `--prod` to deploy to production 115 + deno deploy 116 + ```