feat: make invite link base URL configurable via APP_URL

Load environment variables from .env file using godotenv.
Defaults to https://demo.adriatica.io if APP_URL is not set.
This commit is contained in:
Ryan Hamamura
2026-02-04 07:02:52 -10:00
parent 20ed4807d9
commit 7faf94fa6d
7 changed files with 23 additions and 4 deletions

5
.env.example Normal file
View File

@@ -0,0 +1,5 @@
# Application URL for invite links (defaults to https://demo.adriatica.io)
# APP_URL=http://localhost:7331
# Server port (defaults to 7331)
# PORT=7331

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
c4 c4
c4.db c4.db
data/ data/
.env
# Deploy artifacts # Deploy artifacts
c4-deploy-*.tar.gz c4-deploy-*.tar.gz

3
go.mod
View File

@@ -4,10 +4,10 @@ go 1.25.4
require ( require (
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
github.com/pressly/goose/v3 v3.26.0 github.com/pressly/goose/v3 v3.26.0
github.com/ryanhamamura/via v0.4.0 github.com/ryanhamamura/via v0.4.0
golang.org/x/crypto v0.47.0 golang.org/x/crypto v0.47.0
maragu.dev/gomponents v1.2.0
modernc.org/sqlite v1.44.0 modernc.org/sqlite v1.44.0
) )
@@ -43,6 +43,7 @@ require (
golang.org/x/sync v0.18.0 // indirect golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.40.0 // indirect golang.org/x/sys v0.40.0 // indirect
golang.org/x/time v0.14.0 // indirect golang.org/x/time v0.14.0 // indirect
maragu.dev/gomponents v1.2.0 // indirect
modernc.org/libc v1.67.4 // indirect modernc.org/libc v1.67.4 // indirect
modernc.org/mathutil v1.7.1 // indirect modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect modernc.org/memory v1.11.0 // indirect

2
go.sum
View File

@@ -33,6 +33,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hookenz/gotailwind/v4 v4.1.18 h1:1h3XwTVx1dEBm6A0bcosAplNCde+DCmVJG0arLy5fBE= github.com/hookenz/gotailwind/v4 v4.1.18 h1:1h3XwTVx1dEBm6A0bcosAplNCde+DCmVJG0arLy5fBE=
github.com/hookenz/gotailwind/v4 v4.1.18/go.mod h1:IfiJtdp8ExV9HV2XUiVjRBvB3QewVXVKWoAGEcpjfNE= github.com/hookenz/gotailwind/v4 v4.1.18/go.mod h1:IfiJtdp8ExV9HV2XUiVjRBvB3QewVXVKWoAGEcpjfNE=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=

View File

@@ -9,6 +9,7 @@ import (
"os" "os"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/joho/godotenv"
"github.com/ryanhamamura/c4/auth" "github.com/ryanhamamura/c4/auth"
"github.com/ryanhamamura/c4/db" "github.com/ryanhamamura/c4/db"
@@ -46,6 +47,8 @@ func port() string {
} }
func main() { func main() {
_ = godotenv.Load()
if err := db.Init("c4.db"); err != nil { if err := db.Init("c4.db"); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@@ -130,7 +130,7 @@ func SnakePlayerList(sg *snake.SnakeGame, mySlot int) h.H {
} }
func SnakeInviteLink(gameID string) h.H { func SnakeInviteLink(gameID string) h.H {
fullURL := baseURL + "/snake/" + gameID fullURL := getBaseURL() + "/snake/" + gameID
return h.Div(h.Class("mt-4 text-center"), return h.Div(h.Class("mt-4 text-center"),
h.P(h.Text("Share this link to invite players:")), h.P(h.Text("Share this link to invite players:")),
h.Div(h.Class("bg-base-200 p-4 rounded-lg font-mono break-all my-2"), h.Div(h.Class("bg-base-200 p-4 rounded-lg font-mono break-all my-2"),

View File

@@ -1,6 +1,8 @@
package ui package ui
import ( import (
"os"
"github.com/ryanhamamura/c4/game" "github.com/ryanhamamura/c4/game"
"github.com/ryanhamamura/via/h" "github.com/ryanhamamura/via/h"
) )
@@ -115,10 +117,15 @@ func PlayerInfo(g *game.Game, myColor int) h.H {
) )
} }
const baseURL = "https://demo.adriatica.io" func getBaseURL() string {
if url := os.Getenv("APP_URL"); url != "" {
return url
}
return "https://demo.adriatica.io"
}
func InviteLink(gameID string) h.H { func InviteLink(gameID string) h.H {
fullURL := baseURL + "/game/" + gameID fullURL := getBaseURL() + "/game/" + gameID
return h.Div(h.Class("mt-4 text-center"), return h.Div(h.Class("mt-4 text-center"),
h.P(h.Text("Share this link with your opponent:")), h.P(h.Text("Share this link with your opponent:")),
h.Div(h.Class("bg-base-200 p-4 rounded-lg font-mono break-all my-2"), h.Div(h.Class("bg-base-200 p-4 rounded-lg font-mono break-all my-2"),