Files
minstrel/web/vite.config.ts
T
bvandeusen 180d85eec0 chore(web): post-#363 cleanup — DRY tripwires, drop unused description, singular playlist title
M2 — Add TODO(#375) tripwire comments where the dark/light theme-color
hex pair is duplicated outside tokens.json (vite.config.ts and
applyMetaThemeColor.svelte.ts). Refactoring is out of scope for #363;
the comments are stop signs for the next person who edits these.

M5 — The SPA never reads window.__MINSTREL__.description. The OG meta
description is server-rendered and complete on its own. Drop the dead
inline-script field and the corresponding helpers in branding.ts.
Server-side BrandingConfig.Description stays — it's still used for
<meta name="description"> and og:description.

Copy nit — Playlist detail page title becomes "Playlist · Foo"
matching the singular form already used by Artist · / Album ·.
2026-05-03 19:04:59 -04:00

69 lines
2.7 KiB
TypeScript

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { execSync } from 'node:child_process';
const tokensPlugin = {
name: 'minstrel-tokens',
buildStart() {
execSync('node scripts/tokens-to-css.js', { stdio: 'inherit' });
}
};
// Build-only plugin that injects Go html/template tokens into the
// rendered index.html so the runtime Go server can substitute per-
// instance branding. In dev (`vite dev`), the marker stays as a
// comment and the SPA falls back to the literal app.html title.
// `enforce: 'post'` ensures this runs after SvelteKit's own
// transformIndexHtml so %sveltekit.head% is already expanded into
// hydration markup before our anchors are rewritten.
const injectGoTokensPlugin = {
name: 'minstrel-inject-go-tokens',
apply: 'build' as const,
enforce: 'post' as const,
transformIndexHtml(html: string) {
const titleTag = `<title>{{ .AppName }}</title>`;
const headBlock = `
<meta name="description" content="{{ .Description }}">
<meta property="og:title" content="{{ .AppName }}">
<meta property="og:description" content="{{ .Description }}">
<meta property="og:image" content="/brand/og-image.png">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<!-- TODO(#375): keep theme-color hex in sync with tokens.json colors.dark.obsidian / colors.light.obsidian -->
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#14171A">
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#F8F5EE">
<script>window.__MINSTREL__ = { appName: "{{ .AppName }}" };</script>`;
// Fail loudly if either anchor drifts. A silent .replace() no-op
// would ship a build with un-substituted Go template tokens missing,
// and the runtime brand override would silently break — exactly the
// class of regression a build-time plugin should catch.
if (!html.includes('<title>Minstrel</title>')) {
throw new Error('minstrel-inject-go-tokens: <title>Minstrel</title> anchor missing from rendered index.html');
}
if (!html.includes('<!-- MINSTREL_TOKENS -->')) {
throw new Error('minstrel-inject-go-tokens: <!-- MINSTREL_TOKENS --> anchor missing from app.html');
}
return html
.replace('<title>Minstrel</title>', titleTag)
.replace('<!-- MINSTREL_TOKENS -->', headBlock);
}
};
export default defineConfig({
plugins: [tokensPlugin, sveltekit(), injectGoTokensPlugin],
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:4533',
changeOrigin: true
},
'/rest': {
target: 'http://localhost:4533',
changeOrigin: true
}
}
}
});