<sfg545 />

/* 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

  1. Open Settings.
  2. Choose Updates.
  3. In Artist pages, choose Import pack.
  4. Select a .orchardpack, .zip, or .zst file 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 use 1
  • artistName: canonical artist name
  • displayName: page title. Orchard falls back to artistName for the detail page title.
  • layout: appended to the page as detail-page--layout-${layout} for CSS hooks. Orchard does not enforce a fixed layout list.
  • assets.thumbnail: image used in artist cards and fallback profile art
  • assets.profile: main artist image
  • assets.hero: hero background image, when supplied
  • assets.immersive: immersive background image, when supplied
  • search.canonicalQuery: query Orchard should use when an alias redirects search
  • search.aliases: exact normalized names that should prioritize this artist in search
  • banner: optional custom hero banner metadata
  • features: optional feature flags and renderer hints
  • theme.cssVariables: CSS variables applied to the artist page
  • previews: optional album hover-preview map

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 the previews map
  • animatedArtwork: attempts to show enhanced animated artwork videos on album-card hover or focus
  • highlightWords: words in the artist subtitle that Orchard highlights
  • keyEasterEgg: 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.