Build-time image optimization plus auth-gated private content. - <Image> (src/lib/components/Image.svelte): wraps @sveltejs/enhanced-img for public images under src/lib/assets/images/ (AVIF/WebP, multiple widths, lazy by default), plus a `private` mode for auth-gated images. - Private images: scripts/build-private-images.ts encodes sources from src/lib/assets/private-images/ into private-assets/ (outside the bundle) and a manifest; served only via the auth-checked /private-images/ endpoint (X-Accel-Redirect in prod, disk read in dev). - HikeImage gains a `src` prose mode: build-hikes encodes non-waypoint images referenced in .svx and exposes them by filename (imagesByName); a `private` attr routes them through the gated /hikes/<slug>/private/ path. - <Private> (src/lib/components/Private.svelte): renders prose only to logged-in viewers (cosmetic gating — text still ships in the bundle). - deploy.sh rsyncs private-assets/; prod needs an nginx internal /protected-images/ location.
1.6 KiB
Private (auth-gated) image sources
Drop private source images here, then render them with
<Image src="…" private /> from $lib/components/Image.svelte.
These can't use @sveltejs/enhanced-img — its output is a public asset. Instead
scripts/build-private-images.ts (runs at prebuild) encodes each image into
AVIF/WebP at multiple widths into private-assets/ (gitignored, outside the
client bundle) and writes src/lib/data/privateImages.generated.ts. The bytes
are served only through the auth-gated endpoint
src/routes/private-images/[...file]/+server.ts.
<script>
import Image from '$lib/components/Image.svelte';
</script>
<!-- `src` is relative to THIS folder; shows a lock badge -->
<Image src="receipt.jpg" private alt="…" />
<!-- gate rendering behind your own auth check too -->
{#if data.session}
<Image src="family/2024.jpg" private alt="…" sizes="min(1000px, 100vw)" />
{/if}
Setup / notes:
-
Dev: run
pnpm exec vite-node scripts/build-private-images.tsonce (and after adding/changing images) so the manifest +private-assets/exist. You must be logged in for the gated endpoint to serve the bytes. -
Prod (one-time): add an nginx
internallocation so the bytes are only reachable via the endpoint'sX-Accel-Redirect:location /protected-images/ { internal; alias /var/www/static/private-images/; }scripts/deploy.shrsyncsprivate-assets/→/var/www/static/private-images/. -
These source images are gitignored (private + large). Back them up separately.
-
SVGs are not processed here.