# Umami Setup with Actual Club Name and Domain ## Changes Made ### Problem Solved Previously, Umami created websites with: - **Name:** "Fotbal Club (Dev)" (hardcoded) - **Domain:** "localhost" (hardcoded) Now it uses: - **Name:** Actual club name from setup form - **Domain:** Auto-detected from Host header (works with Cloudflare Tunnel!) ### How It Works with Cloudflare Tunnel When you route through Cloudflare Tunnel to a club's domain: ``` User → fotbalklub.cz → Cloudflare Tunnel → Your Local Backend ``` The HTTP request will have: ``` Host: fotbalklub.cz ``` The backend reads this header and creates the Umami website with the correct domain! ### Implementation Details **Frontend (`SetupPage.tsx`):** - Calls `POST /api/v1/umami/initialize-setup` during step 3 - Sends: `{ "name": "SK Slavia Litomyšl" }` (from club name field) - Domain is auto-detected by backend **Backend (`umami_controller.go`):** - New endpoint: `POST /api/v1/umami/initialize-setup` - No authentication required (public, called during setup) - Extracts domain from `c.Request.Host` header - Removes port if present (`:8080` → ``) - Calls Umami API to create website - Stores website ID in memory **Backend Flow:** ```go // 1. Get club name from request name := payload.Name // "SK Slavia Litomyšl" // 2. Auto-detect domain from Host header domain := c.Request.Host // "fotbalklub.cz" or "localhost:8080" if i := strings.Index(domain, ":"); i >= 0 { domain = domain[:i] // Remove port } // 3. Create Umami website websiteID := umamiService.EnsureWebsite(name, domain) ``` ## Testing ### 1. Local Development Test ```bash # Restart backend go run main.go # Open setup page # Fill in club name: "Test Club" # Complete setup # Backend will create: # Name: "Test Club" # Domain: "localhost" ``` ### 2. Cloudflare Tunnel Test ```bash # Start Cloudflare tunnel cloudflared tunnel --url http://localhost:8080 # Or with named tunnel: cloudflared tunnel run # Access via club domain (e.g., fotbalklub.cz) # Fill in club name: "SK Slavia Litomyšl" # Complete setup # Backend will create: # Name: "SK Slavia Litomyšl" # Domain: "fotbalklub.cz" ``` ### 3. Verify in Umami Dashboard 1. Login to https://umami.tdvorak.dev 2. Check websites list 3. You should see the club's actual name and domain ### 4. Test via API ```powershell # After setup, check the website was created $body = @{ username = "admin" password = "eevRQ6h3G@!c#y4A1T" } | ConvertTo-Json $response = Invoke-RestMethod -Uri "https://umami.tdvorak.dev/api/auth/login" ` -Method Post ` -ContentType "application/json" ` -Body $body $token = $response.token $headers = @{ Authorization = "Bearer $token" } $websites = Invoke-RestMethod -Uri "https://umami.tdvorak.dev/api/websites" ` -Headers $headers # Should show the new website with club name and domain $websites.data | Format-Table name, domain, id ``` ## Environment Configuration Your `.env` file should have: ```env # Umami Analytics UMAMI_URL=https://umami.tdvorak.dev UMAMI_USERNAME=admin UMAMI_PASSWORD=eevRQ6h3G@!c#y4A1T # Leave empty - will be auto-created during setup UMAMI_WEBSITE_ID= ``` **Important:** No inline comments on `UMAMI_WEBSITE_ID` line! ## Cloudflare Tunnel Setup ### Quick Start ```bash # Install cloudflared # Windows: Download from https://github.com/cloudflare/cloudflared/releases # Login to Cloudflare cloudflared tunnel login # Create tunnel cloudflared tunnel create my-fotbal-club # Configure tunnel (create config.yml): tunnel: credentials-file: C:\Users\\.cloudflared\.json ingress: - hostname: fotbalklub.cz service: http://localhost:8080 - service: http_status:404 # Create DNS record in Cloudflare dashboard: # Type: CNAME # Name: @ (or subdomain) # Target: .cfargotunnel.com # Run tunnel cloudflared tunnel run my-fotbal-club ``` ### Testing the Tunnel ```bash # Check if tunnel is working curl https://fotbalklub.cz/api/v1/health # Should return 200 OK ``` ## Files Modified 1. **Frontend:** - `frontend/src/pages/SetupPage.tsx` - Changed from `GET /umami/config` to `POST /umami/initialize-setup` - Passes club name: `{ name: clubName }` - Domain auto-detected by backend 2. **Backend:** - `internal/controllers/umami_controller.go` - Added `InitializeUmamiSetup()` function - Auto-detects domain from `c.Request.Host` - Removes port number - Creates website with actual name and domain - `internal/routes/routes.go` - Added route: `POST /api/v1/umami/initialize-setup` (public, no auth) ## Benefits 1. ✅ **Correct club names** in Umami dashboard 2. ✅ **Correct domains** (not "localhost" in production) 3. ✅ **Works with Cloudflare Tunnel** automatically 4. ✅ **No manual configuration** needed 5. ✅ **Clean Umami dashboard** with proper website names ## Troubleshooting ### Issue: Still showing "localhost" **Cause:** Accessing via `http://localhost:8080` directly **Fix:** Access via Cloudflare Tunnel URL or set proper Host header ### Issue: Website name still "Fotbal Club (Dev)" **Cause:** Old website exists from previous setup **Solution:** 1. Login to Umami dashboard 2. Delete the old "Fotbal Club (Dev)" website 3. Clear `.env`: `UMAMI_WEBSITE_ID=` 4. Restart backend 5. Run setup again ### Issue: Domain includes port (e.g., "fotbalklub.cz:8080") **Cause:** This shouldn't happen - the code strips ports **Fix:** Check the backend logs for the actual domain being used ## Production Deployment Checklist - [ ] Set up Cloudflare Tunnel - [ ] Point club's domain to tunnel - [ ] Verify `.env` has `UMAMI_WEBSITE_ID=` (empty) - [ ] Clear any old Umami websites in dashboard - [ ] Run initial setup via club's domain - [ ] Verify in Umami dashboard: correct name and domain - [ ] Test tracking: visit pages and check Umami stats ## Expected Result After setup via `https://fotbalklub.cz`, Umami dashboard shows: ``` Name: SK Slavia Litomyšl Domain: fotbalklub.cz ID: ``` Perfect! 🎉