Marketing site for BW Player — a monochrome music player for Android, iOS, and macOS. Stream, mix, and queue from Last.fm, Audius, and Jamendo with a calm UI where album art is the only color on screen.
Repository: github.com/aksharahegde/bw-player-website
Production: bwplayer.akshara.dev
| Layer | Choice |
|---|---|
| Framework | Nuxt 4 (Vue 3, TypeScript) |
| Styling | Tailwind CSS 4 + custom landing tokens |
| Typography | Newsreader (display), DM Sans (UI) |
| SEO | @nuxtjs/seo — sitemap, robots, Schema.org, OG images |
| OG images | Satori + @resvg/resvg-js (BwPlayerOg template) |
| Motion | anime.js (hero entrance, scroll reveals, hover; respects prefers-reduced-motion) |
The home page is prerendered (/, /sitemap.xml, /robots.txt) for fast static hosting.
- Hero with platform list and app mockup
- Editorial features showcase (Discover, Smart Mix, Now Playing, Library, Design)
- Mood cards and streaming source cards (Last.fm, Audius, Jamendo)
- Download CTAs (placeholders until store URLs are set)
- Footer with site credit
- Bun 1.x (recommended; lockfile included) or Node.js 20+
- Git
git clone git@github.com:aksharahegde/bw-player-website.git
cd bw-player-website
bun install
cp .env.example .envEdit .env and set NUXT_PUBLIC_SITE_URL to your deployment URL (production: https://bwplayer.akshara.dev; local dev can use http://localhost:3000).
| Command | Description |
|---|---|
bun run dev |
Start dev server (wraps nuxt dev; on macOS sets TMPDIR=/tmp to avoid SSR socket path limits) |
bun run build |
Production build |
bun run preview |
Preview production build locally |
bun run generate |
Static generation (if you deploy as fully static output) |
npm equivalents: npm install, npm run dev, etc.
| Variable | Required | Description |
|---|---|---|
NUXT_PUBLIC_SITE_URL |
Yes (prod) | Canonical site URL for meta, sitemap, OG, and JSON-LD @id |
NUXT_PUBLIC_TWITTER_SITE |
No | Twitter handle for cards (e.g. @bwplayer) |
NUXT_PUBLIC_ANDROID_STORE_URL |
No | Play Store URL for Schema.org downloadUrl |
NUXT_PUBLIC_IOS_STORE_URL |
No | App Store URL |
NUXT_PUBLIC_MAC_STORE_URL |
No | Mac App Store or direct download URL |
See .env.example for defaults.
app/
pages/index.vue # Single-page landing
content/landing.ts # Typed copy (source of truth for UI strings)
composables/
useLandingSeo.ts # Meta, OG, Schema.org
useLandingAnime.ts # Client motion (anime.js)
components/
landing/ # Mockups, features showcase
OgImage/BwPlayerOg.satori.vue
assets/css/ # main.css + landing.css
public/
mockups/now-playing-overview.png # Hero — light + dark Now Playing overview
favicon.svg, providers/ # Provider logos
LANDING_CONTENT.md # Human-editable copy mirror (keep in sync with landing.ts)
- Edit marketing copy in LANDING_CONTENT.md (planning / review).
- Apply the same strings in app/content/landing.ts (what the app renders).
| Placement | Type | Source |
|---|---|---|
| Hero | Screenshot (overview) | public/mockups/now-playing-overview.png — light and dark Now Playing side-by-side. Set via landingHero.mockupImage in app/content/landing.ts; rendered with LandingAppMockup (presentation="overview", caption from landingHero.mockupLabel). |
| Features showcase | Vue components | app/components/landing/mockups/ — Discover, Smart Mix, Now Playing, Library |
To change the hero image, replace public/mockups/now-playing-overview.png (or update landingHero.mockupImage if using another path).
To use screenshots on a feature tile instead of a Vue mockup, add PNGs under public/mockups/ and map the screen in landingMockupImages in app/content/landing.ts.
Provider logos live in public/providers/ (monochrome SVGs).
- Sitemap, robots, and structured data are configured via
@nuxtjs/seoanduseLandingSeo. - Dynamic OG images use the
BwPlayerOgSatori component; fonts are listed innuxt.config.ts.
Regenerate PWA icons after changing the favicon:
bunx nuxt-seo-utils icons --source public/favicon.svg- Set
NUXT_PUBLIC_SITE_URLin the host environment. - Run
bun run buildand deploy the Nitro output (Node server) or usebun run generatefor static hosts that support the generated output. - Optional: set store URLs and
NUXT_PUBLIC_TWITTER_SITEbefore go-live.
Works well on Vercel, Netlify, Cloudflare Pages, or any Node/Nitro-compatible platform.
MIT — see LICENSE.
Built with ♥ by Akshara Hegde.
