Smokesignal Frontend#
This directory contains the frontend JavaScript and CSS source code for Smokesignal.
Prerequisites#
- Node.js 20+ (LTS recommended)
- npm 10+
Setup#
Install dependencies:
npm install
Development#
Build frontend assets (outputs to ../static/js/bundle.js and ../static/css/bundle.css):
npm run build
Watch mode for development (rebuilds on file changes):
npm run dev
Code Quality#
Format code:
npm run format
Check formatting without modifying:
npm run format:check
Lint code:
npm run lint
Fix lint issues:
npm run lint:fix
Type check:
npm run typecheck
Run all checks:
npm run check
Project Structure#
src-js/
├── src/
│ ├── main.ts # Entry point
│ ├── types.ts # Shared TypeScript types
│ ├── core/ # Core utilities
│ ├── components/ # Reusable UI components
│ │ └── navigation.ts # Navbar toggle
│ └── features/ # Feature-specific code
│ ├── maps/
│ │ ├── event-map.ts # Event page map
│ │ ├── globe-map.ts # Homepage globe
│ │ └── location-heatmap.ts # Location page heatmap
│ ├── events/
│ │ ├── create.ts # Event form Alpine.js component
│ │ └── quick-create.ts # Quick event form
│ └── lfg/
│ └── form.ts # LFG form Alpine.js component
├── styles/
│ ├── main.css # CSS entry point
│ ├── base/ # Variables, utilities
│ ├── components/ # Component styles
│ └── features/ # Feature styles
├── package.json
├── tsconfig.json
├── vite.config.ts
└── biome.json
Build Output#
The build produces:
../static/js/bundle.js- JavaScript bundle../static/css/bundle.css- CSS bundle
These are referenced in templates with cache-busting query parameters using ?rev={{ build_rev }}.
Integration with Rust#
The BUILD_REV environment variable is generated at Rust compile time in build.rs and made available to templates via templates.rs. This ensures browser caches are invalidated on each deploy.
Alpine.js Components#
Some features use Alpine.js components that are exposed on the global SmokesignalApp namespace:
SmokesignalApp.eventForm()- Event creation/editing formSmokesignalApp.lfgForm()- LFG (Looking For Group) form
Templates can use these directly:
<div x-data="SmokesignalApp.eventForm()">
<!-- form content -->
</div>
Map Features#
Map features auto-initialize based on DOM element presence:
#event-mapwithdata-geo-locations- Event page map#globe-map- Homepage globe (fetches data from API)#location-heatmapwithdata-geo-buckets- Location page heatmap
Vendor libraries (Leaflet, MapLibre, H3) are loaded separately in templates.