### Go Web Server Example Source: https://templ.guide/developer-tools/live-reload A basic Go web server setup using Templ components. This file is typically run by the `--cmd` flag in `templ generate`. ```go package main import ( "fmt" "net/http" "github.com/a-h/templ" ) func main() { component := hello("World") http.Handle("/", templ.Handler(component)) fmt.Println("Listening on :8080") http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Initialize NPM Project and Install Dependencies Source: https://templ.guide/syntax-and-usage/script-templates Sets up a new Node.js project and installs TypeScript and esbuild as development dependencies. ```bash mkdir ts cd ts npm init npm install --save-dev typescript esbuild ``` -------------------------------- ### Install templ in Nix Flake Source: https://templ.guide/quick-start/installation Example configuration for integrating templ into a Nix Flake, either for NixOS or a project-specific flake. ```nix { inputs = { ... templ.url = "github:a-h/templ"; ... }; outputs = inputs@{ ... }: # For NixOS configuration: { # Add the overlay, nixpkgs.overlays = [ inputs.templ.overlays.default ]; # and install the package environment.systemPackages = with pkgs; [ templ ]; }; # For a flake project: let forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f { inherit system; pkgs = import nixpkgs { inherit system; }; }); templ = system: inputs.templ.packages.${system}.templ; in { packages = forAllSystems ({ pkgs, system }: { myNewPackage = pkgs.buildGoModule { ... preBuild = "''${templ system}/bin/templ generate "; }; }); devShell = forAllSystems ({ pkgs, system }: pkgs.mkShell { buildInputs = with pkgs [ go (templ system) ]; }); } ``` -------------------------------- ### Build a URL with Path and Query Parameters Source: https://templ.guide/experimental/urlbuilder Use `urlbuilder.New` to start constructing a URL. Chain `Path` and `Query` methods to add segments and parameters. Finally, call `Build` to get a `templ.SafeURL`. ```go import ( "github.com/templ-go/x/urlbuilder" "strconv" "strings" ) templ component(o Order) { { strings.ToUpper(o.Name) } } ``` -------------------------------- ### Start HTTP Server in Go Source: https://templ.guide/syntax-and-usage/forms Starts the HTTP server on the specified address and port, returning any error encountered. ```go log.Info("Starting server", slog.String("address", addr)) return http.ListenAndServe(addr, mux) ``` -------------------------------- ### Troubleshooting: Check Binary Installation Source: https://templ.guide/developer-tools/ide-support Verify that Go, gopls, and templ binaries are installed and accessible in your system's PATH. This is crucial for IDE integration. ```bash which go gopls templ ``` ```text /run/current-system/sw/bin/go /Users/adrian/go/bin/gopls /Users/adrian/bin/templ ``` -------------------------------- ### Install templ Globally with Go Source: https://templ.guide/quick-start/installation Installs the templ CLI globally for use on your system. Requires Go 1.24 or greater. ```bash go install github.com/a-h/templ/cmd/templ@latest ``` -------------------------------- ### Main Entrypoint for Go Application Source: https://templ.guide/syntax-and-usage/forms Sets up logging, context, and calls the run function. Exits with an error code if the server fails to start. ```go var dbURI = "file:data.db?mode=rwc" var addr = "localhost:8080" func main() { log := slog.Default() ctx := context.Background() if err := run(ctx, log); err != nil { log.Error("Failed to run server", slog.Any("error", err)) os.Exit(1) } } ``` -------------------------------- ### Setup Templ Counter with Datastar SSE Source: https://templ.guide/server-side-rendering/datastar Sets up SSE endpoints for a templated counter example using Datastar. It handles global and per-user increments and updates the UI with changed signals. ```go package site import ( "net/http" "sync/atomic" "github.com/Jeffail/gabs/v2" "github.com/go-chi/chi/v5" "github.com/gorilla/sessions" "github.com/starfederation/datastar-go/datastar" ) func setupExamplesTemplCounter(examplesRouter chi.Router, sessionSignals sessions.Store) error { var globalCounter atomic.Uint32 const ( sessionKey = "templ_counter" countKey = "count" ) userVal := func(r *http.Request) (uint32, *sessions.Session, error) { sess, err := sessionSignals.Get(r, sessionKey) if err != nil { return 0, nil, err } val, ok := sess.Values[countKey].(uint32) if !ok { val = 0 } return val, sess, nil } examplesRouter.Get("/templ_counter/data", func(w http.ResponseWriter, r *http.Request) { userVal, _, err := userVal(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } signals := TemplCounterSignals{ Global: globalCounter.Load(), User: userVal, } c := templCounterExampleInitialContents(signals) datastar.NewSSE(w, r).MergeFragmentTempl(c) }) updateGlobal := func(signals *gabs.Container) { signals.Set(globalCounter.Add(1), "global") } examplesRouter.Route("/templ_counter/increment", func(incrementRouter chi.Router) { incrementRouter.Post("/global", func(w http.ResponseWriter, r *http.Request) { update := gabs.New() updateGlobal(update) datastar.NewSSE(w, r).MarshalAndMergeSignals(update) }) incrementRouter.Post("/user", func(w http.ResponseWriter, r *http.Request) { val, sess, err := userVal(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } val++ sess.Values[countKey] = val if err := sess.Save(r, w); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } update := gabs.New() updateGlobal(update) update.Set(val, "user") datastar.NewSSE(w, r).MarshalAndMergeSignals(update) }) }) return nil } ``` -------------------------------- ### Install templ as a Go Tool Source: https://templ.guide/quick-start/installation Installs templ locally within your project using Go's tool directive feature. Use 'go tool templ' to run it. ```bash go get -tool github.com/a-h/templ/cmd/templ@latest ``` -------------------------------- ### Run the Go Program Source: https://templ.guide/quick-start/running-your-first-templ-application Execute the Go program from your terminal to start the web server. Ensure you are in the directory containing your `main.go` file. ```bash go run *.go ``` -------------------------------- ### Main Application Entrypoint Source: https://templ.guide/project-structure/project-structure Configures and starts the HTTP server. It initializes the logger, database store, service layer, and HTTP handlers. Session middleware is added, and server timeouts are configured. The application listens on localhost:9000. ```go package main import ( "fmt" "net/http" "os" "time" "github.com/a-h/templ/examples/counter/db" "github.com/a-h/templ/examples/counter/handlers" "github.com/a-h/templ/examples/counter/services" "github.com/a-h/templ/examples/counter/session" "golang.org/x/exp/slog" ) func main() { log := slog.New(slog.NewJSONHandler(os.Stderr)) s, err := db.NewCountStore(os.Getenv("TABLE_NAME"), os.Getenv("AWS_REGION")) if err != nil { log.Error("failed to create store", slog.Any("error", err)) os.Exit(1) } cs := services.NewCount(log, s) h := handlers.New(log, cs) var secureFlag = true if os.Getenv("SECURE_FLAG") == "false" { secureFlag = false } // Add session middleware. sh := session.NewMiddleware(h, session.WithSecure(secureFlag)) server := &http.Server{ Addr: "localhost:9000", Handler: sh, ReadTimeout: time.Second * 10, WriteTimeout: time.Second * 10, } fmt.Printf("Listening on %v\n", server.Addr) server.ListenAndServe() } ``` -------------------------------- ### Serve Static Assets Before Live Reload Setup Source: https://templ.guide/developer-tools/live-reload-with-other-tools This Go code snippet demonstrates serving static assets using `http.FS` with `embed.FS` before implementing live reload. ```go //go:embed assets/* var assets embed.FS ... mux.Handle("/assets/", http.FileServer(http.FS(assets))) ``` -------------------------------- ### Multi-stage Dockerfile with templ Source: https://templ.guide/quick-start/installation An example Dockerfile demonstrating a multi-stage build process using the templ Docker image to generate code. ```dockerfile # Fetch FROM golang:latest AS fetch-stage COPY go.mod go.sum /app WORKDIR /app RUN go mod download # Generate FROM ghcr.io/a-h/templ:latest AS generate-stage COPY --chown=65532:65532 . /app WORKDIR /app RUN ["templ", "generate"] # Build FROM golang:latest AS build-stage COPY --from=generate-stage /app /app WORKDIR /app RUN CGO_ENABLED=0 GOOS=linux go build -o /app/app # Test FROM build-stage AS test-stage RUN go test -v ./... # Deploy FROM gcr.io/distroless/base-debian12 AS deploy-stage WORKDIR / COPY --from=build-stage /app/app /app EXPOSE 8080 USER nonroot:nonroot ENTRYPOINT ["/app"] ``` -------------------------------- ### Vim: Install LSP and Autocomplete Plugins Source: https://templ.guide/developer-tools/ide-support Use vim-plug to install the necessary plugins for LSP and autocompletion in Vim. Ensure you are using Vim version 8 or later. ```vim Plug 'prabirshrestha/vim-lsp' Plug 'prabirshrestha/asyncomplete.vim' Plug 'prabirshrestha/asyncomplete-lsp.vim' ``` -------------------------------- ### Prop Drilling Example in Templ Source: https://templ.guide/syntax-and-usage/context Demonstrates how data is passed through multiple components using props, leading to prop drilling. ```templ package main templ top(name string) {
@middle(name)
} templ middle(name string) { } templ bottom(name string) {
  • { name }
  • } ``` -------------------------------- ### Enter Nix Development Shell Source: https://templ.guide/quick-start/installation Starts a Nix development shell that includes tools like Go and gopls, but not templ itself. Useful for building templ. ```bash nix develop github:a-h/templ ``` -------------------------------- ### Go View Model Example Source: https://templ.guide/core-concepts/view-models This Go code demonstrates how to create a handler that fetches data, constructs a view model, and then renders a Templ component with that view model. It includes the handler logic, the view model definition, and the Templ component itself. ```go package invitesget type Handler struct { Invites *InviteService } func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { invites, err := h.Invites.Get(getUserIDFromContext(r.Context())) if err != nil { //TODO: Log error server side. } m := NewInviteComponentViewModel(invites, err) teamInviteComponent(m).Render(r.Context(), w) } func NewInviteComponentViewModel(invites []models.Invite, err error) (m InviteComponentViewModel) { m.InviteCount = len(invites) if err != nil { m.ErrorMessage = "Failed to load invites, please try again" } return m } type InviteComponentViewModel struct { InviteCount int ErrorMessage string } templ teamInviteComponent(model InviteComponentViewModel) { if model.InviteCount > 0 {
    You have { fmt.Sprintf("%d", model.InviteCount) } pending invites
    } if model.ErrorMessage != "" {
    { model.ErrorMessage }
    } } ``` -------------------------------- ### HTMX Example with Fragments Source: https://templ.guide/syntax-and-usage/fragments This example demonstrates using templ fragments with HTMX. The server conditionally renders either the full page or just a button fragment based on the 'template' query parameter. ```go package main import ( "fmt" "net/http" "strconv" ) type PageState struct { Counter int Next int } templ Page(state PageState) { @templ.Fragment("buttonOnly") { } } // handleRequest does the work to execute the template (or fragment) and serve the result. // It's mostly boilerplate, so don't get hung up on it. func handleRequest(w http.ResponseWriter, r *http.Request) { // Collect state info to pass to the template. var state PageState state.Counter, _ = strconv.Atoi(r.URL.Query().Get("counter")) state.Next = state.Counter + 1 // If the template querystring paramater is set, render the pecific fragment. var opts []func(*templ.ComponentHandler) if templateName := r.URL.Query().Get("template"); templateName != "" { opts = append(opts, templ.WithFragments(templateName)) } // Render the template or fragment and serve it. templ.Handler(Page(state), opts...).ServeHTTP(w, r) } func main() { // Handle the template. http.HandleFunc("/", handleRequest) // Start the server. fmt.Println("Server is running at http://localhost:8080") http.ListenAndServe("localhost:8080", nil) } ``` -------------------------------- ### Serve Static Assets After Live Reload Setup Source: https://templ.guide/developer-tools/live-reload-with-other-tools This Go code snippet shows how to serve static assets using `http.Dir` after setting up live reload, which requires serving from the filesystem. ```go mux.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("assets")))) ``` -------------------------------- ### Vim: Install Templ.vim Plugin for Indentation Source: https://templ.guide/developer-tools/ide-support Optionally install the templ.vim plugin for improved indentation behavior outside of Templ blocks, especially when working with Go code. ```vim Plug 'iefserge/templ.vim' ``` -------------------------------- ### Start templ proxy server in watch mode Source: https://templ.guide/developer-tools/live-reload-with-other-tools Use this command to start the templ proxy server. It watches for changes in .templ files and sends reload events. Set `--open-browser=false` to prevent automatic browser opening. ```bash templ generate --watch --proxy="http://localhost:8080" --open-browser=false ``` -------------------------------- ### Configure Templ LSP in Neovim Source: https://templ.guide/developer-tools/ide-support Set up the templ Language Server Protocol (LSP) in Neovim by iterating through a list of servers and calling their respective setup functions. Ensure the 'templ' command is in your system path. ```lua local lspconfig = require("lspconfig") -- Use a loop to conveniently call 'setup' on multiple servers and -- map buffer local keybindings when the language server attaches local servers = { 'gopls', 'ccls', 'cmake', 'tsserver', 'templ' } for _, lsp in ipairs(servers) do lspconfig[lsp].setup({ on_attach = on_attach, capabilities = capabilities, }) end ``` -------------------------------- ### Templ Component Example Source: https://templ.guide/developer-tools/live-reload A simple Templ component that renders a greeting. Changes to this file will trigger live reload. ```templ package main templ hello(name string) {
    Hello, { name }
    } ``` -------------------------------- ### Serve Fixed Data with templ.Handler and Options Source: https://templ.guide/server-side-rendering/creating-an-http-server-with-templ Serve components with fixed data and control rendering options like HTTP status codes. The output reflects the time the server started, not the current time. ```go package main import "time" templ timeComponent(d time.Time) {
    { d.String() }
    } templ notFoundComponent() {
    404 - Not found
    } ``` ```go package main import ( "net/http" "time" "github.com/a-h/templ" ) func main() { http.Handle("/", templ.Handler(timeComponent(time.Now()))) http.Handle("/404", templ.Handler(notFoundComponent(), templ.WithStatus(http.StatusNotFound))) http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Generate Code for a Single File Source: https://templ.guide/developer-tools/cli Example of how to use the `templ generate` command to generate Go code for a specific .templ file. ```bash templ generate -f header.templ ``` -------------------------------- ### Integrate Middleware and Load Locales Source: https://templ.guide/integrations/internationalization This Go code demonstrates how to load translation locales and integrate the language selection middleware with an HTTP server. It sets up a templ handler and starts the server. ```go func main() { if err := ctxi18n.Load(locales.Content); err != nil { log.Fatalf("error loading locales: %v", err) } mux := http.NewServeMux() mux.Handle("/", templ.Handler(page())) withLanguageMiddleware := newLanguageMiddleware(mux) log.Println("listening on :8080") if err := http.ListenAndServe("127.0.0.1:8080", withLanguageMiddleware); err != nil { log.Printf("error listening: %v", err) } } ``` -------------------------------- ### Importing and Using a Templ Component Source: https://templ.guide/syntax-and-usage/template-composition To use a component from another package, import that package and then use the component as you would any other Go function or type. This example imports the 'Hello' component from the 'components' package. ```go package main import "github.com/a-h/templ/examples/counter/components" templ Home() { @components.Hello() } ``` -------------------------------- ### Install htmx Client-Side Library Source: https://templ.guide/server-side-rendering/htmx Include this script tag in the head of your HTML to load the htmx library. Ensure the path to `htmx.min.js` is correct for your project. ```html ``` -------------------------------- ### Templ Counter Example with Datastar Signals Source: https://templ.guide/server-side-rendering/datastar Defines Templ components for a counter example using Datastar signals. It includes buttons for incrementing global and user-specific counts and displays the current values. The `data-signals` attribute initializes reactive signals, and `data-on:click` triggers server requests on button clicks. ```go package site import "github.com/starfederation/datastar-go/datastar" type TemplCounterSignals struct { Global uint32 `json:"global"` User uint32 `json:"user"` } templ templCounterExampleButtons() {
    } templ templCounterExampleCounts() {
    Global
    User
    } templ templCounterExampleInitialContents(signals TemplCounterSignals) {
    @templCounterExampleButtons() @templCounterExampleCounts()
    } ``` -------------------------------- ### Configure HTML LSP in Neovim Source: https://templ.guide/developer-tools/ide-support Set up the HTML Language Server Protocol (LSP) in Neovim to work with both 'html' and 'templ' filetypes. Ensure the HTML LSP is installed via Mason or :LspInstall. ```lua lspconfig.html.setup({ on_attach = on_attach, capabilities = capabilities, filetypes = { "html", "templ" }, }) ``` -------------------------------- ### Run templ with Nix Source: https://templ.guide/quick-start/installation Executes the templ binary using Nix without a global installation. This command fetches and runs the latest version. ```bash nix run github:a-h/templ ``` -------------------------------- ### Define a templ Component Source: https://templ.guide/static-rendering/generating-static-html-files-with-templ Create a .templ file to define a reusable HTML component. This example defines a simple greeting component. ```templ package main templ hello(name string) {
    Hello, { name }
    } ``` -------------------------------- ### Render Chart with Go Data using Script Template Source: https://templ.guide/syntax-and-usage/script-templates This example demonstrates how to use a script template to render a chart with data passed from Go. The `graph` script template creates a chart using LightweightCharts and populates it with `data` provided by the `page` template. ```go package main script graph(data []TimeValue) { const chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 }); const lineSeries = chart.addLineSeries(); lineSeries.setData(data); } templ page(data []TimeValue) { } ``` ```go package main import ( "fmt" "log" "net/http" ) type TimeValue struct { Time string `json:"time"` Value float64 `json:"value"` } func main() { mux := http.NewServeMux() // Handle template. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { data := []TimeValue{ {Time: "2019-04-11", Value: 80.01}, {Time: "2019-04-12", Value: 96.63}, {Time: "2019-04-13", Value: 76.64}, {Time: "2019-04-14", Value: 81.89}, {Time: "2019-04-15", Value: 74.43}, {Time: "2019-04-16", Value: 80.01}, {Time: "2019-04-17", Value: 96.63}, {Time: "2019-04-18", Value: 76.64}, {Time: "2019-04-19", Value: 81.89}, {Time: "2019-04-20", Value: 74.43}, } page(data).Render(r.Context(), w) }) // Start the server. fmt.Println("listening on :8080") if err := http.ListenAndServe(":8080", mux); err != nil { log.Printf("error listening: %v", err) } } ``` -------------------------------- ### Test Templ Navigation Component with Goquery Source: https://templ.guide/core-concepts/testing Tests a Templ navigation component by rendering it, parsing with goquery, and asserting the presence of a data-testid attribute. Requires goquery to be installed. ```go func TestNav(t *testing.T) { r, w := io.Pipe() go func() { _ = navTemplate().Render(context.Background(), w) _ = w.Close() }() doc, err := goquery.NewDocumentFromReader(r) if err != nil { t.Fatalf("failed to read template: %v", err) } // Expect the component to include a testid. if doc.Find(`[data-testid="navTemplate"]`).Length() == 0 { t.Error("expected data-testid attribute to be rendered, but it wasn't") } } ``` -------------------------------- ### Lambda Entrypoint with algnhsa Source: https://templ.guide/hosting-and-deployment/hosting-on-aws-lambda Sets up the main entrypoint for an AWS Lambda function using the algnhsa package to adapt the standard Go HTTP interface. It initializes services, handlers, and session middleware before starting the Lambda listener. ```go package main import ( "os" "github.com/a-h/templ/examples/counter/db" "github.com/a-h/templ/examples/counter/handlers" "github.com/a-h/templ/examples/counter/services" "github.com/a-h/templ/examples/counter/session" "github.com/akrylysov/algnhsa" "golang.org/x/exp/slog" ) func main() { // Create handlers. log := slog.New(slog.NewJSONHandler(os.Stderr)) s, err := db.NewCountStore(os.Getenv("TABLE_NAME"), os.Getenv("AWS_REGION")) if err != nil { log.Error("failed to create store", slog.Any("error", err)) os.Exit(1) } cs := services.NewCount(log, s) h := handlers.New(log, cs) // Add session middleware. sh := session.NewMiddleware(h) // Start Lambda. algnhsa.ListenAndServe(sh, nil) } ``` -------------------------------- ### Combine Multiple OnceHandle Scripts Source: https://templ.guide/syntax-and-usage/script-templates This example demonstrates how to use multiple `templ.NewOnceHandle` instances to manage different sets of global client-side scripts, ensuring each set is rendered only once per request. It also shows integrating a third-party script via CDN. ```templ var helloHandle = templ.NewOnceHandle() var surrealHandle = templ.NewOnceHandle() templ hello(label, name string) { @helloHandle.Once() { } @surrealHandle.Once() { }
    } ``` -------------------------------- ### Pass server-side data to client via HTML attribute (Alpine.js example) Source: https://templ.guide/syntax-and-usage/script-templates Demonstrates passing server-side data to the client using `templ.JSONString` within an `x-data` attribute, a pattern used by Alpine.js. ```templ templ DataDisplay(data DataType) {
    } ``` -------------------------------- ### Test Templ Header Component with Goquery Source: https://templ.guide/core-concepts/testing Tests a Templ header component by rendering it to an io.Pipe, parsing the output with goquery, and asserting the presence of a data-testid attribute and the correct page name in the h1 tag. Requires goquery to be installed. ```go func TestHeader(t *testing.T) { // Pipe the rendered template into goquery. r, w := io.Pipe() go func () { _ = headerTemplate("Posts").Render(context.Background(), w) _ = w.Close() }() doc, err := goquery.NewDocumentFromReader(r) if err != nil { t.Fatalf("failed to read template: %v", err) } // Expect the component to be present. if doc.Find(`[data-testid="headerTemplate"]`).Length() == 0 { t.Error("expected data-testid attribute to be rendered, but it wasn't") } // Expect the page name to be set correctly. expectedPageName := "Posts" if actualPageName := doc.Find("h1").Text(); actualPageName != expectedPageName { t.Errorf("expected page name %q, got %q", expectedPageName, actualPageName) } } ``` -------------------------------- ### Initialize Go Project Source: https://templ.guide/static-rendering/generating-static-html-files-with-templ Navigate into the project directory and initialize a new Go module. ```bash cd static-generator go mod init github.com/a-h/templ-examples/static-generator ``` -------------------------------- ### Install Tailwind CSS CLI Source: https://templ.guide/developer-tools/live-reload-with-other-tools Install the Tailwind CSS CLI package. It requires tailwindcss as a local peer dependency and cannot be installed globally. ```bash npm install tailwindcss @tailwindcss/cli ``` -------------------------------- ### Sample Blog Posts Data Source: https://templ.guide/static-rendering/blog-example Initializes a slice of Post structs with sample data for demonstration purposes. ```go posts := []Post{ { Date: time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC), Title: "Happy New Year!", Content: `New Year is a widely celebrated occasion in the United Kingdom, marking the end of one year and the beginning of another. Top New Year Activities in the UK include: * Attending a Hogmanay celebration in Scotland * Taking part in a local First-Foot tradition in Scotland and Northern England * Setting personal resolutions and goals for the upcoming year * Going for a New Year's Day walk to enjoy the fresh start * Visiting a local pub for a celebratory toast and some cheer `, }, { Date: time.Date(2023, time.May, 1, 0, 0, 0, 0, time.UTC), Title: "May Day", Content: `May Day is an ancient spring festival celebrated on the first of May in the United Kingdom, embracing the arrival of warmer weather and the renewal of life. Top May Day Activities in the UK: * Dancing around the Maypole, a traditional folk activity * Attending local village fetes and fairs * Watching or participating in Morris dancing performances * Enjoying the public holiday known as Early May Bank Holiday `, }, } ``` -------------------------------- ### Create a Go HTTP Server with templ Source: https://templ.guide/quick-start/running-your-first-templ-application Update your `main.go` file to serve a templ component as an HTTP handler. This sets up a basic web server that listens on port 3000. ```go package main import ( "fmt" "net/http" "github.com/a-h/templ" ) func main() { component := hello("John") http.Handle("/", templ.Handler(component)) fmt.Println("Listening on :3000") http.ListenAndServe(":3000", nil) } ``` -------------------------------- ### Main program to render HTML to file Source: https://templ.guide/static-rendering/generating-static-html-files-with-templ This Go program demonstrates how to create an HTML file and render a templ component into it. It handles file creation and error checking. ```go package main import ( "context" "log" "os" ) func main() { f, err := os.Create("hello.html") if err != nil { log.Fatalf("failed to create output file: %v", err) } err = hello("John").Render(context.Background(), f) if err != nil { log.Fatalf("failed to write output file: %v", err) } } ``` -------------------------------- ### Initialize Go Project and Add templ Dependency Source: https://templ.guide/quick-start/creating-a-simple-templ-component Initializes a new Go module and adds the templ library as a dependency. ```bash cd hello-world go mod init github.com/a-h/templ-examples/hello-world go get github.com/a-h/templ ``` -------------------------------- ### Serve templ and Static Assets with Go Source: https://templ.guide/syntax-and-usage/using-react-with-templ Set up a Go HTTP server to serve the templ-generated HTML and the static client-side JavaScript bundle. Use `templ.Handler` for templ components and `http.FileServer` for static files. ```go package main import ( "fmt" "log" "net/http" "github.com/a-h/templ" ) func main() { mux := http.NewServeMux() // Serve the templ page. mux.Handle("/", templ.Handler(page())) // Serve static content. mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) // Start the server. fmt.Println("listening on localhost:8080") if err := http.ListenAndServe("localhost:8080", mux); err != nil { log.Printf("error listening: %v", err) } } ``` -------------------------------- ### Handling Text Starting with Control Keywords Source: https://templ.guide/syntax-and-usage/statements To include text that starts with `if`, `switch`, or `for`, use Go string expressions or capitalize the keywords. This prevents the Templ parser from misinterpreting them as control flow statements. ```templ package main templ display(price float64, count int) {

    Switch to Linux

    { `switch to Linux` }

    { "for a day" }

    { fmt.Sprintf("%f", price) }{ "for" }{ fmt.Sprintf("%d", count) }

    { fmt.Sprintf("%f for %d", price, count) }

    } ``` -------------------------------- ### Error: Text Block Starting with Unescaped Keyword Source: https://templ.guide/syntax-and-usage/statements A text run starting with `if`, `for`, or `switch` without an immediately following opening brace `{` will cause a parser error. Use Go string expressions or capitalize the keyword to resolve this. ```templ package main templ text(b bool) {

    if a tree fell in the woods

    } ``` -------------------------------- ### Handle GET Request to Display Form in Go Source: https://templ.guide/syntax-and-usage/forms Implement a handler for GET requests to display the form. This function populates the model with existing data if it's an edit request, or uses an empty model for new entries. ```go func (h *Handler) Get(w http.ResponseWriter, r *http.Request) { model := NewModel() // If it's an edit request, populate the model with existing data. if id := r.PathValue("id"); id != "" { contact, ok, err := h.DB.Get(r.Context(), id) if err != nil { h.Log.Error("Failed to get contact", slog.String("id", id), slog.Any("error", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } if !ok { http.Redirect(w, r, "/contacts/edit", http.StatusSeeOther) return } model = ModelFromContact(contact) } h.DisplayForm(w, r, model) } ``` -------------------------------- ### Create Project Directory Source: https://templ.guide/quick-start/creating-a-simple-templ-component Creates a new directory for your Go project. ```bash mkdir hello-world ``` -------------------------------- ### Implement Go Handlers for HTTP Requests Source: https://templ.guide/server-side-rendering/example-counter-application Implements Go handlers for GET and POST requests. The GET handler renders the page, while the POST handler parses form data, updates global state if the 'global' button was pressed, and then re-renders the page. ```go package main import ( "fmt" "log" "net/http" ) type GlobalState struct { Count int } var global GlobalState func getHandler(w http.ResponseWriter, r *http.Request) { component := page(global.Count, 0) component.Render(r.Context(), w) } func postHandler(w http.ResponseWriter, r *http.Request) { // Update state. r.ParseForm() // Check to see if the global button was pressed. if r.Form.Has("global") { global.Count++ } //TODO: Update session. // Display the form. getHandler(w, r) } func main() { // Handle POST and GET requests. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { postHandler(w, r) return } getHandler(w, r) }) // Start the server. fmt.Println("listening on http://localhost:8000") if err := http.ListenAndServe("localhost:8000", nil); err != nil { log.Printf("error listening: %v", err) } ``` -------------------------------- ### Accessing data from an HTML attribute Source: https://templ.guide/syntax-and-usage/script-templates Example of how to retrieve and parse JSON data from an HTML attribute using client-side JavaScript. ```javascript const button = document.getElementById('alerter'); const data = JSON.parse(button.getAttribute('alert-data')); ``` -------------------------------- ### Configure Go Web Server to Serve Static Assets Source: https://templ.guide/syntax-and-usage/script-templates Sets up an HTTP multiplexer in Go to serve static files from the 'assets' directory and handle Templ component requests. ```go func main() { mux := http.NewServeMux() // Serve the JS bundle. mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets")))) // Serve components. data := map[string]any{"msg": "Hello, World!"} h := templ.Handler(components.Page(data)) mux.Handle("/", h) fmt.Println("Listening on http://localhost:8080") http.ListenAndServe("localhost:8080", mux) } ``` -------------------------------- ### Define Translations in YAML Source: https://templ.guide/integrations/internationalization Translations are stored in YAML files, organized by language. This example shows the structure for English translations. ```yaml en: hello: "Hello" select_language: "Select Language" ``` -------------------------------- ### Setting and Rendering Context in Go Source: https://templ.guide/syntax-and-usage/context Demonstrates creating a context with a value and passing it to a Templ component's Render function. ```go // Define the context key type. type contextKey string // Create a context key for the theme. var themeContextKey contextKey = "theme" // Create a context variable that inherits from a parent, and sets the value "test". ctx := context.WithValue(context.Background(), themeContextKey, "test") // Pass the ctx variable to the render function. themeName().Render(ctx, w) ``` -------------------------------- ### Create a Button Component with templUI Source: https://templ.guide/component-libraries Demonstrates how to import and use the Button component from the templUI library. Ensure the 'components' and 'icons' packages are correctly imported. ```go import "github.com/axzilla/templui/components" templ ExamplePage() { @components.Button(components.ButtonProps{ Text: "Click me", IconRight: icons.ArrowRight(icons.IconProps{Size: "16"}), }) } ``` -------------------------------- ### Format All Templ Files Source: https://templ.guide/developer-tools/cli Demonstrates how to format all .templ files in the current directory and its subdirectories using the `templ fmt` command. ```bash templ fmt . ``` -------------------------------- ### Set Up HTTP Routes in Go Source: https://templ.guide/syntax-and-usage/forms Configures the HTTP multiplexer with handlers for various routes including home, contacts, and contact management (edit/delete). ```go mux := http.NewServeMux() homeHandler := home.NewHandler() mux.Handle("/", homeHandler) ch := contacts.NewHandler(log, db) mux.Handle("/contacts", ch) ceh := contactsedit.NewHandler(log, db) mux.Handle("/contacts/edit", ceh) mux.Handle("/contacts/edit/{id}", ceh) cdh := contactsdelete.NewHandler(log, db) mux.Handle("/contacts/delete/{id}", cdh) ``` -------------------------------- ### Accessing data from a script element Source: https://templ.guide/syntax-and-usage/script-templates Example of how to retrieve and parse JSON data embedded within a script element using client-side JavaScript. ```javascript const data = JSON.parse(document.getElementById('id').textContent); ``` -------------------------------- ### Handle GET Request for Contacts Source: https://templ.guide/syntax-and-usage/forms Retrieves a list of contacts from the database and renders them using the View template. Handles potential database errors. ```go func (h *Handler) Get(w http.ResponseWriter, r *http.Request) { contacts, err := h.DB.List(r.Context()) if err != nil { h.Log.Error("Failed to list contacts", slog.Any("error", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } v := layout.Handler(View(contacts)) v.ServeHTTP(w, r) } ``` -------------------------------- ### Go Main Function for Static Site Generation Source: https://templ.guide/static-rendering/blog-example Orchestrates the static site generation process by creating output directories, rendering the index page, and iterating through blog posts to create individual pages. It handles markdown conversion and integrates raw HTML using the Unsafe component. ```go package main import ( "bytes" "context" "io" "log" "os" "path" "time" "github.com/a-h/templ" "github.com/gosimple/slug" "github.com/yuin/goldmark" ) func main() { // Output path. rootPath := "public" if err := os.Mkdir(rootPath, 0755); err != nil { log.Fatalf("failed to create output directory: %v", err) } // Create an index page. name := path.Join(rootPath, "index.html") f, err := os.Create(name) if err != nil { log.Fatalf("failed to create output file: %v", err) } // Write it out. err = indexPage(posts).Render(context.Background(), f) if err != nil { log.Fatalf("failed to write index page: %v", err) } // Create a page for each post. for _, post := range posts { // Create the output directory. dir := path.Join(rootPath, post.Date.Format("2006/01/02"), slug.Make(post.Title)) if err := os.MkdirAll(dir, 0755); err != nil && err != os.ErrExist { log.Fatalf("failed to create dir %q: %v", dir, err) } // Create the output file. name := path.Join(dir, "index.html") f, err := os.Create(name) if err != nil { log.Fatalf("failed to create output file: %v", err) } // Convert the markdown to HTML, and pass it to the template. var buf bytes.Buffer if err := goldmark.Convert([]byte(post.Content), &buf); err != nil { log.Fatalf("failed to convert markdown to HTML: %v", err) } // Create an unsafe component containing raw HTML. content := Unsafe(buf.String()) // Use templ to render the template containing the raw HTML. err = contentPage(post.Title, content).Render(context.Background(), f) if err != nil { log.Fatalf("failed to write output file: %v", err) } } } ``` -------------------------------- ### Display form using layout handler Source: https://templ.guide/syntax-and-usage/forms Renders the form view within the application's common layout. This method is used by both GET and POST handlers. ```go func (h *Handler) DisplayForm(w http.ResponseWriter, r *http.Request, m Model) { layout.Handler(View(m)).ServeHTTP(w, r) } ``` -------------------------------- ### Dockerfile for Go Application Source: https://templ.guide/hosting-and-deployment/hosting-using-docker This Dockerfile sets up a multi-stage build for a Go application. It first builds the application and then copies the compiled binary and assets to a minimal release image. It exposes port 8080 and runs the application as a non-root user. ```docker # Build. FROM golang:1.20 AS build-stage WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . /app RUN CGO_ENABLED=0 GOOS=linux go build -o /entrypoint # Deploy. FROM gcr.io/distroless/static-debian11 AS release-stage WORKDIR / COPY --from=build-stage /entrypoint /entrypoint COPY --from=build-stage /app/assets /assets EXPOSE 8080 USER nonroot:nonroot ENTRYPOINT ["/entrypoint"] ``` -------------------------------- ### Handle GET request for contact form Source: https://templ.guide/syntax-and-usage/forms Retrieves an existing contact or initializes a new one for form display. Handles database interactions and populates the model. ```go func (h *Handler) Get(w http.ResponseWriter, r *http.Request) { // Read the ID from the URL. id := r.PathValue("id") model := NewModel() if id != "" { // Get the existing contact from the database and populate the form. contact, ok, err := h.DB.Get(r.Context(), id) if err != nil { h.Log.Error("Failed to get contact", slog.String("id", id), slog.Any("error", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return err } if !ok { http.Redirect(w, r, "/contacts/edit", http.StatusSeeOther) return } model = ModelFromContact(contact) } h.DisplayForm(w, r, model) } ```