MusicPrompt 2.1
2.0 shipped the workspace. 2.1 is about making sure people can find it — and it starts with an uncomfortable discovery.
The 2.0 SEO work was never live
Everything 2.0 built for search — prerendered pages, per-page titles, hreflang, structured data, a real 404 — was sitting on an unmerged branch. Production was still serving the previous build as a client-only app, which meant every English URL returned byte-identical HTML with a canonical link pointing at the home page. Search engines were being told, explicitly, that nothing except the home page was worth indexing.
That is fixed. It was also the single largest thing on this list; everything below is a real but much smaller improvement on top of it.
One h1 per page, and landmarks everywhere
The changelog rendered two h1 elements — one from the page, one from each release's markdown — and would have grown another with every release. Release titles are now demoted to h2, so the page keeps a single heading root no matter how long it gets.
Library genre and mood pages jumped straight from h1 to h3, and mood pages had no h2 at all. They now have a real section heading above the blueprint grid. /blog, blog posts and guide pages were missing a <main> landmark; all page types have exactly one now.
Fonts are self-hosted
Every page was blocking on a stylesheet from a third-party font host before it could paint. Both families are variable fonts, so the whole set is now two files totalling 70 KB, served from the same origin and preloaded.
The Studio workspace also moved into its own chunk. It is the largest component tree in the app and is reachable from exactly one route, so every marketing and library page was downloading it for nothing.
Structured data on every page type
/guides, /blog, /changelog and /studio had no JSON-LD at all. They now carry ItemList and BreadcrumbList, guide and blog posts gained breadcrumbs, and every page carries site-level Organization and WebSite nodes.
No SearchAction was added. The library filters in memory and has no URL you can send a search to, and declaring an endpoint that does not resolve is worse than declaring none.
Icons, and a real /favicon.ico
The icon existed only as a data URI inlined into each page, so a direct request for /favicon.ico — which crawlers and link-preview bots make — returned the app shell. There is now a real icon file, an Apple touch icon, and a web manifest.
Social cards are no longer shared: each library genre gets its own generated card carrying its name and blueprint count, so links to different genres no longer preview identically.
Guides, doubled
Three of the four guides carried under seventy words of their own once the header and footer were discounted. All three have been rewritten at length, and two guides have been added: one on section tags and song structure, one on using the Exclude field without over-constraining.
/blog also stopped claiming to be a how-to collection. It was competing with /guides for the same readers while holding a single post; it is now what it actually is — notes on how the product got built.
Smaller things
Meta descriptions were cut at 155 characters mid-word; they now break on a word boundary. The language switcher was a pair of buttons, so there was no crawlable link between the English and Chinese versions of a page — it renders real links now. A hardcoded keyword list and author tag were being emitted on all 57 pages, including every Chinese one; both are gone.