/* Extensions */
Artist Page Packs
Create and install local Orchard artist page packs with JSON, CSS, image assets, and album hover previews.
Orchard artist pages are data-only packs. The app keeps the renderer, playback logic, and safety-sensitive behavior local. A pack supplies JSON metadata, CSS, image assets, search aliases, banner metadata, theme variables, and optional preview behavior.
Users install community artist pages from files on their own computer. They do not need to publish anything to a server.
Installing a Pack
- Open Settings.
- Choose Updates.
- In Artist pages, choose Import pack.
- Select a
.orchardpack,.zip, or.zstfile from your computer.
Imported packs are copied into Orchard’s app data folder and loaded ahead of official artist page content. A user pack may override only the artist ID declared in its own artist.json.
Pack Layout
A user pack is one zip archive for one artist. Zstandard-compressed zip archives are also accepted by builds that support Node’s Zstandard decompressor.
kehlani.orchardpack
artist.json
style.css
assets/
kehlani-profile.webp
manifest.json is optional for user packs and is not required by the importer. Orchard requires artist.json at the archive root.
Allowed files:
artist.json
manifest.json
style.css
assets/**/*.png
assets/**/*.webp
assets/**/*.jpg
assets/**/*.jpeg
assets/**/*.mp3
JavaScript, HTML, nested archives, and files outside those paths are rejected. The archive and its unpacked entries must stay under 50 MiB.
Artist Config
Each user pack has one artist.json. This example matches the current Kehlani official artist page pack:
{
"schema": 1,
"artistId": "UCONwFIjhxe4MR2sY3Cv0adA",
"artistName": "Kehlani",
"displayName": "Kehlani",
"layout": "kehlani",
"assets": {
"thumbnail": "assets/kehlani-profile.webp",
"profile": "assets/kehlani-profile.webp"
},
"search": {
"canonicalQuery": "Kehlani"
},
"banner": {
"type": "albumWall",
"sources": ["album", "single", "ep"],
"limit": 12
},
"features": {
"hoverPreviews": true,
"animatedArtwork": true,
"highlightWords": ["Kehlani Ashley Parrish"]
},
"theme": {
"cssVariables": {
"--custom-artist-accent": "#dca4b0",
"--custom-artist-ink": "#1e0c1b",
"--custom-artist-ink-soft": "#2d1329"
}
}
}
Required for import:
artistId: the YouTube Music artist browse ID the pack applies to. It must be 8 to 80 characters and contain only letters, numbers,_, or-.
Expected by the page renderer:
schema: current packs use1artistName: canonical artist namedisplayName: page title. Orchard falls back toartistNamefor the detail page title.layout: appended to the page asdetail-page--layout-${layout}for CSS hooks. Orchard does not enforce a fixed layout list.assets.thumbnail: image used in artist cards and fallback profile artassets.profile: main artist imageassets.hero: hero background image, when suppliedassets.immersive: immersive background image, when suppliedsearch.canonicalQuery: query Orchard should use when an alias redirects searchsearch.aliases: exact normalized names that should prioritize this artist in searchbanner: optional custom hero banner metadatafeatures: optional feature flags and renderer hintstheme.cssVariables: CSS variables applied to the artist pagepreviews: optional album hover-preview map
Banner
The current banner type is albumWall. Orchard builds the wall from matching artist sections and optional fixed tiles.
{
"banner": {
"type": "albumWall",
"sources": ["album", "single", "ep"],
"limit": 12,
"tiles": [
{
"id": "featured",
"title": "Featured artwork",
"assetKey": "profile"
}
]
}
}
sources are matched against section keys and titles. limit is clamped between 4 and 18. A tile may provide image directly, or reference an asset with assetKey or asset.
Features
Supported features values:
hoverPreviews: enables album-card audio previews from thepreviewsmapanimatedArtwork: attempts to show enhanced animated artwork videos on album-card hover or focushighlightWords: words in the artist subtitle that Orchard highlightskeyEasterEgg: a keyboard sequence that can play a local audio asset and/or start a target track
keyEasterEgg is configured under features:
{
"assets": {
"easterEggAudio": "assets/sting.mp3"
},
"features": {
"keyEasterEgg": {
"keys": ["2", "2", "3", "2"],
"audioAsset": "easterEggAudio",
"targetTrack": {
"id": "T6eK-2OQtew",
"title": "Not Like Us",
"artist": "Kendrick Lamar"
}
}
}
}
The audioAsset value is an asset key, not a file path. Orchard resolves it through the assets map after import.
Hover Previews
Preview keys are YouTube Music album browse IDs. Each value points to a YouTube Music track and a start time. Kehlani enables the preview system but does not currently define fixed preview entries; add previews only when an album card should play a specific audio segment.
{
"previews": {
"MPREb_exampleAlbumBrowseId": {
"label": "Album - Song",
"videoId": "exampleTrackVideoId",
"start": 31,
"duration": 30
}
}
}
videoId is the YouTube Music track ID, start is seconds from the beginning of the track, and duration is the preview length in seconds. If start is missing, Orchard starts at 0; if duration is missing, Orchard uses 30.
Hosted Official Packs
Community users usually import one-artist packs locally. Orchard’s official hosted packs use a different archive layout with multiple artists:
manifest.json
artists/
UCONwFIjhxe4MR2sY3Cv0adA/
artist.json
style.css
assets/
kehlani-profile.webp
Official packs must include manifest.json and at least one artists/{artistId}/artist.json whose artistId matches its folder name. The public index has this shape:
{
"schema": 1,
"kind": "orchard-official-artist-pack-index",
"version": "1.5.0-custom-artists.34",
"archive": {
"url": "./orchard-official-artists-1.5.0-custom-artists.34.orchardpack.zst",
"sha256": "...",
"size": 12345
},
"artists": {
"UCONwFIjhxe4MR2sY3Cv0adA": {
"artistId": "UCONwFIjhxe4MR2sY3Cv0adA",
"artistName": "Kehlani",
"displayName": "Kehlani",
"layout": "kehlani",
"search": {
"canonicalQuery": "Kehlani"
},
"profileArtwork": "assets/kehlani-profile.webp"
}
}
}
Hosted entries may also point directly to per-artist config and style URLs with config.url, assetBaseUrl, profileArtwork, and styles.
CSS
style.css is loaded only for the declared artist page. Scope selectors to the artist ID:
.detail-page--artist[data-artist-id="UCONwFIjhxe4MR2sY3Cv0adA"] {
--kehlani-accent: var(--custom-artist-accent, #dca4b0);
--kehlani-ink: var(--custom-artist-ink, #1e0c1b);
}
.detail-page--artist[data-artist-id="UCONwFIjhxe4MR2sY3Cv0adA"].detail-page--layout-kehlani .detail-title-line h2 {
color: var(--kehlani-accent);
font-family: "Georgia", "Times New Roman", serif;
font-style: italic;
}
The page root exposes data-artist-id, and layout adds a detail-page--layout-{layout} class. CSS should only style the page. Do not attempt to hide application controls, fake system dialogs, or depend on remote url() assets.
Safety Rules
Artist packs are content, not plugins.
- Do not include executable JavaScript.
- Keep all behavior in Orchard’s local renderer.
- Use JSON for metadata, preview maps, layout keys, aliases, banner settings, feature flags, and theme variables.
- Use CSS only for visual styling.
- Keep images and MP3 assets inside
assets/. - Keep archives small enough for quick import.
- Use one artist per user archive.
Creating the Zip
From inside your pack folder:
zip -r kehlani.orchardpack artist.json style.css assets
Then import kehlani.orchardpack from Orchard’s Updates > Artist pages section.