"Just you and your PDS."
Prerequisites
- be familiar with JS objects or JSON (JSON is basically stricter JS objects)
- have
index.html
andmain.js
in the same folder (source https://codeberg.org/fei-chicory-blue/atproto-site) - have your PDS and DID (you can check them with internect.info)
- if you're not part of chicory.blue, understand that although this is open source, it exists primarily for our personal use
Disclaimer
This is a purely client side page. That means you can test it just by double-clicking the HTML file. It also means there is no caching and it fetches everything directly from the PDS (or the optional blob URL). There's also no post validation! Use at your own risk.
Options
Simple options
Option | Description | Example |
---|---|---|
PDS | your pds | 'chicory.blue' |
title | your web page title | 'My blog' |
postsPerPage | number of posts to display on a page | 10 |
pageLimit | max number of pages | 5 |
linkToUserHandles | link pfp, username, and handle to your handle url | false |
showDrafts | whether to show WhiteWind draft and url-only posts | false |
showReplies | whether to show Bluesky and PinkSea replies | false |
hideNSFW | whether to hide NSFW and self-labeled posts | false |
readMore | number of paragraphs before a Read more line for markdown | false |
tagsAsClasses | whether to add lowercase outline hashtags to post html as CSS classes | false |
blobURL | where to get blobs from (default asks the PDS directly) | 'https://cdn.bsky.app/img/feed_fullsize/plain' |
dateFormat | Intl.DateTimeFormat or similar | new Intl.DateTimeFormat() |
Complicated options
pages
A page displays one post and gets a url, https://domain.name#pagename
. The post doesn't have to be normally visible on the blog, so you can display a draft if you want.
If you want normal site functions to work, avoid these names for pages:
#page/2
shows page 2 of your posts#tagged/tagname
shows all posts tagged with tagname. Tag names are matched case-insensitive. Inline tags are not supported.
title
: the title to display on the browser tab
post
: URI of the post record for the page content
You can get the URI of a post using the PDSls Redirector or if you use Klearsky, just Copy > Copy URI from the post menu.
pages: {
'about': {
title: 'About',
post: 'at://...'
}
},
users
You can display multiple users from the PDS. Each user in the list has these properties:
DID
: the user's DID.
handle
: the user's handle.
sources
: flags for which types of posts you want to display, based on the collection names. You can leave out any ones that you're not using. Currently supported: Bluesky, Frontpage, Linkat (displays in a link board rather than adding posts), WhiteWind, PinkSea, pastesphere.
profile
: you can specify an alternate username, description, and pfp. Pfp should be a link to the image - preferably you add a file to the folder in which case the link is ./filename.jpg
(or whatever the file extension is).
users: [
{
DID: 'did:plc:...',
handle: 'me.domain.name',
sources: {
Bluesky: true,
WhiteWind: true
},
profile: {
username: 'me',
description: 'Hi',
pfp: './icon.png'
},
},
{ ...some other user }
]
profile
You can also specify alternate profile information for the entire site. Otherwise, it will use the first user's profile information.
Custom elements
These are the custom elements you can use on the page. Your record data and options data will be added to them.
You can use these elements anywhere on the page:
post-container
: posts and page content will go in hereprofile-picture
: first user/site iconprofile-username
: first user/site nameprofile-description
: first user/site descriptionlink-board
: cards from Linkat will be added hereif-index-page
: rendered if on the index pageif-tag-page
: rendered if on a tag pagetag-name
: on a tag page, the name of the tag
Pagination
if-pagination
: rendered if on a page that supports pagination (currently only index page)if-previous-page
: rendered if there is a previous pageif-next-page
: rendered if there is a next pageprevious-page-link
: link to the previous pagenext-page-link
: link to the next pagecurrent-page-number
: the current page number
Show a specific post
site-post
: used to add a single post anywhere on the page. Has attributes:-
data-uri="uri"
(the AT URI of the post)
-
data-show-author
(add this if you want to display author information)
You can use this class anywhere on the page:
.atproto-site-scroll
: a class you can add to an element to make that element scroll to the top when a new "page" is loaded.
You can use these elements in any post:
if-author
: rendered if the post author should be shownauthor-pfp
: the post author's profile pictureauthor-username
: the post author's usernameauthor-handle
: the post author's handleif-embeds
: rendered if the post has embedsembed-container
: container for embeds to be added toif-tags
: rendered if the post has tagstag-container
: container for tags to be added toremote-link
: link to the service associated with the post, has inserted textcreated-at
: date and time the post reports to have been createdif-reply
: rendered if the post is a replyif-not-reply
: rendered if the post is not a reply
Templates
Posts are constructed using the templates at the bottom. Templates have the id template-<name>
. For example, a text post will be created from template-text-post
and on the page it will be added as a text-post
element. This means you can also write CSS rules for specific post types. You don't have to write a template for every post type - any missing templates will be cloned from template-generic-post
.
Templates and the additional custom elements they can have
text-post
: a post with only text.
if-title
title-content
text-content
image-post
: a post with one image.
text-content
image-content
imageset-post
: a post with multiple images.
text-content
image-content
link-post
: a post from a link aggregator.
title-content
link-wrapper
link-content
embed-card
: one embed.
if-title
title-content
text-content
image-content
tag-chip
: one tag.
link-wrapper
link-content
Notes on some of the additional custom elements
link-wrapper
: anything in the link wrapper element will be linked
image-content
: when there are multiple images, they will all be added to it
Other
We are using markdown-it over CDN. Please note that it doesn't handle checkboxes or embedded html by default.
The atprotoSite
function is async, so use .then()
or await
if you want to process posts after they're loaded.