Gonertia is a well-tested and zero-dependency Inertia.js server-side adapter for Golang. Visit inertiajs.com to learn more.
Inertia allows you to create fully client-side rendered, single-page apps, without the complexity that comes with modern SPAs. It does this by leveraging existing server-side patterns that you already love.
This package based on the official Laravel adapter for Inertia.js: inertiajs/inertia-laravel.
- Tests
- Helpers for testing
- Helpers for validation errors
- SSR
Install using go get
command:
go get github.com/romsar/gonertia
Initialize Gonertia in your main.go
:
package main
import (
"log"
"http"
"time"
inertia "github.com/romsar/gonertia"
)
func main() {
i, err := inertia.New("./ui/templates/root.html")
if err != nil {
log.Fatal(err)
}
// Now create your HTTP server.
// Gonertia works well with standard http handlers,
// but you are free to use some frameworks like Gorilla Mux or Chi.
mux := http.NewServeMux()
mux.Handle("/home", i.Middleware(homeHandler(i)))
}
func homeHandler(i *inertia.Inertia) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
err := i.Render(w, r, "Home/Index", inertia.Props{
"some": "data",
})
if err != nil {
handleServerErr(w, err)
}
}
return http.HandlerFunc(fn)
}
Create root.html
template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>title</title>
{{ .inertiaHead }}
</head>
<body>
{{ .inertia }}
<script src="/static/js/app.js"></script>
</body>
</html>
import "embed"
//go:embed templates
var templateFS embed.FS
// ...
i, err := inertia.New(
/* ... */
inertia.WithTemplateFS(templateFS),
)
Set asset version (learn more)
i, err := inertia.New(
/* ... */
inertia.WithVersion("some-version"), // by any string
inertia.WithAssetURL("/static/js/1f0f8sc6.js"), // by asset url
inertia.WithManifestFile("./ui/manifest.json"), // by manifest file
)
import jsoniter "github.com/json-iterator/go"
// ...
i, err := inertia.New(
/* ... */,
inertia.WithMarshalJSON(jsoniter.Marshal),
)
i, err := inertia.New(
/* ... */
inertia.WithLogger(somelogger.New()),
// or inertia.WithoutLogger(),
)
i, err := inertia.New(
/* ... */
inertia.WithContainerID("inertia"),
)
Closure and lazy props (learn more)
props := inertia.Props{
"regular": "prop",
"closure": func () (any, error) { return "prop", nil },
"lazy": inertia.LazyProp(func () (any, error) {
return "prop", nil
},
}
i.Render(w, r, "Some/Page", props)
Redirects (learn more)
func homeHandler(i *inertia.Inertia) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
i.Location(w, r, "/some-url")
}
return http.HandlerFunc(fn)
}
NOTES: If response is empty - user will be redirected to the previous url.
To redirect back, you can use Back
helper:
i.Back(w, r)
Share template data (learn more)
i.ShareTemplateData("title", "Home page")
<title>{{ .title }}</title>
i.ShareTemplateFunc("trim", strings.Trim)
<title>{{ trim "foo bar" }}</title>
ctx := i.WithTemplateData(r.Context(), "title", "Home page")
// pass it to the next middleware or inertia.Render function using r.WithContext(ctx).
Share prop globally (learn more)
i.ShareProp("name", "Roman")
ctx := i.WithProp(r.Context(), "name", "Roman")
// or i.WithProps(r.Context(), inertia.Props{"name": "Roman"})
// pass it to the next middleware or inertia.Render function using r.WithContext(ctx).
Validation errors (learn more)
ctx := i.WithValidationError(r.Context(), "some_field", "some error")
// or i.WithValidationErrors(r.Context(), inertia.ValidationErrors{"some_field": "some error"})
// pass it to the next middleware or inertia.Render function using r.WithContext(ctx).
Of course, this package provides convenient interfaces for testing!
func TestHomepage(t *testing.T) {
body := ... // get an HTML or JSON using httptest package or real HTTP request.
// ...
assertable := inertia.Assert(t, body) // io.Reader body
// OR
assertable := inertia.AssertFromBytes(t, body) // []byte body
// OR
assertable := inertia.AssertFromString(t, body) // string body
// now you can do assertions using assertable.Assert[...] methods:
assertable.AssertComponent("Foo/Bar")
assertable.AssertVersion("foo bar")
assertable.AssertURL("https://example.com")
assertable.AssertProps(inertia.Props{"foo": "bar"})
// or work with the data yourself:
assertable.Component // Foo/Bar
assertable.Version // foo bar
assertable.URL // https://example.com
assertable.Props // inertia.Props{"foo": "bar"}
}
This package is based on inertiajs/inertia-laravel and uses some parts of petaki/inertia-go.
Gonertia is released under the MIT License.