# 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)