mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-02-23 13:49:00 +00:00
230 lines
7.8 KiB
Markdown
230 lines
7.8 KiB
Markdown
![]() |
# NIP-74: Nostr Link Lists
|
||
|
|
||
|
`draft` `optional` `author:vveerrgg`
|
||
|
|
||
|
This NIP defines a standardized format for sharing curated lists of links on Nostr. The NIP number 74 was chosen as it represents the ASCII character 'L' (for Links).
|
||
|
|
||
|
## Abstract
|
||
|
|
||
|
Link lists are collections of URLs with associated metadata that users can share, curate, and discover. This NIP defines a standard format for link list events that enables interoperability between different Nostr clients and promotes consistent handling of link-sharing features.
|
||
|
|
||
|
## Motivation
|
||
|
|
||
|
Link sharing and curation are fundamental activities in online communities. While users can share individual links in text notes or save them privately using NIP-51 bookmarks, there's a need for a standardized format specifically designed for public, curated link collections. This NIP enables:
|
||
|
|
||
|
- Public sharing of curated link collections (e.g., "link-in-bio" style lists)
|
||
|
- Better organization and discovery of related resources
|
||
|
- Consistent metadata across implementations
|
||
|
- Support for internationalization
|
||
|
- Improved user experience through specialized UI
|
||
|
- Interoperability between different clients
|
||
|
|
||
|
The distinction from personal bookmarks (NIP-51) is intentional - while bookmarks serve as private reading lists, NIP-74 link lists are designed for public sharing and discovery, enabling users to curate and share collections of resources with their community.
|
||
|
|
||
|
## Event Format
|
||
|
|
||
|
### Kind: 30001
|
||
|
|
||
|
Link list events use kind `30001`.
|
||
|
|
||
|
### Content
|
||
|
|
||
|
The content field MUST be empty. All data is stored in tags.
|
||
|
|
||
|
### Tags
|
||
|
|
||
|
Required tags:
|
||
|
- `ll` ["list"] - Identifies this as a link list event
|
||
|
- `title` [list_title] - Name of the list
|
||
|
- `nl` [url, description, language?, direction?] - One or more link entries
|
||
|
- `url`: The URL being shared (must follow protocol requirements)
|
||
|
- `description`: Text description of the link (must be non-empty)
|
||
|
- `language`: Optional ISO 639-1 language code
|
||
|
- `direction`: Optional text direction ("ltr" or "rtl")
|
||
|
|
||
|
Optional tags:
|
||
|
- `lang` [code] - Default language for the list (ISO 639-1)
|
||
|
- `dir` [direction] - Default text direction ("ltr" or "rtl")
|
||
|
- `t` [topic] - Topics/hashtags for discovery
|
||
|
- `summary` [text] - Brief description of the list
|
||
|
- `image` [url] - Cover image for the list
|
||
|
|
||
|
### URL Protocol Support
|
||
|
|
||
|
The format supports various URL protocols to accommodate different types of resources:
|
||
|
|
||
|
Standard Web Protocols:
|
||
|
- `http://`, `https://` - Standard web URLs
|
||
|
- `ftp://`, `sftp://` - File transfer protocols
|
||
|
|
||
|
Special Protocols:
|
||
|
- `magnet:` - BitTorrent magnet links
|
||
|
- `ipfs://` - IPFS content
|
||
|
- `nostr:` - Nostr protocol links
|
||
|
- `dat://` - Dat protocol
|
||
|
- `git://` - Git repository links
|
||
|
- `ssh://` - Secure shell links
|
||
|
|
||
|
Extended Protocols:
|
||
|
- `mailto:` - Email addresses
|
||
|
- `tel:` - Phone numbers
|
||
|
- `sms:` - Text message links
|
||
|
- `geo:` - Geographic locations
|
||
|
|
||
|
### URL Validation and Security
|
||
|
|
||
|
1. Protocol Validation:
|
||
|
- URLs MUST start with one of the supported protocols
|
||
|
- Custom protocols MAY be supported by clients but MUST be clearly marked
|
||
|
- Clients SHOULD implement appropriate security measures for each protocol
|
||
|
|
||
|
2. Protocol-Specific Metadata:
|
||
|
```json
|
||
|
{
|
||
|
"kind": 30001,
|
||
|
"tags": [
|
||
|
["ll", "list"],
|
||
|
["title", "Mixed Protocol Resources"],
|
||
|
["nl", "https://example.com", "Web Resource"],
|
||
|
["nl", "magnet:?xt=urn:btih:...", "Linux ISO Torrent", null, null, "torrent"],
|
||
|
["nl", "ipfs://Qm...", "IPFS Document", null, null, "ipfs"],
|
||
|
["nl", "nostr:npub1...", "Nostr Profile", null, null, "nostr"]
|
||
|
],
|
||
|
"content": ""
|
||
|
}
|
||
|
```
|
||
|
|
||
|
3. Client Handling:
|
||
|
- Clients MUST verify protocol support before attempting to open links
|
||
|
- Clients SHOULD display appropriate icons/indicators for different protocols
|
||
|
- Clients MAY implement protocol-specific preview features
|
||
|
- Clients SHOULD warn users when opening non-HTTP protocols
|
||
|
|
||
|
### Examples
|
||
|
|
||
|
1. Basic link list with default language:
|
||
|
```json
|
||
|
{
|
||
|
"kind": 30001,
|
||
|
"tags": [
|
||
|
["ll", "list"],
|
||
|
["title", "Favorite Programming Resources"],
|
||
|
["lang", "en"],
|
||
|
["dir", "ltr"],
|
||
|
["nl", "https://example.com/tutorial", "Great Python Tutorial"],
|
||
|
["t", "programming"]
|
||
|
],
|
||
|
"content": ""
|
||
|
}
|
||
|
```
|
||
|
|
||
|
2. Multilingual list with mixed content:
|
||
|
```json
|
||
|
{
|
||
|
"kind": 30001,
|
||
|
"tags": [
|
||
|
["ll", "list"],
|
||
|
["title", "Global Dev Resources"],
|
||
|
["lang", "en"],
|
||
|
["dir", "ltr"],
|
||
|
["nl", "https://example.com/docs", "Documentation"],
|
||
|
["nl", "https://arabic-example.com/tutorial", "شرح البرمجة", "ar", "rtl"],
|
||
|
["nl", "https://japanese-site.com/guide", "プログラミング入門", "ja"],
|
||
|
["t", "programming"],
|
||
|
["t", "tutorials"]
|
||
|
],
|
||
|
"content": ""
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Relationship to Other NIPs
|
||
|
|
||
|
This NIP builds upon and complements several existing NIPs:
|
||
|
|
||
|
1. [NIP-01](01.md) provides the basic protocol structure we build upon
|
||
|
2. [NIP-23](23.md) demonstrates handling of longer-form content
|
||
|
3. [NIP-51](51.md) defines lists, including bookmarks (kind:10003) which are primarily for personal use - saving posts, articles, and URLs for later reading. While NIP-51's bookmarks serve as a private reading list, NIP-74 focuses on public, shareable collections designed for distribution and discovery:
|
||
|
- Curated collections meant to be shared (like "link-in-bio" lists)
|
||
|
- Rich metadata for the collection as a whole
|
||
|
- Consistent theme or purpose across all links
|
||
|
- Enhanced internationalization support
|
||
|
- Protocol-specific handling for various link types
|
||
|
- Collection-level discovery and organization
|
||
|
|
||
|
For example:
|
||
|
- NIP-51 Bookmark: "Save this article to read later" (personal use)
|
||
|
- NIP-74 Link List: "My public collection of resources about Nostr" (sharing with others)
|
||
|
|
||
|
This separation of concerns allows:
|
||
|
- NIP-51 to handle personal, private bookmarking for later reading
|
||
|
- NIP-74 to focus on public, curated collections meant for sharing
|
||
|
- Users to have both private reading lists and public resource collections
|
||
|
|
||
|
## Finding Link Lists
|
||
|
|
||
|
To discover a user's link lists:
|
||
|
1. Filter for events by the user's pubkey
|
||
|
2. Filter for events with kind 30001
|
||
|
3. Filter for events with the tag `["ll", "list"]`
|
||
|
|
||
|
## Client Behavior
|
||
|
|
||
|
### Required Behavior
|
||
|
|
||
|
Clients MUST:
|
||
|
- Include the `["ll", "list"]` tag in all link list events
|
||
|
- Validate URLs to ensure they:
|
||
|
- Start with http:// or https://
|
||
|
- Have a non-empty description
|
||
|
- Support Unicode domains (IDN/Punycode)
|
||
|
- Handle both profile-level and link-level language settings
|
||
|
- Support RTL text rendering when specified
|
||
|
|
||
|
### Recommended Behavior
|
||
|
|
||
|
Clients SHOULD:
|
||
|
- Display link lists in a way that makes their curated nature clear
|
||
|
- Respect language and text direction settings
|
||
|
- Provide ways to discover lists by topic/hashtag
|
||
|
- Support Unicode normalization for non-Latin text
|
||
|
- Handle bidirectional text properly
|
||
|
|
||
|
Clients MAY:
|
||
|
- Fetch link previews (titles, descriptions, images)
|
||
|
- Provide specialized UI for different types of links
|
||
|
- Support list organization features
|
||
|
- Implement list sharing and discovery features
|
||
|
|
||
|
## Implementation Notes
|
||
|
|
||
|
1. Language Support
|
||
|
- Use ISO 639-1 two-letter codes (e.g., "en", "es", "ar", "ja")
|
||
|
- Default to profile language if not specified per link
|
||
|
- Support both LTR and RTL text rendering
|
||
|
- Handle mixed-language content appropriately
|
||
|
|
||
|
2. URL Handling
|
||
|
- Validate URLs before displaying
|
||
|
- Support IDN/Punycode domains
|
||
|
- Consider implementing preview safety measures
|
||
|
|
||
|
3. Backward Compatibility
|
||
|
- Default to "en"/"ltr" when language/direction not specified
|
||
|
- Support legacy formats during transition
|
||
|
- Handle missing optional tags gracefully
|
||
|
|
||
|
## Extensions
|
||
|
|
||
|
Future extensions might include:
|
||
|
- Link categorization within lists
|
||
|
- Collaborative list editing
|
||
|
- List versioning
|
||
|
- Enhanced metadata for specific link types
|
||
|
- Integration with other NIPs (e.g., reactions, comments)
|
||
|
|
||
|
## References
|
||
|
|
||
|
- [NIP-01: Basic protocol flow description](01.md)
|
||
|
- [NIP-23: Long-form Content](23.md)
|
||
|
- [NIP-51: Lists](51.md)
|