https://github.com/petaki/inertia-go
⏩ Inertia.js server-side adapter for Go.
https://github.com/petaki/inertia-go
go golang inertiajs
Last synced: 3 months ago
JSON representation
⏩ Inertia.js server-side adapter for Go.
- Host: GitHub
- URL: https://github.com/petaki/inertia-go
- Owner: petaki
- License: mit
- Created: 2020-08-26T19:48:13.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2025-02-14T22:22:27.000Z (over 1 year ago)
- Last Synced: 2025-02-14T22:29:28.992Z (over 1 year ago)
- Topics: go, golang, inertiajs
- Language: Go
- Homepage:
- Size: 35.2 KB
- Stars: 231
- Watchers: 5
- Forks: 12
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README

# Inertia.js Go Adapter
[](https://github.com/petaki/inertia-go/actions)
[](LICENSE.md)
An Inertia.js server-side adapter for Go. Visit [inertiajs.com](https://inertiajs.com) to learn more.
## Installation
Install the package using the `go get` command:
```
go get github.com/petaki/inertia-go
```
## Usage
### 1. Create new instance
```go
url := "http://inertia-app.test" // Application URL for redirect
rootTemplate := "./app.gohtml" // Root template, see the example below
version := "" // Asset version
inertiaManager := inertia.New(url, rootTemplate, version)
```
Or create with `embed.FS` for root template:
```go
import "embed"
//go:embed template
var templateFS embed.FS
// ...
inertiaManager := inertia.New(url, rootTemplate, version, templateFS)
```
### 2. Register the middleware
```go
mux := http.NewServeMux()
mux.Handle("/", inertiaManager.Middleware(homeHandler))
```
### 3. Render in handlers
```go
func homeHandler(w http.ResponseWriter, r *http.Request) {
// ...
err := inertiaManager.Render(w, r, "home/Index", nil)
if err != nil {
// Handle server error...
}
}
```
Or render with props:
```go
// ...
err := inertiaManager.Render(w, r, "home/Index", map[string]any{
"total": 32,
})
//...
```
### 4. Server-side Rendering (Optional)
First, enable SSR with the url of the Node server:
```go
inertiaManager.EnableSsrWithDefault() // http://127.0.0.1:13714/render
```
Or with custom url:
```go
inertiaManager.EnableSsr("http://ssr-host:13714/render")
```
Or with the Vite dev server:
```go
inertiaManager.EnableSsr("http://localhost:5173/__inertia_ssr")
```
You can also provide a custom `*http.Client`:
```go
client := &http.Client{
Timeout: 10 * time.Second,
}
inertiaManager.EnableSsr("http://ssr-host:13714/render", client)
inertiaManager.EnableSsrWithDefault(client)
```
For more information, please read the official Server-side Rendering documentation on [inertiajs.com](https://inertiajs.com).
## Props
| Prop Type | Method(s) | Evaluation | Full | Partial |
|-----------|-----------|------------|------|---------|
| Base | `Share`, `WithProp`, `Render` | Eager | ✅ | ✅ if requested |
| Optional | `WithOptionalProp` | Lazy | ❌ | ✅ if requested |
| Always | `WithAlwaysProp` | Lazy | ✅ | ✅ always |
| Deferred | `WithDeferredProp` | Lazy | ❌ deferred | ✅ if requested |
| Merge | `WithMergeProp` | Lazy | ✅ | ✅ if requested |
| Deep Merge | `WithDeepMergeProp` | Lazy | ✅ | ✅ if requested |
| Prepend | `WithPrependProp` | Lazy | ✅ | ✅ if requested |
| Scroll | `WithScrollProp` | — | ✅ metadata | ✅ metadata |
| Once | `WithOnceProp`, `WithOnce` | Lazy | ✅ | ❌ if in except-once |
| Flash | `WithFlashProp` | Eager | ✅ | ✅ |
`WithOnce` can be combined with Deferred, Merge, Deep Merge, Prepend, and Optional props.
`WithScrollProp` adds scroll metadata to the page response for infinite scroll support.
## Examples
The following examples show how to use the package.
### Share a function with root template (globally)
```go
inertiaManager.ShareFunc("asset", assetFunc)
```
```html
```
### Share data with root template (globally)
```go
inertiaManager.ShareViewData("env", "production")
```
```html
{{ if eq .env "production" }}
...
{{ end }}
```
### Share data with root template (context based)
```go
ctx := inertiaManager.WithViewData(r.Context(), "meta", meta)
r = r.WithContext(ctx)
```
```html
```
### Share a prop (globally)
```go
inertiaManager.Share("title", "Inertia App Title")
```
### Share a prop (context based)
```go
func authenticate(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// ...
ctx := inertiaManager.WithProp(r.Context(), "authUserID", user.ID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
```
### Optional prop (context based)
```go
ctx := inertiaManager.WithOptionalProp(r.Context(), "extra", func() any {
return getExtra()
})
r = r.WithContext(ctx)
```
### Always prop (context based)
```go
ctx := inertiaManager.WithAlwaysProp(r.Context(), "errors", func() any {
return getErrors()
})
r = r.WithContext(ctx)
```
### Deferred prop (context based)
```go
ctx := inertiaManager.WithDeferredProp(r.Context(), "comments", func() any {
return getComments()
})
r = r.WithContext(ctx)
```
### Deferred prop with group (context based)
```go
ctx := inertiaManager.WithDeferredProp(r.Context(), "comments", func() any {
return getComments()
}, "my-group")
r = r.WithContext(ctx)
```
### Merge prop (context based)
```go
ctx := inertiaManager.WithMergeProp(r.Context(), "results", func() any {
return getResults()
})
r = r.WithContext(ctx)
```
Or with match on:
```go
ctx := inertiaManager.WithMergeProp(r.Context(), "results", func() any {
return getResults()
}, "id")
r = r.WithContext(ctx)
```
Or with multiple nested match on paths:
```go
ctx := inertiaManager.WithMergeProp(r.Context(), "complexData", func() any {
return getComplexData()
}, "users.data.id", "messages.uuid")
r = r.WithContext(ctx)
```
### Deep merge prop (context based)
```go
ctx := inertiaManager.WithDeepMergeProp(r.Context(), "settings", func() any {
return getSettings()
})
r = r.WithContext(ctx)
```
Or with match on:
```go
ctx := inertiaManager.WithDeepMergeProp(r.Context(), "settings", func() any {
return getSettings()
}, "id")
r = r.WithContext(ctx)
```
### Prepend prop (context based)
```go
ctx := inertiaManager.WithPrependProp(r.Context(), "notifications", func() any {
return getNotifications()
})
r = r.WithContext(ctx)
```
Or with match on:
```go
ctx := inertiaManager.WithPrependProp(r.Context(), "notifications", func() any {
return getNotifications()
}, "id")
r = r.WithContext(ctx)
```
### Scroll prop (context based)
```go
ctx := inertiaManager.WithScrollProp(r.Context(), "items", inertia.ScrollPageProp{
PageName: "page",
CurrentPage: 1,
NextPage: 2,
})
r = r.WithContext(ctx)
```
### Once prop (context based)
```go
ctx := inertiaManager.WithOnceProp(r.Context(), "plans", func() any {
return getPlans()
})
r = r.WithContext(ctx)
```
### Once modifier (context based)
```go
ctx := inertiaManager.WithMergeProp(r.Context(), "activity", func() any {
return getActivity()
})
ctx = inertiaManager.WithOnce(ctx, "activity")
r = r.WithContext(ctx)
```
Or with expiration:
```go
expiresAt := time.Now().Add(24 * time.Hour).UnixMilli()
ctx := inertiaManager.WithDeferredProp(r.Context(), "permissions", func() any {
return getPermissions()
})
ctx = inertiaManager.WithOnce(ctx, "permissions", inertia.OncePageProp{ExpiresAt: &expiresAt})
r = r.WithContext(ctx)
```
### Flash prop (context based)
```go
ctx := inertiaManager.WithFlashProp(r.Context(), map[string]any{
"success": "Item created successfully",
})
r = r.WithContext(ctx)
```
### Clear history (context based)
```go
ctx := inertiaManager.WithClearHistory(r.Context())
r = r.WithContext(ctx)
```
### Encrypt history (context based)
```go
ctx := inertiaManager.WithEncryptHistory(r.Context())
r = r.WithContext(ctx)
```
### Root template
```html
{{ marshal .page }}
```
### Root template with Server-side Rendering (SSR)
```html
{{ if .ssr }}
{{ raw .ssr.Head }}
{{ end }}
{{ if not .ssr }}
{{ marshal .page }}
{{ else }}
{{ raw .ssr.Body }}
{{ end }}
```
## Example Apps
### Satellite
Vite /
Vue3
https://github.com/petaki/satellite
### Homettp
Vite /
Vue3
https://github.com/homettp/homettp
### Waterkube
Vite /
Vue3
https://github.com/waterkube/waterkube
## Contributors
- [@monstergron](https://github.com/monstergron) for logo ([ArtStation](https://www.artstation.com/danielmakaro))
## Reporting Issues
If you are facing a problem with this package or found any bug, please open an issue on [GitHub](https://github.com/petaki/inertia-go/issues).
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.