Files
MyClub/DOCS/UMAMI_SETUP_WITH_CLUB_NAME.md
Tomáš Dvořák 12cba639b9 upload
2025-10-16 13:32:05 +02:00

5.9 KiB

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:

// 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

# 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

# Start Cloudflare tunnel
cloudflared tunnel --url http://localhost:8080

# Or with named tunnel:
cloudflared tunnel run <tunnel-name>

# 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

# 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:

# 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

# 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: <tunnel-id>
credentials-file: C:\Users\<you>\.cloudflared\<tunnel-id>.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: <tunnel-id>.cfargotunnel.com

# Run tunnel
cloudflared tunnel run my-fotbal-club

Testing the Tunnel

# 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: <auto-generated-uuid>

Perfect! 🎉