Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ concurrency:

env:
VITE_BASE_URL: /cookmark/
SERVER_PRESET: github-pages

jobs:
build:
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ gitignore
.DS_Store
Thumbs.db
bundle-report.html

# local media source (uploaded to R2, not committed)
videos/

# local recipe data (sourced from the data branch / R2, not committed)
data/
data.local-backup/
60 changes: 49 additions & 11 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ import { defineConfig } from "@solidjs/start/config";
import { visualizer } from "rollup-plugin-visualizer";
import { VitePWA } from "vite-plugin-pwa";
import { getPrerenderRoutes } from "./scripts/getPrerenderRoutes.ts";
import { getVideoSlugs } from "./scripts/getVideoSlugs.ts";

// Single source of truth for the deploy base path (trailing slash included).
// GitHub Pages (project site) sets it to "/cookmark/"; Cloudflare Pages (root) uses "/".
const basePath = process.env.VITE_BASE_URL ?? "/";

// Baked into the bundle so recipe pages know which slugs have a video to stream.
const videoSlugs = getVideoSlugs();

export default defineConfig({
vite: {
define: {
__VIDEO_SLUGS__: JSON.stringify(videoSlugs),
},
plugins: [
visualizer({
filename: "bundle-report.html",
Expand Down Expand Up @@ -54,18 +65,18 @@ export default defineConfig({
theme_color: "#ffffff",
background_color: "#ffffff",
display: "standalone",
scope: "/cookmark/",
start_url: "/cookmark/",
scope: basePath,
start_url: basePath,
categories: ["food", "lifestyle"],
icons: [
{
src: "/cookmark/web-app-manifest-192x192.png",
src: `${basePath}web-app-manifest-192x192.png`,
sizes: "192x192",
type: "image/png",
purpose: "maskable any",
},
{
src: "/cookmark/web-app-manifest-512x512.png",
src: `${basePath}web-app-manifest-512x512.png`,
sizes: "512x512",
type: "image/png",
purpose: "maskable any",
Expand All @@ -76,21 +87,48 @@ export default defineConfig({
name: "Search Recipes",
short_name: "Search",
description: "Search for recipes",
url: "/cookmark/",
icons: [{ src: "/cookmark/favicon-96x96.png", sizes: "96x96" }],
url: basePath,
icons: [{ src: `${basePath}favicon-96x96.png`, sizes: "96x96" }],
},
],
},
}),
],
},
server: {
preset: "github-pages",
baseURL: process.env.GITHUB_REPOSITORY
? `/${process.env.GITHUB_REPOSITORY.split("/")[1]}/`
: "/",
// Default target is a Cloudflare Worker with Static Assets: it serves the
// prerendered site for free and runs dynamic routes (e.g. media streamed
// from R2). GitHub Pages builds pass SERVER_PRESET=github-pages for a pure
// static site (no server runtime).
preset: process.env.SERVER_PRESET ?? "cloudflare_module",
baseURL: basePath,
prerender: {
routes: getPrerenderRoutes() as string[],
routes: getPrerenderRoutes(basePath) as string[],
},
// Runtime-only routes (R2 streaming, per-user favourites) — never prerender.
routeRules: {
"/media/**": { prerender: false },
"/api/**": { prerender: false },
},
// Merged into the wrangler config nitro generates at .output/server.
// The ASSETS binding and `main` are added automatically by the preset.
cloudflare: {
// Generate .output/server/wrangler.json (+ deploy redirect) and enable
// nodejs_compat so `wrangler deploy` works from the project root.
deployConfig: true,
wrangler: {
name: "cookmark",
compatibility_date: "2025-07-15",
// Per-user favourites trust the Access JWT, so the app must only be
// reachable through the Access-fronted custom domain — not workers.dev.
workers_dev: false,
// Serve the app from the Access-protected custom domain.
routes: [{ pattern: "cookmark.kiralivan.eu", custom_domain: true }],
// Private bucket holding the recipe videos (videos/<slug>.mp4).
r2_buckets: [{ binding: "MEDIA", bucket_name: "cookmark" }],
// Per-user favourite recipe slugs, keyed by Access email.
kv_namespaces: [{ binding: "FAVORITES", id: "9be88640af5546f5b2341287ae842757" }],
},
},
},
});
10 changes: 9 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
"root": true,
"files": {
"ignoreUnknown": true,
"includes": ["src/**/*", "!.output", "!.vinxi", "!.claude", "!data", "!bundle-report.html"]
"includes": [
"src/**/*",
"!.output",
"!.vinxi",
"!.wrangler",
"!.claude",
"!data",
"!bundle-report.html"
]
},
"linter": {
"rules": {
Expand Down
Loading
Loading