Articles
Articles are addressable kind 30023 events whose content is markdown (NIP-23). Because they are addressable, an author can edit an article and clients keep only the latest version.
Reading an article
Load an article with store.replaceable() and cast it with Article. The cast reads the metadata tags and falls back to created_at when there is no published_at tag.
const article = use$(
() => store.replaceable(pointer).pipe(castEventStream(Article, store)),
[pointer.kind, pointer.pubkey, pointer.identifier],
);
article.title;
article.image;
article.summary;
article.publishedDate; // Date, from published_at or created_atTo list articles, cast a timeline with castTimelineStream(Article, store).
Linking to an article
article.pointer and article.address give the AddressPointer and naddr. The pointer$ and address$ observables add up to three relay hints from the author's outboxes.
const naddr = use$(article.address$);Reactions and comments
article.reactions$ returns the article's reactions as Reaction casts. Articles are discussed with kind 1111 comments, which CommentsModel reads and CreateComment publishes.
const comments = use$(
() => store.model(CommentsModel, article.event).pipe(castTimelineStream(Comment, store)),
[article.id],
);
await actions.run(CreateComment, article.event, "Great read");Rendering the content
Article content is markdown with nostr: mentions. Render it with remarkNostrMentions from applesauce-content/markdown, as shown in Markdown.
Helpers
isValidArticle(event)checks for kind 30023 with a title and non-empty content, which the cast requiresgetArticleTitle,getArticleImage,getArticleSummary, andgetArticlePublishedread the metadata
Example: Article rendering
Best Practices
- Key subscriptions on the article's address, not its event id, since edits change the id
- Share
address$instead ofaddressso links carry relay hints - Sanitize links when rendering article markdown