NIP-89 App Handler
nsyte supports NIP-89 handler announcements, allowing your nsite to be discovered as a viewer/handler for specific Nostr event types.
What is NIP-89?
NIP-89 (Recommended Application Handlers) provides a way for applications to announce what event kinds they can handle. This enables cross-client discovery - when users encounter an unknown event type in their Nostr client, the client can find and suggest applications that can display that event type.
Event Kinds
- Kind 31990: Handler information event - Published by applications to announce their capabilities
- Kind 31989: Recommendation event - Published by users to recommend an app for handling specific event kinds
How nsyte Uses NIP-89
When enabled, nsyte will publish a kind 31990 event announcing that your nsite can handle/display specific event kinds. Other Nostr clients can then suggest your nsite when users encounter those event types.
Configuration
Publication of the handler announcement is controlled by the top-level publishAppHandler boolean. The appHandler block describes the handler itself (supported kinds, optional name/description/icon, optional platform handlers).
Add both fields to your .nsite/config.json:
{
"publishAppHandler": true,
"appHandler": {
"kinds": [1, 30023, 30311],
"name": "My Event Viewer",
"description": "A custom viewer for various Nostr events",
"platforms": {
"web": {
"patterns": [
{ "url": "https://myapp.com/e/<bech32>", "entities": ["nevent", "note"] },
{ "url": "https://myapp.com/a/<bech32>", "entities": ["naddr"] },
{ "url": "https://myapp.com/p/<bech32>", "entities": ["nprofile", "npub"] }
]
},
"android": "com.example.myapp",
"ios": "myapp://",
"macos": "myapp://",
"windows": "myapp.exe",
"linux": "myapp"
}
}
}Configuration Options
publishAppHandler(boolean, top-level, defaultfalse): Whether to publish the handler announcement. TheappHandlerblock is only emitted when this istrue(or when the--publish-app-handlerflag is passed).appHandler.kinds(number[], required whenappHandleris set): Array of event kind numbers this nsite can handle.appHandler.id(string, optional): Unique identifier used as thedtag in the kind 31990 event. Defaults to the siteidwhen omitted.appHandler.name(string, optional): Display name for your handler.appHandler.description(string, optional): Description of what your handler does.appHandler.icon(string, optional): URL to an icon image; included aspicturein the handler metadata.appHandler.platforms(object, optional): Platform-specific handler configurations.web.patterns(array, optional): Custom URL patterns for handling entities.url: Full URL pattern (e.g.,https://example.com/e/<bech32>).entities: Supported entity types (one or more ofnevent,naddr,nprofile,note,npub).
android(string, optional): Android app intent URL or package name.ios(string, optional): iOS app URL scheme or universal link.macos(string, optional): macOS app URL scheme or bundle identifier.windows(string, optional): Windows app protocol or executable path.linux(string, optional): Linux app command or desktop file.
Command Line Usage
You can also publish handler announcements via command line:
# Publish handler announcement with command line options
nsyte deploy ./site --publish-app-handler --handler-kinds "1,30023,30311"
# Or rely on the config file (publishAppHandler: true)
nsyte deploy ./site --publish-app-handlerThe --publish-app-handler flag forces publication for that single deploy. If you would rather flip it on permanently, set publishAppHandler: true in your .nsite/config.json.
Common Event Kinds
Here are some common event kinds you might want to handle:
1: Short text notes30023: Long-form content articles30311: Live events/streams1063: File metadata30078: Application-specific data31337: Audio tracks (Zapstr)
Example Use Cases
1. Blog Viewer
{
"publishAppHandler": true,
"appHandler": {
"kinds": [30023],
"name": "My Blog",
"description": "A beautiful reader for long-form content"
}
}2. Media Gallery
{
"publishAppHandler": true,
"appHandler": {
"kinds": [1063, 1, 6],
"name": "Media Gallery",
"description": "View images and media files"
}
}3. Event Archive
{
"publishAppHandler": true,
"appHandler": {
"kinds": [1, 6, 7, 30023],
"name": "Nostr Archive",
"description": "Archive viewer for various event types"
}
}How It Works
- When you upload with handler announcement enabled, nsyte creates a kind 31990 event
- This event includes:
- The event kinds your nsite can handle (
ktags) - Platform-specific handlers (web, android, ios, etc.)
- Web URLs with placeholders for bech32-encoded entities
- Optional metadata about your handler
- The event kinds your nsite can handle (
- The event is published to your configured relays
- Other Nostr clients can query for these handler events and suggest your nsite
Gateway URLs
The handler announcement uses your configured gateway hostname (default: nsite.lol) to construct URLs following the NIP-89 pattern:
Default Patterns
https://<your-npub>.nsite.lol/e/<bech32>- For event entities (nevent)https://<your-npub>.nsite.lol/a/<bech32>- For addressable entities (naddr)https://<your-npub>.nsite.lol/p/<bech32>- For profile entities (nprofile)
Custom Patterns
You can define custom URL patterns in your configuration to match your application's routing. These must be full URLs:
{
"appHandler": {
"platforms": {
"web": {
"patterns": [
{ "url": "https://myapp.com/events/<bech32>", "entities": ["nevent"] },
{ "url": "https://myapp.com/articles/<bech32>", "entities": ["naddr"] },
{ "url": "https://myapp.com/users/<bech32>", "entities": ["nprofile", "npub"] }
]
}
}
}
}Where <bech32> will be replaced by the client with the actual bech32-encoded entity.
Best Practices
- Only announce event kinds your nsite actually handles
- Provide clear name and description for better discovery
- Test that your nsite properly handles the announced event types
- Consider which bech32 entity types you support (nevent, naddr, note)
Permissions
The handler announcement (kind 31990) is automatically included in the NIP-46 permissions when using a bunker for signing.