NIPs by PolleramaCommunity NIPs, surfaced by trustConnect
npub14rg4vrt2v37...

Shakespeare.wtf URL Registry

Published Jan 4, 2026
kind 32579

NIP-XX: Shakespeare.wtf URL Registry

draft optional

This NIP defines a standardized way to catalog and share URLs with the format https://*.shakespeare.wtf across the Nostr network.

Kind 32579: Shakespeare URL Entry

A kind 32579 event represents a single shakespeare.wtf URL entry in a distributed registry. This allows clients to efficiently discover and index shakespeare.wtf links without scanning all text notes.

Event Format

{
  "kind": 32579,
  "tags": [
    ["d", "<url-identifier>"],
    ["url", "<full-url>"],
    ["title", "<optional-title>"],
    ["description", "<optional-description>"],
    ["published_at", "<unix-timestamp>"],
    ["t", "shakespeare"],
    ["category", "<root|path>"]
  ],
  "content": "<optional-notes-or-context>",
  "created_at": <unix-timestamp>,
  "pubkey": "<author-pubkey>"
}

Tags

  • **d (required)**: A unique identifier for this URL entry. Recommended format: subdomain name (e.g., my-app for https://my-app.shakespeare.wtf)
  • **url (required)**: The full URL including protocol in the format https://<subdomain>.shakespeare.wtf (e.g., https://my-app.shakespeare.wtf)
  • **title (optional)**: Human-readable title for the URL
  • **description (optional)**: Brief description of what the URL points to
  • **published_at (optional)**: When the content at this URL was originally published (unix timestamp)
  • **t (required)**: Always set to "shakespeare" for discoverability via relay filtering
  • **category (optional)**: Either "root" for URLs at the subdomain root (e.g., https://app.shakespeare.wtf), or "path" for URLs with additional path segments (e.g., https://app.shakespeare.wtf/page)

Content Field

The content field may contain:

  • Additional notes or context about the URL
  • A quote or excerpt from the linked content
  • Personal commentary from the publisher
  • Empty string if no additional context is needed

Behavior

  • Replaceable: Since this is an addressable event (30000-39999 range), only the most recent event per pubkey + kind + d tag combination is kept by relays
  • User Curation: Each user can maintain their own list of shakespeare.wtf URLs, with their own titles and descriptions
  • Deduplication: Multiple users can catalog the same URL with different d tags, titles, or descriptions based on their perspective

Use Cases

  1. URL Discovery: Clients can query for all kind 32579 events to find shakespeare.wtf links
  2. Personal Bookmarks: Users maintain their own curated list of shakespeare.wtf URLs
  3. Metadata Enhancement: Add titles and descriptions to URLs for better presentation
  4. Category Filtering: Filter between root URLs and path URLs using the category tag
  5. Efficient Indexing: Relays can efficiently index and search these events using the #t tag filter

Example Events

Root URL Entry (subdomain root)

{
  "kind": 32579,
  "tags": [
    ["d", "my-app"],
    ["url", "https://my-app.shakespeare.wtf"],
    ["title", "My Awesome Nostr App"],
    ["description", "A social app built with Shakespeare"],
    ["published_at", "1704067200"],
    ["t", "shakespeare"],
    ["category", "root"]
  ],
  "content": "Check out my new Nostr app built with Shakespeare!",
  "created_at": 1704153600,
  "pubkey": "a8d1560d6a647d501699167246f237b36fb123f89168fda11dc743533fec7a08"
}

Path URL Entry (subdomain with path)

{
  "kind": 32579,
  "tags": [
    ["d", "my-app-article"],
    ["url", "https://my-app.shakespeare.wtf/article/getting-started"],
    ["title", "Getting Started Guide"],
    ["description", "How to use My Awesome Nostr App"],
    ["t", "shakespeare"],
    ["category", "path"]
  ],
  "content": "A comprehensive guide for new users",
  "created_at": 1704153600,
  "pubkey": "b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc"
}

Querying

Find all Shakespeare URLs

const urls = await nostr.query([
  {
    kinds: [32579],
    '#t': ['shakespeare'],
    limit: 100
  }
]);

Find URLs by specific user

const myUrls = await nostr.query([
  {
    kinds: [32579],
    authors: [userPubkey],
    '#t': ['shakespeare']
  }
]);

Find only root URLs

const rootUrls = await nostr.query([
  {
    kinds: [32579],
    '#t': ['shakespeare'],
    '#category': ['root']
  }
]);

Publishing

When publishing a kind 32579 event, always include the NIP-31 alt tag for human-readable descriptions:

{
  "kind": 32579,
  "tags": [
    ["d", "my-app"],
    ["url", "https://my-app.shakespeare.wtf"],
    ["t", "shakespeare"],
    ["alt", "Shakespeare URL registry entry for https://my-app.shakespeare.wtf"]
  ],
  "content": "",
  ...
}

Rationale

Why Not Use Existing Kinds?

  • Kind 30023 (Long-form Content): Designed for articles, not URL catalogs
  • Kind 30001 (Generic Lists): Could work but lacks shakespeare-specific semantics
  • Kind 1 (Text Notes): Inefficient for discovery; requires full-text search
  • Custom Kind: Provides semantic clarity, efficient querying, and future extensibility

Why Addressable?

Addressable events allow users to update their entries for specific URLs. For example:

  • Update the title or description
  • Add metadata as it becomes available
  • Correct mistakes without creating duplicates

URL Format

All shakespeare.wtf URLs follow the subdomain format:

  • Format: https://<subdomain>.shakespeare.wtf[/path]
  • Examples:
  • https://my-app.shakespeare.wtf (root)
  • https://my-app.shakespeare.wtf/page (with path)
  • https://chat.shakespeare.wtf
  • https://blog.shakespeare.wtf/article/123

Design Decisions

  1. **d tag format**: Using the subdomain name (or a descriptive identifier for paths) makes entries human-readable and easy to manage. Each user can organize their registry however they prefer.
  1. **t tag**: Single-letter tag t is indexed by relays, enabling efficient filtering at the relay level without requiring full-text search.
  1. **category tag**: Allows filtering between subdomain roots and URLs with paths, which have different use cases (main app vs specific pages/articles).
  1. Flexible content: Supports both minimal entries (just URL + title) and rich entries (with context and commentary).

Implementation Notes

  • All URLs must use HTTPS protocol and follow the subdomain format https://*.shakespeare.wtf
  • Clients should validate URL format before creating registry entries
  • The same URL may have multiple entries from different users - this is intentional and allows for crowdsourced curation
  • Clients may choose to deduplicate URLs in their UI or show multiple perspectives
  • For d tags, using the subdomain name alone is recommended for root URLs (e.g., "my-app" for https://my-app.shakespeare.wtf)

References