Skip to main content

Overview

Poway Auto uses Jekyll for static site generation with configuration managed through _config.yml, environment-specific JavaScript settings, and build tools.

Jekyll Configuration

_config.yml

The main Jekyll configuration file (_config.yml:1-22):
title: Poway Auto
description: "An online program to find the best and most optimible route for traveling to Qualcomm"
owner_name: Ahaan Vaidyanathan
github_username: Ahaanv19
github_repo: "QAV_Frontend"
baseurl: "/QAV_Frontend"
future: true
remote_theme: jekyll/minima
minima:
  skin: dark
plugins:
  - jekyll-remote-theme
header_pages:
  - /search
  - /about
  - /blogs
  - /Readme4yml

Key Settings

Site Metadata

title: Poway Auto
description: "An online program to find the best and most optimible route for traveling to Qualcomm"
owner_name: Ahaan Vaidyanathan
github_username: Ahaanv19
github_repo: "QAV_Frontend"
  • title - Site name displayed in browser and navigation
  • description - SEO and meta description
  • owner_name - Site owner for footer and attribution
  • github_username / github_repo - Repository information

Base URL

baseurl: "/QAV_Frontend"
Important: The baseurl is used for GitHub Pages deployment. All internal links must use:
<a href="{{site.baseurl}}/page">Link</a>
Or in JavaScript:
import { ... } from '{{site.baseurl}}/assets/js/api/config.js';

Theme Configuration

remote_theme: jekyll/minima
minima:
  skin: dark
Available themes (commented out):
# remote_theme: pages-themes/[email protected]
# remote_theme: pages-themes/[email protected]
# remote_theme: pages-themes/[email protected]
# remote_theme: pages-themes/[email protected]
# remote_theme: pages-themes/[email protected]
To change themes, uncomment desired theme and comment out current theme.

Plugins

plugins:
  - jekyll-remote-theme
Enables remote theme support for GitHub Pages.
header_pages:
  - /search
  - /about
  - /blogs
  - /Readme4yml
Defines pages shown in the main navigation. These are rendered in the base layout (base.html:92-98):
<nav class="hidden md:flex gap-6 text-sm font-medium">
  {% for page in site.header_pages %}
  <a href="{{ page | relative_url }}" class="hover:text-primary transition duration-200">
    {{ page | split: "/" | last | split: "." | first | capitalize }}
  </a>
  {% endfor %}
</nav>

API Configuration

Environment Detection

The API configuration in assets/js/api/config.js automatically detects the environment:
export var pythonURI;
if (location.hostname === "localhost") {
    pythonURI = "http://localhost:8888";
} else if (location.hostname === "127.0.0.1") {
    pythonURI = "http://127.0.0.1:8888";
} else {
    pythonURI = "https://autonomous.stu.nighthawkcodingsociety.com";
}

export var javaURI;
if (location.hostname === "localhost") {
    javaURI = "http://localhost:8888";
} else if (location.hostname === "127.0.0.1") {
    javaURI = "http://127.0.0.1:8888";
} else {
    javaURI = "https://autonomous.stu.nighthawkcodingsociety.com";
}
Environments:
EnvironmentHostnameAPI Base URL
Local (localhost)localhosthttp://localhost:8888
Local (IP)127.0.0.1http://127.0.0.1:8888
Productionahaanv19.github.iohttps://autonomous.stu.nighthawkcodingsociety.com

Changing API Endpoints

To use a different backend: Development:
if (location.hostname === "localhost") {
    pythonURI = "http://localhost:3000";  // Your dev server
}
Production:
else {
    pythonURI = "https://your-api-domain.com";
}

Fetch Configuration

export const fetchOptions = {
    method: 'GET',
    mode: 'cors',
    cache: 'default',
    credentials: 'include',
    headers: {
        'Content-Type': 'application/json',
        'X-Origin': 'client'
    },
};
Options explained:
  • mode: 'cors' - Enable cross-origin requests
  • credentials: 'include' - Send cookies with requests
  • cache: 'default' - Use browser cache when appropriate
  • X-Origin: 'client' - Custom header to identify frontend

Map Configuration

OpenStreetMap Setup

From navigation/findBestRoute/map.js (map.js:6-9):
const map = L.map('map').setView([32.7157, -117.1611], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; OpenStreetMap contributors',
}).addTo(map);
Configuration:
  • Default center: [32.7157, -117.1611] (San Diego area)
  • Default zoom: 12
  • Tile provider: OpenStreetMap (free, no API key required)

Alternative Map Providers

Mapbox:
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
    id: 'mapbox/streets-v11',
    accessToken: 'YOUR_MAPBOX_TOKEN',
    attribution: '&copy; Mapbox'
}).addTo(map);
Google Maps:
L.tileLayer('https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
    attribution: '&copy; Google Maps'
}).addTo(map);

Geolocation

Automatic user location detection (map.js:13-19):
if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(position => {
    const lat = position.coords.latitude;
    const lon = position.coords.longitude;
    map.setView([lat, lon], 13);
  });
}
This centers the map on the user’s current location if permission is granted.

Build Configuration

Makefile Settings

Customize build behavior in the Makefile:
# Configuration variables
PORT ?= 4887
REPO_NAME ?= flocker_frontend
LOG_FILE = /tmp/jekyll$(PORT).log
Change defaults:
# Use different port
PORT ?= 4000

# Update repository name
REPO_NAME ?= QAV_Frontend
Or override at runtime:
make PORT=4200
make REPO_NAME=my_project

Jekyll Server Options

The server command (Makefile:92-94):
bundle exec jekyll serve -H 127.0.0.1 -P $(PORT)
Additional options:
# Enable live reload
bundle exec jekyll serve -H 127.0.0.1 -P 4887 --livereload

# Enable incremental builds
bundle exec jekyll serve -H 127.0.0.1 -P 4887 --incremental

# Show drafts
bundle exec jekyll serve -H 127.0.0.1 -P 4887 --drafts

# Future posts
bundle exec jekyll serve -H 127.0.0.1 -P 4887 --future
Update Makefile to include options:
server: stop convert
	@echo "Starting server..."
	@@nohup bundle exec jekyll serve -H 127.0.0.1 -P $(PORT) --livereload > $(LOG_FILE) 2>&1 & \
		PID=$$!; \
		echo "Server PID: $$PID"

Deployment Configuration

GitHub Pages

GitHub Actions Workflow

The project uses GitHub Actions for deployment (.github/workflows/jekyll-gh-pages.yml):
name: Deploy Jekyll site to Pages

on:
  push:
    branches: ["main"]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.1'
          bundler-cache: true
      
      - name: Setup Pages
        uses: actions/configure-pages@v3
      
      - name: Build with Jekyll
        run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
        env:
          JEKYLL_ENV: production
      
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1

Repository Settings

  1. Enable GitHub Pages:
    • Go to repository Settings > Pages
    • Source: GitHub Actions
    • Branch: main
  2. Set baseurl in _config.yml:
    baseurl: "/QAV_Frontend"  # Your repo name
    
  3. Custom domain (optional):
    url: "https://powayauto.com"
    baseurl: ""
    

Environment Variables

For sensitive configuration, use environment variables: GitHub Secrets:
  1. Go to Settings > Secrets > Actions
  2. Add secrets (e.g., API_KEY, MAP_API_KEY)
  3. Access in workflow:
    env:
      API_KEY: ${{ secrets.API_KEY }}
    
In JavaScript:
// Not recommended - exposes secrets
const API_KEY = 'hardcoded_key';

// Better - backend handles secrets
const response = await fetch(`${pythonURI}/api/routes`, {
    // Backend uses API keys internally
});

Theme Customization

Tailwind Configuration

The base layout includes custom Tailwind config (base.html:12-34):
tailwind.config = {
  darkMode: 'class',
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'ui-sans-serif', 'system-ui'],
      },
      colors: {
        primary: '#4f46e5',
        secondary: '#6366f1',
        accent: '#a78bfa',
        background: '#f9fafb',
        darkbg: '#1f2937',
      },
      boxShadow: {
        soft: '0 2px 25px rgba(0, 0, 0, 0.05)',
      },
    },
  },
};
Customizing colors:
colors: {
  primary: '#FF6B6B',      // Red accent
  secondary: '#4ECDC4',    // Teal
  accent: '#FFE66D',       // Yellow
  background: '#FFFFFF',   // White
  darkbg: '#1A1A2E',      // Dark blue
}

Dark Mode

Dark mode is configured with class-based toggling (base.html:114-128):
const toggleBtn = document.getElementById('theme-toggle');
const html = document.documentElement;

function applyTheme() {
  if (localStorage.getItem('theme') === 'dark') {
    html.classList.add('dark');
    toggleBtn.textContent = '☀️';
  } else {
    html.classList.remove('dark');
    toggleBtn.textContent = '🌙';
  }
}

toggleBtn.addEventListener('click', () => {
  const current = localStorage.getItem('theme') === 'dark';
  localStorage.setItem('theme', current ? 'light' : 'dark');
  applyTheme();
});
Theme persists across sessions via localStorage.

Custom Styles

Add custom CSS in the base layout or create a separate stylesheet: In _layouts/base.html:
<style>
  .custom-class {
    /* Your styles */
  }
</style>
In _sass/custom.scss:
.custom-class {
  background: $primary-color;
  &:hover {
    opacity: 0.8;
  }
}

Development Settings

Hot Reload

The Makefile includes automatic regeneration detection (Makefile:26-38):
@(tail -f $(LOG_FILE) | awk '/Server address: http:\/\/127.0.0.1:$(PORT)\/$(REPO_NAME)\// { serverReady=1 } \
serverReady && /^ *Regenerating:/ { regenerate=1 } \
regenerate { \
    if (/^[[:blank:]]*$$/) { regenerate=0 } \
    else { \
        print; \
        if ($$0 ~ /_notebooks\/.*\.ipynb/) { system("make convert &") } \
    } \
}')
This automatically converts notebooks when they change during development.

Logging

Jekyll output is logged to /tmp/jekyll{PORT}.log:
# View logs
tail -f /tmp/jekyll4887.log

# Check for errors
grep -i error /tmp/jekyll4887.log

Production Optimizations

Minification

Enable in _config.yml:
sass:
  style: compressed

compress_html:
  clippings: all
  comments: all
  endings: all
  startings: []
  blanklines: false
  profile: false

Caching

Service worker for offline support:
// sw.js
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('v1').then((cache) => {
      return cache.addAll([
        '/',
        '/assets/css/style.css',
        '/assets/js/api/config.js',
      ]);
    })
  );
});
Register in base.html:
<script>
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}
</script>

Troubleshooting

Port Already in Use

# Find process using port
lsof -ti :4887

# Kill process
make stop

# Or use different port
make PORT=4888

Build Errors

# Clean and rebuild
make clean
make

# Check dependencies
bundle install
pip install -r requirements.txt

Theme Not Loading

# Clear cache
rm -rf .sass-cache _site

# Rebuild
bundle exec jekyll build

Configuration Checklist

  • Install Ruby and Bundler
  • Install Python dependencies
  • Set PORT in Makefile if needed
  • Start backend server on port 8888
  • Run make to start frontend
  • Access http://127.0.0.1:4887/QAV_Frontend/
  • Verify API endpoints in config.js
  • Test CORS settings
  • Configure authentication
  • Set up credentials handling
  • Set baseurl in _config.yml
  • Enable GitHub Pages in repository settings
  • Configure GitHub Actions workflow
  • Verify build succeeds
  • Test production site
  • Update API endpoints for production
  • Enable CSS/JS minification
  • Configure caching
  • Test on mobile devices
  • Verify HTTPS

Next Steps

Project Structure

Explore the file organization and build system

API Integration

Learn about backend communication patterns

Build docs developers (and LLMs) love