Files
client/docs/MUSIC_URL_STRUCTURE.md

107 lines
3.9 KiB
Markdown

# Music & VJ URL Structure
Unified URL schema for `music.html` and `vj.html`.
## URL Anatomy
```
https://example.com/vj.html?show=reggae&npub=npub1abc#/playlist/ep-1744382400
\______________________/\________/ \_______________/ \________________________/
origin pathname query string hash fragment
```
## Query String Parameters
Query string parameters represent **identity and session context**. They persist across hash navigation changes.
| Parameter | Format | Pages | Required | Description |
|-----------|--------|-------|----------|-------------|
| `npub` | `npub1...` | both | no | Target user public key in npub format (preferred) |
| `pubkey` | 64-char hex | both | no | Target user public key in hex format (fallback) |
| `auth` | `required` \| `optional` \| `none` | both | no | Authentication mode override |
| `show` | slug string | both | no | Active show slug (e.g. `saturday-reggae`) |
| `episode` | identifier string | both | no | Active episode playlist identifier |
| `a` | `30311:{pubkey}:{slug}` | vj.html | no | Stream coordinate for direct stream targeting |
| `naddr` | `naddr1...` | vj.html | no | Nostr address encoding of stream event |
### Parameter Precedence
- `npub` takes priority over `pubkey` when both are present
- `pubkey` is deleted from URL when `npub` is set
- If `npub` or `pubkey` points to a different user than the logged-in user, the page enters **read-only mode**
## Hash Fragment Routes
Hash routes represent **in-page navigation state**. Changing the hash does not reload the page.
| Route | Description |
|-------|-------------|
| `#/` | Home — empty search view |
| `#/search/{query}` | Search results for the given query |
| `#/album/{albumId}` | Album detail drill-down |
| `#/artist/{artistId}` | Artist detail drill-down |
| `#/track/{trackId}` | Play a specific track by ID |
| `#/playlist/{identifier}` | Open own playlist/episode by identifier |
| `#/playlist/{pubkey}/{identifier}` | Open external playlist/episode by pubkey and identifier |
### Route Parsing
Routes are parsed by splitting the hash on `/`:
```
#/playlist/abc123/ep-42 → { page: 'playlist', parts: ['abc123', 'ep-42'] }
#/search/bob marley → { page: 'search', parts: ['bob marley'] }
#/track/36787:pubkey:dTag → { page: 'track', parts: ['36787:pubkey:dTag'] }
```
## URL Examples
### VJ working on own show
```
vj.html?show=saturday-reggae&episode=ep-1744382400
```
### Sharing an episode for playback on music.html
```
music.html?npub=npub1abc123...#/playlist/npub1abc123.../ep-1744382400
```
### Sharing a VJ episode for viewing
```
vj.html?npub=npub1abc123...&show=saturday-reggae&episode=ep-1744382400
```
### Direct track link (works on either page)
```
music.html#/track/36787:aaaaaaaa...:my-track-dtag
vj.html#/track/36787:aaaaaaaa...:my-track-dtag
```
### Search link
```
music.html#/search/bob%20marley
```
### Album link
```
music.html#/album/album-id-here
```
## URL Update Behavior
| User Action | URL Change | Method |
|-------------|-----------|--------|
| Select show in dropdown | `?show={slug}` added/updated | `replaceState` |
| Select/create episode | `?episode={id}` added/updated | `replaceState` |
| Search for music | `#/search/{query}` | hash assignment |
| Click album/artist | `#/album/{id}` or `#/artist/{id}` | hash assignment |
| Play track from link | `#/track/{id}` (`id` is now typically `36787:pubkey:dTag`) | hash assignment |
| Select playlist | `#/playlist/{id}` | hash assignment |
| Login / auth change | `?npub={npub}` added | `replaceState` |
| Load external user | `?npub={npub}` or `?pubkey={hex}` | page navigation |
### replaceState vs hash assignment
- **`replaceState`** — Used for context changes (show, episode, auth). Does not create a new history entry. The user does not get a "back" step for every dropdown change.
- **Hash assignment** — Used for navigation changes (search, album, track, playlist). Creates a new history entry. Back/Forward buttons navigate between views.