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

docs: add typescript usage example #738

Merged
merged 8 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ examples/integration-ct/static/index.js
examples/counter/assets/css/bulma.*
examples/counter/assets/js/htmx.min.js
examples/counter-basic/assets/css/bulma.*
examples/typescript/assets/index.js
package-lock.json
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.692
0.2.696
53 changes: 53 additions & 0 deletions examples/typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Pass Go data to TypeScript

This demonstrates how to bundle TypeScript code, and use it in a templ project.

The TypeScript code is bundled using `esbuild`, with templ used to serve HTML.

The code demonstrates application of `onclick` event handlers, and how to pass data from Go to TypeScript.

This demo passes data from server-side Go code to TypeScript code by placing the data in `<script type="application/json">` tags, or data attributes (called `alert-data` in this example).

Note how the Go web server serves the `./assets` directory, which contains the bundled TypeScript code.

## Tasks

### generate

```bash
templ generate
```

### ts-install

Since it's a TypeScript project, you need to install the dependencies.

Dir: ts

```bash
npm install
```

### ts-build-cli

If you have `esbuild` installed globally, you can bundle and minify the TypeScript code without using NPM. Remember to run `npm install` to install the dependencies first.

```bash
esbuild --bundle --minify --outfile=assets/js/index.js ts/src/index.ts
```

### ts-build-npm

If you don't have `esbuild` installed globally, you can use the NPM script to build the TypeScript code.

Dir: ./ts

```bash
npm run build
```

### run

```bash
go run .
```
1 change: 1 addition & 0 deletions examples/typescript/assets/js/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions examples/typescript/components/index.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package components

import (
"encoding/json"
"fmt"
)

type Data struct {
Message string `json:"msg"`
}

func JSON(v any) (string, error) {
s, err := json.Marshal(v)
if err != nil {
return "", err
}
return string(s), nil
}

func JSONScript(id string, data any) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
dataJSON, err := json.Marshal(data)
if err != nil {
return err
}
if _, err = io.WriteString(w, `<script`); err != nil {
return err
}
if id != "" {
if _, err = fmt.Fprintf(w, ` id="%s"`, templ.EscapeString(id)); err != nil {
return err
}
}
if _, err = fmt.Fprintf(w, ` type="application/json">%s</script>`, string(dataJSON)); err != nil {
return err
}
return nil
})
}

templ Page(attributeData Data, scriptData Data) {
<!DOCTYPE html>
<html>
<head>
<title>Script usage</title>
<script src="/assets/js/index.js" defer></script>
</head>
<body>
<button id="attributeAlerter" alert-data={ JSON(attributeData) }>Show alert from data in alert-data attribute</button>
@JSONScript("scriptData", scriptData)
<button id="scriptAlerter">Show alert from data in script</button>
</body>
</html>
}
93 changes: 93 additions & 0 deletions examples/typescript/components/index_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions examples/typescript/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/a-h/templ/examples/typescript

go 1.21.5

replace github.com/a-h/templ => ../../

require github.com/a-h/templ v0.0.0-00010101000000-000000000000
2 changes: 2 additions & 0 deletions examples/typescript/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
30 changes: 30 additions & 0 deletions examples/typescript/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"fmt"
"net/http"

"github.com/a-h/templ"
"github.com/a-h/templ/examples/typescript/components"
)

func main() {
mux := http.NewServeMux()
// Serve the JS bundle.
mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets"))))

// Serve the page.
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Create random server-side data.
attributeData := components.Data{
Message: fmt.Sprintf("Hello, from the attribute data"),
}
scriptData := components.Data{
Message: fmt.Sprintf("Hello, from the script data"),
}
templ.Handler(components.Page(attributeData, scriptData)).ServeHTTP(w, r)
})

fmt.Println("Listening on http://localhost:8080")
http.ListenAndServe("localhost:8080", mux)
}
Loading
Loading