nips/74.md

236 lines
8.3 KiB
Markdown
Raw Normal View History

# 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: 30011
Link list events use kind `30011`. This number was chosen because:
1. The "11" in 30011 visually resembles "ll" for "link list"
2. It falls within the addressable event range (30000-39999) as defined in NIP-01
3. Maintains separation from other list-type events (30000-30009)
4. Avoids conflict with previously used kind numbers
As an addressable event (NIP-01), for each combination of `kind`, `pubkey`, and `d` tag value, only the latest event will be stored by relays, allowing for efficient updates to link lists.
### 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
- `d` [identifier] - Identifier and title 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] - Additional 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": 30011,
"tags": [
["ll", "list"],
["d", "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": 30011,
"tags": [
["ll", "list"],
["d", "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": 30011,
"tags": [
["ll", "list"],
["d", "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 30011
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)