HighlineTales is a hiking-themed web application built as part of my JavaScript learning journey, inspired by me and my wife's vacation to Glacier National Park. It combines activity guides, blog posts sharing our ‘trailing’ stories, and planning tools centered on Glacier’s iconic Highline Trail.
HighlineTales is a React + Vite application that shares trail information, hiking tips, and personal stories for Glacier National Park. It also includes helpful UI like info cards, visitor analytics (via Supabase), and a clean CSS architecture combining global tokens and CSS Modules. Content is dynamically served via Vercel Serverless Functions from a Vercel Postgres database.
- Dynamic trail and activity pages fetched from Vercel Postgres
- Blog with individual post-pages powered by serverless API endpoints
- Hiking checklist/essentials page
- Visitor counter backed by Supabase (RPC function increment_page_view)
- Responsive layout with CSS Modules and global typography/utilities
- Robust routing with error boundaries
- Frontend: React 19, React Router 7 (react-router-dom)
- Backend/API: Vercel Serverless Functions (Node.js)
- Database: Vercel Postgres (Powered by Neon)
- Bundler: Vite 7 with @vitejs/plugin-react, alias @ → src
- Styles: Global CSS (globals.css, typography.css, prose.css, utilities.css) + CSS Modules
- Analytics: Supabase JS v2 client for simple analytics/features
- Testing: Vitest + Testing Library (jsdom environment)
- Linting: ESLint 9 (react-hooks, react-refresh) configured via eslint.config.js
flowchart TD
subgraph Client
A[index.html] --> B(src/main.jsx)
B --> C(App.jsx)
C --> F(AppRouter)
end
subgraph Frontend Services
F --> G[HomePage]
F --> H[ActivityPage]
F --> K[BlogPage]
G & H & K --> M[activitiesService]
G & H & K --> N[blogService]
end
subgraph Vercel API
M --> O[api/activities.js]
N --> P[api/blogs.js]
end
subgraph Database
O & P --> Q[(Vercel Postgres)]
S[Supabase] -. analytics .-> F
end
Note:
activitiesServiceandblogServicefetch data from the/apiserverless endpoints.- Content is managed in Vercel Postgres; for schema and management.
├─ api/ # Vercel Serverless Functions
├─ docs/ # Technical documentation (e.g., DATABASE.md)
├─ index.html
├─ vite.config.js
├─ eslint.config.js
├─ jsconfig.json # @/* → src/* alias for editor/tooling
├─ package.json
├─ package-lock.json
├─ README.md
├─ public/ # Static assets served as-is
├─ src/
│ ├─ AppRouter.jsx # Central routes + loaders
│ ├─ services/ # Data fetching logic
│ ├─ components/ # Reusable UI components
│ ├─ pages/ # Page-level components
│ ├─ data/ # Static config/fallback data
│ └─ utils/ # Utility functions & parsers
Tip: Import using the @ alias, e.g., import App from '@/App.jsx'.
- / → HomePage
- /activities → ActivityPage
- /activities/:slug → ActivityPost (loader: getActivityBySlug, 404 → ActivityNotFound)
- /hiking-checklist → EssentialsPage
- /blog → BlogPage
- /blog/:slug → BlogPost (loader: getPostBySlug, 404 → BlogPostNotFound)
- Node.js 18+ (LTS recommended) and npm
- Optional: Supabase project (for VisitorCounter)
-
Clone and install
- git clone https://github.com/yourusername/highline-tales.git
- cd highline-tales
- npm install
-
Environment variables
- Create a
.env.localfile in the repository root by pulling from Vercel (requires Vercel CLI):vercel linkvercel env pull .env.local
- This file will contain your
POSTGRES_URLand other database secrets. - Also ensure your Supabase variables are set if using analytics:
VITE_PUBLIC_SUPABASE_URL=your_supabase_urlVITE_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
- Create a
-
Development server
vercel dev(Recommended - runs frontend + API)npm run dev(Frontend only - API calls will fail)- Open http://localhost:3000
- npm run dev → Start Vite dev server (with --host)
- npm run build → Production build to dist/
- npm run preview → Serve the production build locally
- npm run clean → Remove dist/ (safe helper)
- npm run lint → Lint JS/JSX with ESLint 9 (no warnings allowed)
- npm test → Run Vitest in CI mode
- npm run test:watch → Run Vitest in watch mode
- Global CSS provides design tokens and base typography: globals.css, typography.css
- prose.css styles rich text for blog posts
- CSS Modules encapsulate component styles throughout components and pages
- Utilities: utilities.css offers a small set of global helpers (gap, visibility, etc.). A future enhancement could split utilities into utilities.module.css and surfaces.module.css for better encapsulation.
- The Supabase client lives at src/services/supabase/supabase.js and reads env vars VITE_PUBLIC_SUPABASE_URL and VITE_PUBLIC_SUPABASE_ANON_KEY
- VisitorCounter uses a Supabase RPC named increment_page_view and basic reads for totals
- Ensure Row Level Security policies and RPC exist in your Supabase project if you enable this feature
- Vitest is configured with jsdom and React Testing Library
- Setup file: src/test/setupTests.js (adds jest-dom matchers)
- Run tests: npm test or npm run test:watch
- ESLint 9 with react-hooks and react-refresh plugins
- Config: eslint.config.js (dist/ ignored; JSX enabled)
- Run lint: npm run lint
- Typography and color tokens are centralized for consistency
- Error boundaries prevent full-app crashes
- Where possible, provide descriptive alt text; decorative images should use empty alt=""
- Consider Lighthouse and Axe DevTools checks during development; maintain an internal checklist in issues/PR templates rather than separate docs/ files.
-
Production Site: https://www.highlinetales.com
-
Hosting: Deployed on Vercel with continuous deployment from the main branch
-
Domain: Registered with Hostinger with DNS configured to use Vercel nameservers
-
Build Process:
- Vercel automatically builds the project using
npm run buildon each push to the main branch - The build creates optimized static files in the directory
dist/ - Vercel handles SPA routing configuration automatically, redirecting all routes to
index.html
- Vercel automatically builds the project using
-
Environment Variables:
- Supabase connection details are configured in the Vercel project settings
- Environment variables for production are managed through the Vercel dashboard
-
Deployment Options:
- Manual Deployment:
npm run buildfollowed by uploading to Verceldist/ - Preview Locally:
npm run previewto test the production build before deployment - Preview Deployments: Each pull request gets a unique preview URL through Vercel's PR integration
- Manual Deployment:
For local development, you can still use npm run dev to start the Vite development server and preview at http://localhost:5173.
This project is licensed under the MIT License.