Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fully integration of Templ live reload with Air #369

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

leakedmemory
Copy link
Contributor

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

Feature

Templ live reloading fully integrated with Air and TailwindCSS.

Description of Changes:

This fully integrates Templ live reload with Air. Now it's not necessary to manually reload the page after a change, rebuilds and reloads faster, and also integrates with TailwindCSS live reload.

Solves #368.

Checklist

Question

Do I need to use make deploy on the docs?

@Ujstor
Copy link
Collaborator

Ujstor commented Jan 26, 2025

I tried testing your implementation. It seems that live reload is not working. I created a project (go-blueprint create --name air1 --framework chi --driver postgres --advanced --feature htmx --git commit), ran make watch, and changed the submit button name in hello.templ. After saving, the change is not visible - I still need to manually reload the page.

Can you check if you have the same behavior or if I am doing something wrong?

Let me know if you need any additional logs from me.

make watch
make[1]: Entering directory '/home/ujstor/code/blueprint-version-test/air1'

  __    _   ___
 / /\  | | | |_)
/_/--\ |_| |_| \_ v1.51.0, built with Go go1.22.0

watching .
watching cmd
watching cmd/api
watching cmd/web
watching cmd/web/assets
watching cmd/web/assets/js
watching internal
watching internal/database
watching internal/server
!exclude tmp
building...
(!) templ version check: generator v0.2.778 is older than templ version v0.3.819 found in go.mod file, consider upgrading templ CLI
(✓) Starting post-generation handler
(✓) Walking directory [ path=/home/ujstor/code/blueprint-version-test/air1 devMode=true ]
(✓) Starting event handler
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/base_templ.go ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello_templ.go ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/base.templ ]
(✓) Watching files
(✓) Waiting for context to be cancelled to stop watching files
(✓) Generated code [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/base.templ in=737.064µs ]
(✓) Generated code [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ in=773.326µs ]
(✓) First post-generation event received, starting proxy
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello_templ.go ]
(✓) Not opening browser
(✓) Sending reload event
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello_templ.txt ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/base_templ.txt ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/base_templ.go ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/base_templ.txt ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello_templ.txt ]
(✓) Proxying [ from=http://127.0.0.1:8000 to=http://localhost:8080 ]
running...
(✓) Sending reload event
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Generated code [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ in=1.228012ms ]
cmd/web/hello.templ has changed
building...
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Skipping file because it wasn't updated [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Skipping file because it wasn't updated [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
(✓) Skipping file because it wasn't updated [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello.templ ]
running...
(✓) Sending reload event
(✓) Processing file [ file=/home/ujstor/code/blueprint-version-test/air1/cmd/web/hello_templ.txt ]
(✓) Sending reload event

@leakedmemory
Copy link
Contributor Author

Just ran the command and worked just fine to me. Maybe it's the version of something? As you can see in the log, I'm using Air 1.61.1, Templ 0.3.819, and Go 1.23.2, while you're using Air 1.51.0, Templ 0.2.788, and Go 1.22.0.

Your log also has this warning line: (!) templ version check: generator v0.2.778 is older than templ version v0.3.819 found in go.mod file, consider upgrading templ CLI

$ make watch
make[1]: Entering directory '/home/leaked/dev/oss/air1'

  __    _   ___
 / /\  | | | |_)
/_/--\ |_| |_| \_ v1.61.1, built with Go go1.23.2

mkdir /home/leaked/dev/oss/air1/tmp
watching .
watching cmd
watching cmd/api
watching cmd/web
watching cmd/web/assets
watching cmd/web/assets/js
watching internal
watching internal/database
watching internal/server
!exclude tmp
building...
(✓) Starting post-generation handler
(✓) Starting event handler
(✓) Walking directory [ path=/home/leaked/dev/oss/air1 devMode=true ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/base.templ ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/api/main.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/efs.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/internal/database/database.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/internal/database/database_test.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/internal/server/routes.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/internal/server/routes_test.go ]
(✓) Watching files
(✓) Processing file [ file=/home/leaked/dev/oss/air1/internal/server/server.go ]
(✓) Waiting for context to be cancelled to stop watching files
(✓) Generated code [ file=/home/leaked/dev/oss/air1/cmd/web/base.templ in=1.090395ms ]
(✓) Generated code [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ in=1.336003ms ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/base_templ.txt ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/base_templ.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/base_templ.txt ]
(✓) First post-generation event received, starting proxy
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello_templ.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello_templ.txt ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello_templ.txt ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello_templ.go ]
(✓) Not opening browser
(✓) Sending reload event
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/base_templ.go ]
(✓) Proxying [ from=http://127.0.0.1:8000 to=http://localhost:8080 ]
cmd/web/base_templ.go has changed
running...
(✓) No content encoding header found
2025/01/26 14:59:26 "GET http://localhost:8000/web HTTP/1.1" from [::1]:51082 - 200 480B in 55.434µs
(✓) Reload script inserted
2025/01/26 14:59:26 "GET http://localhost:8000/assets/css/output.css HTTP/1.1" from [::1]:51082 - 404 19B in 28.985µs
(✓) Skipping response modification because content type is not text/html [ content-type=text/plain; charset=utf-8 ]
2025/01/26 14:59:26 "GET http://localhost:8000/assets/js/htmx.min.js HTTP/1.1" from [::1]:51082 - 200 83027B in 2.348891ms
(✓) Skipping response modification because content type is not text/html [ content-type=text/javascript; charset=utf-8 ]
2025/01/26 14:59:26 "GET http://localhost:8000/assets/css/output.css HTTP/1.1" from [::1]:51082 - 404 19B in 16.748µs
(✓) Skipping response modification because content type is not text/html [ content-type=text/plain; charset=utf-8 ]
2025/01/26 14:59:26 "GET http://localhost:8000/favicon.ico HTTP/1.1" from [::1]:51082 - 404 19B in 18.886µs
(✓) Skipping response modification because content type is not text/html [ content-type=text/plain; charset=utf-8 ]
 (✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
cmd/web/hello.templ has changed
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
building...
(✓) Skipping file because it wasn't updated [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
(✓) Skipping file because it wasn't updated [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
(✓) Generated code [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ in=3.619289ms ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
(✓) Skipping file because it wasn't updated [ file=/home/leaked/dev/oss/air1/cmd/web/hello.templ ]
(✓) Sending reload event
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello_templ.go ]
(✓) Processing file [ file=/home/leaked/dev/oss/air1/cmd/web/hello_templ.txt ]
running...
2025/01/26 14:59:40 "GET http://localhost:8000/web HTTP/1.1" from [::1]:43214 - 200 483B in 72.461µs
(✓) No content encoding header found
(✓) Reload script inserted
2025/01/26 14:59:40 "GET http://localhost:8000/assets/css/output.css HTTP/1.1" from [::1]:43214 - 404 19B in 53.294µs
(✓) Skipping response modification because content type is not text/html [ content-type=text/plain; charset=utf-8 ]
(✓) Skipping response modification because content type is not text/html [ content-type=text/javascript; charset=utf-8 ]
2025/01/26 14:59:40 "GET http://localhost:8000/assets/js/htmx.min.js HTTP/1.1" from [::1]:43214 - 200 83027B in 2.94132ms

@leakedmemory
Copy link
Contributor Author

leakedmemory commented Jan 26, 2025

Also, make sure to use the proxy port, instead of the one defined in the .env file, since the default port will not automatically reload. The default proxy port is 8000, as I've put in the documentation, and can be found in the first lines of Makefile (PROXY_PORT), in case you need to change it.

@Ujstor
Copy link
Collaborator

Ujstor commented Jan 26, 2025

Update fixed the issue. Could you please update the documentation to make the usage clearer? Add an explicit example showing that /web needs to be accessed through the proxy port (localhost:8000/web), not the port defined in .env. I saw this part in the docs, but it should be clearer as it can be confusing for first-time users.

Also, please pay attention to PR #372 - rebase when is merged. There was an issue with the new Tailwind release

@Ujstor
Copy link
Collaborator

Ujstor commented Jan 26, 2025

You can also update the Air-dedicated documentation section in addition to the Makefile

https://docs.go-blueprint.dev/creating-project/air/
https://github.com/Melkeydev/go-blueprint/blob/main/docs/docs/creating-project/air.md

The docs are automatically built and deployed on merge. If this addresses your question about documentation

@leakedmemory
Copy link
Contributor Author

Sure. My bad.

@Ujstor
Copy link
Collaborator

Ujstor commented Jan 26, 2025

On first run, when Tailwind is used, output.css is created but styles are not applied. I need to change styling in code or rerun make watch. You are running all 3 targets in parallel - could this be the reason?

watch:
	@$(MAKE) -j3 watch/tailwind watch/templ watch/air

Can you verify this behavior? I'm using the latest fixed version for the Tailwind download

tailwind-install:
	@if [ ! -f tailwindcss ]; then curl -sL https://github.com/tailwindlabs/tailwindcss/releases/download/v3.4.10/tailwindcss-linux-x64 -o tailwindcss; fi
	@chmod +x tailwindcss

@leakedmemory
Copy link
Contributor Author

Yeah, this happens to me too, but I don't know the reason to be honest. This is how it's implemented in the Templ's documentation. One thing for sure is that they have to be in parallel though.

Building before the watch solves it, but I don't really like it, since it only needs the build for the first run after creation:

watch:
	@./tailwindcss -i cmd/web/styles/input.css -o cmd/web/assets/css/output.css
	@$(MAKE) -j3 watch/tailwind watch/templ watch/air

After creating, watching, stopping, and watching again also loads the page with the styles.

I tried changing the order of the watch to put Templ before Tailwind, but this completely stops Tailwind from generating the output file.

Maybe creating the project with the output.css already filled? If this is a valid option.

@arafays
Copy link
Contributor

arafays commented Jan 29, 2025

I tried it too with go-blueprint create --name air1 --framework chi --driver postgres --advanced --feature htmx --git skip

(✓) Sending reload event
(✓) Proxying [ from=http://127.0.0.1:8000 to=http://localhost:8080 ]

This line was confusing In the air logs I was confused why wasnt it reloading but after reading the comment I was checking port 8080 but was supposed to goto 8000

Also about the live reload of tailwindcss.
What i think the problem is air is not watching css files also on first run the tailwind cli is being downloaded and then it generates the output but our assets folder is excluded in air.toml i tried removing the assets folder from excludes but still the page didnt reload I even tried just removing the exclude_dir from air.toml it still didnt work.

@Ujstor
Copy link
Collaborator

Ujstor commented Jan 29, 2025

It is a nice feature to have, but I am a little bit skeptical after I saw the implementation. We are adding a layer of complexity that will confuse a lot of people, and many issue tickets will be opened.

Currently, merging is on stop because of a refactor and frontend flag implementation.
I would like to see this merged, but only if there is a better solution for live reload. The proxy is a little bit on the edge.

@leakedmemory
Copy link
Contributor Author

leakedmemory commented Jan 29, 2025

This line was confusing In the air logs I was confused why wasnt it reloading but after reading the comment I was checking port 8080 but was supposed to goto 8000

It's counterintuitive, but this is the correct terminology in proxies, as far as I know, since it's the proxy's perspective. Your request FROM port 8000 is redirected TO port 8080. And the line you talked about is a Templ's log, not Air's.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants