SvelteKit-based personal travel website documenting kick scooter adventures across countries. Static site with Docker deployment.
# Install dependencies
pnpm install
# Start dev server
pnpm dev
# Build for production
pnpm build
# Preview production build
pnpm preview
src/
├── lib/
│ ├── components/ # Reusable Svelte components
│ └── utils/ # Helper functions (imageUtils, etc.)
├── routes/
│ ├── trips/ # Trip-specific routes
│ │ ├── japan-2017/ # 40 days, 1,800km
│ │ ├── japan-2023/ # 3 days, 150km
│ │ └── korea-2025/ # 11 days, 560km
│ └── +page.svelte # Homepage
static/
├── images/ # WebP images organized by trip/day
└── sitemap.xml
scripts/
└── generate-build-info.cjs # Git commit hash for footer
pnpm dev # Development server
pnpm check # Type checking + svelte-check
pnpm format # Prettier formatting
pnpm lint # Prettier check
# Production deployment (requires homelab SSH access)
pnpm prod:deploy # Full deploy: build + rsync + docker restart
src/routes/trips/[trip-name]/day-XX-[slug]/+page.svelte using .github/day-entity-template.md as referencestatic/images/[trip-name]/day-XX/static/sitemap.xmlphoto-XX-[ratio].webp (e.g., photo-01-4x3.webp)-4x3, -3x4, -1x1, -16x9/static/images/[trip]/day-XX/Two patterns supported (see src/lib/utils/imageUtils.ts):
Utility Pattern (Japan 2017):
const rawImages = [{ src: '/path/photo-01-4x3.webp', alt: '...' }];
const images = prepareImagesForPhotoSwipe(rawImages);
Explicit Pattern (Korea 2025):
const images = [{
src: '/path/photo-01-4x3.webp',
alt: '...',
width: 1200,
height: 900,
ratio: '4x3'
}];
Deployment uses rsync to sync build artifacts to server, then restarts Docker container.
pnpm prod:deploy
See package.json scripts for details.
#7EB300#C5007C#636363#7E797C.github/copilot-instructions.md.github/day-entity-template.mdTRIP-DETAILS.md in each trip folderContent © Michael Distel. All rights reserved.