diff --git a/cmd/templ/generatecmd/cmd.go b/cmd/templ/generatecmd/cmd.go index f9b6698e1..3cf3c24c8 100644 --- a/cmd/templ/generatecmd/cmd.go +++ b/cmd/templ/generatecmd/cmd.go @@ -301,10 +301,13 @@ func (cmd *Generate) StartProxy(ctx context.Context) (p *proxy.Handler, err erro if cmd.Args.ProxyPort == 0 { cmd.Args.ProxyPort = 7331 } - p = proxy.New(cmd.Args.ProxyPort, target) + if cmd.Args.ProxyBind == "" { + cmd.Args.ProxyBind = "127.0.0.1" + } + p = proxy.New(cmd.Args.ProxyBind, cmd.Args.ProxyPort, target) go func() { cmd.Log.Info("Proxying", slog.String("from", p.URL), slog.String("to", p.Target.String())) - if err := http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", cmd.Args.ProxyPort), p); err != nil { + if err := http.ListenAndServe(fmt.Sprintf("%s:%d", cmd.Args.ProxyBind, cmd.Args.ProxyPort), p); err != nil { cmd.Log.Error("Proxy failed", slog.Any("error", err)) } }() diff --git a/cmd/templ/generatecmd/main.go b/cmd/templ/generatecmd/main.go index 16e5c4445..64af1b43a 100644 --- a/cmd/templ/generatecmd/main.go +++ b/cmd/templ/generatecmd/main.go @@ -17,6 +17,7 @@ type Arguments struct { Watch bool OpenBrowser bool Command string + ProxyBind string ProxyPort int Proxy string WorkerCount int diff --git a/cmd/templ/generatecmd/proxy/proxy.go b/cmd/templ/generatecmd/proxy/proxy.go index 1a6777620..27667d722 100644 --- a/cmd/templ/generatecmd/proxy/proxy.go +++ b/cmd/templ/generatecmd/proxy/proxy.go @@ -90,7 +90,7 @@ func modifyResponse(r *http.Response) error { return modifier(r) } -func New(port int, target *url.URL) *Handler { +func New(bind string, port int, target *url.URL) *Handler { p := httputil.NewSingleHostReverseProxy(target) p.ErrorLog = log.New(os.Stderr, "Proxy to target error: ", 0) p.Transport = &roundTripper{ @@ -100,7 +100,7 @@ func New(port int, target *url.URL) *Handler { } p.ModifyResponse = modifyResponse return &Handler{ - URL: fmt.Sprintf("http://127.0.0.1:%d", port), + URL: fmt.Sprintf("http://%s:%d", bind, port), Target: target, p: p, sse: sse.New(), diff --git a/cmd/templ/generatecmd/testwatch/generate_test.go b/cmd/templ/generatecmd/testwatch/generate_test.go index a289fec9d..8c34a3e04 100644 --- a/cmd/templ/generatecmd/testwatch/generate_test.go +++ b/cmd/templ/generatecmd/testwatch/generate_test.go @@ -307,14 +307,15 @@ loop: } } -func NewTestArgs(modRoot, appDir string, appPort int, proxyPort int) TestArgs { +func NewTestArgs(modRoot, appDir string, appPort int, proxyBind string, proxyPort int) TestArgs { return TestArgs{ ModRoot: modRoot, AppDir: appDir, AppPort: appPort, AppURL: fmt.Sprintf("http://localhost:%d", appPort), + ProxyBind: proxyBind, ProxyPort: proxyPort, - ProxyURL: fmt.Sprintf("http://localhost:%d", proxyPort), + ProxyURL: fmt.Sprintf("http://%s:%d", proxyBind, proxyPort), } } @@ -323,6 +324,7 @@ type TestArgs struct { AppDir string AppPort int AppURL string + ProxyBind string ProxyPort int ProxyURL string } @@ -349,8 +351,9 @@ func Setup(gzipEncoding bool) (args TestArgs, teardown func(t *testing.T), err e if err != nil { return args, teardown, fmt.Errorf("failed to get available port: %v", err) } + proxyBind := "localhost" - args = NewTestArgs(moduleRoot, appDir, appPort, proxyPort) + args = NewTestArgs(moduleRoot, appDir, appPort, proxyBind, proxyPort) ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup @@ -369,6 +372,7 @@ func Setup(gzipEncoding bool) (args TestArgs, teardown func(t *testing.T), err e Path: appDir, Watch: true, Command: command, + ProxyBind: proxyBind, ProxyPort: proxyPort, Proxy: args.AppURL, IncludeVersion: false, diff --git a/cmd/templ/main.go b/cmd/templ/main.go index f5ac379a2..8b0848ba3 100644 --- a/cmd/templ/main.go +++ b/cmd/templ/main.go @@ -86,6 +86,8 @@ Args: Set the URL to proxy after generating code and executing the command. -proxyport The port the proxy will listen on. (default 7331) + -proxybind + The address the proxy will listen on. (default 127.0.0.1) -w Number of workers to use when generating code. (default runtime.NumCPUs) -pprof @@ -127,6 +129,7 @@ func generateCmd(w io.Writer, args []string) (code int) { cmdFlag := cmd.String("cmd", "", "") proxyFlag := cmd.String("proxy", "", "") proxyPortFlag := cmd.Int("proxyport", 7331, "") + proxyBindFlag := cmd.String("proxybind", "127.0.0.1", "") workerCountFlag := cmd.Int("w", runtime.NumCPU(), "") pprofPortFlag := cmd.Int("pprof", 0, "") keepOrphanedFilesFlag := cmd.Bool("keep-orphaned-files", false, "") @@ -160,6 +163,7 @@ func generateCmd(w io.Writer, args []string) (code int) { Command: *cmdFlag, Proxy: *proxyFlag, ProxyPort: *proxyPortFlag, + ProxyBind: *proxyBindFlag, WorkerCount: *workerCountFlag, GenerateSourceMapVisualisations: *sourceMapVisualisationsFlag, IncludeVersion: *includeVersionFlag, diff --git a/docs/docs/09-commands-and-tools/01-cli.md b/docs/docs/09-commands-and-tools/01-cli.md index a221f7c07..67cdaae0f 100644 --- a/docs/docs/09-commands-and-tools/01-cli.md +++ b/docs/docs/09-commands-and-tools/01-cli.md @@ -44,6 +44,8 @@ Args: Set the URL to proxy after generating code and executing the command. -proxyport The port the proxy will listen on. (default 7331) + -proxybind + The address the proxy will listen on. (default 127.0.0.1) -w Number of workers to use when generating code. (default runtime.NumCPUs) -pprof diff --git a/docs/docs/09-commands-and-tools/03-hot-reload.md b/docs/docs/09-commands-and-tools/03-hot-reload.md index 18836f3c6..ff0171e54 100644 --- a/docs/docs/09-commands-and-tools/03-hot-reload.md +++ b/docs/docs/09-commands-and-tools/03-hot-reload.md @@ -23,6 +23,8 @@ Finally, to trigger your web browser to reload automatically (without pressing F The `--proxy` argument starts a HTTP proxy which proxies requests to your app. For example, if your app runs on port 8080, you would use `--proxy="http://localhost:8080"`. The proxy inserts client-side JavaScript before the `` tag that will cause the browser to reload the window when the app is restarted instead of you having to reload the page manually. Note that the html being served by the webserver MUST have a `` tag, otherwise there will be no javascript injection thus making the browser not reload automatically. +By default, the proxy binds to `127.0.0.1`. You can use `--proxybind` to bind to another address, e.g., `--proxybind="0.0.0.0"`. + Altogether, to setup hot reload on an app that listens on port 8080, run the following. ```