- Album-art-tinted cards that crossfade on song change, equalizer bars, live avatar rings, drifting ambient colour, Space Grotesk display font, brand purple-to-blue gradient from the logo - Feed cards rise in and glide to new positions (motion); respects reduced-motion - New logo as nav mark, favicon and Apple touch icon - Installable PWA: manifest, maskable icons, small service worker (cached build assets + offline page), security headers - Show-QR-code on your own profile; centred profile header with stats - Settings explains connecting Spotify via Last.fm or ListenBrainz Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import { fileURLToPath } from 'node:url';
|
|
import type { NextConfig } from 'next';
|
|
|
|
const config: NextConfig = {
|
|
transpilePackages: ['@musicshare/shared'],
|
|
// Self-contained server bundle for the Docker image (only the files it needs).
|
|
output: 'standalone',
|
|
// Monorepo: trace files from the repo root so the shared package is included.
|
|
outputFileTracingRoot: fileURLToPath(new URL('../..', import.meta.url)),
|
|
async headers() {
|
|
return [
|
|
{
|
|
source: '/(.*)',
|
|
headers: [
|
|
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
{ key: 'X-Frame-Options', value: 'DENY' },
|
|
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
|
],
|
|
},
|
|
{
|
|
// The service worker must never be cached, or updates would never reach users.
|
|
source: '/sw.js',
|
|
headers: [
|
|
{ key: 'Content-Type', value: 'application/javascript; charset=utf-8' },
|
|
{ key: 'Cache-Control', value: 'no-cache, no-store, must-revalidate' },
|
|
{ key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self'" },
|
|
],
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
export default config;
|