inertia

package module
v1.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 12 Imported by: 20

README

Inertia GO

Inertia.js Go Adapter

Build Status

An Inertia.js server-side adapter for Go. Visit 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
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:

import "embed"

//go:embed template
var templateFS embed.FS

// ...

inertiaManager := inertia.New(url, rootTemplate, version, templateFS)
2. Register the middleware
mux := http.NewServeMux()
mux.Handle("/", inertiaManager.Middleware(homeHandler))
3. Render in handlers
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:

// ...

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:

inertiaManager.EnableSsrWithDefault() // http://127.0.0.1:13714/render

Or with custom url:

inertiaManager.EnableSsr("http://ssr-host:13714/render")

Or with the Vite dev server:

inertiaManager.EnableSsr("http://localhost:5173/__inertia_ssr")

You can also provide a custom *http.Client:

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.

Page Props

Name 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 requested
Error WithErrorProp Eager ✅ always ✅ always
  • WithOnce can be combined with Deferred, Merge, Deep Merge, Prepend, and Optional props.
  • WithOnceProp and WithOnce props are excluded when listed in the X-Inertia-Except-Once-Props header.
  • WithScrollProp adds scroll metadata to the page response for infinite scroll support.
  • WithErrorProp errors are merged with any inline errors map passed to Render.

Page Settings

Name Method(s) Evaluation Full Partial
Flash WithFlash Eager
Clear History WithClearHistory Eager
Encrypt History WithEncryptHistory Eager
Preserve Fragment WithPreserveFragment Eager
  • WithClearHistory, WithEncryptHistory, and WithPreserveFragment are emitted only when set to true.

Examples

The following examples show how to use the package.

Share a function with root template (globally)
inertiaManager.ShareFunc("asset", assetFunc)
<script src="{{ asset "js/app.js" }}"></script>
Share data with root template (globally)
inertiaManager.ShareViewData("env", "production")
{{ if eq .env "production" }}
    ...
{{ end }}
Share data with root template (context based)
ctx := inertiaManager.WithViewData(r.Context(), "meta", meta)
r = r.WithContext(ctx)
<meta name="description" content="{{ .meta }}">
Share a prop (globally)
inertiaManager.Share("title", "Inertia App Title")
Share a prop (context based)
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)
ctx := inertiaManager.WithOptionalProp(r.Context(), "extra", func() any {
    return getExtra()
})
r = r.WithContext(ctx)
Always prop (context based)
ctx := inertiaManager.WithAlwaysProp(r.Context(), "notifications", func() any {
    return getNotifications()
})
r = r.WithContext(ctx)
Deferred prop (context based)
ctx := inertiaManager.WithDeferredProp(r.Context(), "comments", func() any {
    return getComments()
})
r = r.WithContext(ctx)
Deferred prop with group (context based)
ctx := inertiaManager.WithDeferredProp(r.Context(), "comments", func() any {
    return getComments()
}, "my-group")
r = r.WithContext(ctx)
Merge prop (context based)
ctx := inertiaManager.WithMergeProp(r.Context(), "results", func() any {
    return getResults()
})
r = r.WithContext(ctx)

Or with match on:

ctx := inertiaManager.WithMergeProp(r.Context(), "results", func() any {
    return getResults()
}, "id")
r = r.WithContext(ctx)

Or with multiple nested match on paths:

ctx := inertiaManager.WithMergeProp(r.Context(), "complexData", func() any {
    return getComplexData()
}, "users.data.id", "messages.uuid")
r = r.WithContext(ctx)
Deep merge prop (context based)
ctx := inertiaManager.WithDeepMergeProp(r.Context(), "settings", func() any {
    return getSettings()
})
r = r.WithContext(ctx)

Or with match on:

ctx := inertiaManager.WithDeepMergeProp(r.Context(), "settings", func() any {
    return getSettings()
}, "id")
r = r.WithContext(ctx)
Prepend prop (context based)
ctx := inertiaManager.WithPrependProp(r.Context(), "notifications", func() any {
    return getNotifications()
})
r = r.WithContext(ctx)

Or with match on:

ctx := inertiaManager.WithPrependProp(r.Context(), "notifications", func() any {
    return getNotifications()
}, "id")
r = r.WithContext(ctx)
Scroll prop (context based)
ctx := inertiaManager.WithScrollProp(r.Context(), "items", inertia.ScrollPageProp{
    PageName:    "page",
    CurrentPage: 1,
    NextPage:    2,
})
r = r.WithContext(ctx)
Once prop (context based)
ctx := inertiaManager.WithOnceProp(r.Context(), "plans", func() any {
    return getPlans()
})
r = r.WithContext(ctx)
Once modifier (context based)
ctx := inertiaManager.WithMergeProp(r.Context(), "activity", func() any {
    return getActivity()
})
ctx = inertiaManager.WithOnce(ctx, "activity")
r = r.WithContext(ctx)

Or with expiration:

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)
Error prop (context based)
ctx := inertiaManager.WithErrorProp(r.Context(), "email", "Invalid email")
r = r.WithContext(ctx)

Or with multiple fields:

ctx := inertiaManager.WithErrorProp(r.Context(), "email", "Invalid email")
ctx = inertiaManager.WithErrorProp(ctx, "password", "Too short")
r = r.WithContext(ctx)
Flash (context based)
ctx := inertiaManager.WithFlash(r.Context(), map[string]any{
    "success": "Item created successfully",
})
r = r.WithContext(ctx)
Clear history (context based)
ctx := inertiaManager.WithClearHistory(r.Context())
r = r.WithContext(ctx)
Encrypt history (context based)
ctx := inertiaManager.WithEncryptHistory(r.Context())
r = r.WithContext(ctx)
Preserve fragment (context based)
ctx := inertiaManager.WithPreserveFragment(r.Context())
r = r.WithContext(ctx)
Root template
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/app.css" rel="stylesheet">
        <link rel="icon" type="image/x-icon" href="favicon.ico">
    </head>
    <body>
        <script data-page="app" type="application/json">{{ marshal .page }}</script>
        <div id="app"></div>
        <script src="js/app.js"></script>
    </body>
</html>
Root template with Server-side Rendering (SSR)
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/app.css" rel="stylesheet">
        <link rel="icon" type="image/x-icon" href="favicon.ico">
        {{ if .ssr }}
            {{ raw .ssr.Head }}
        {{ end }}
    </head>
    <body>
        {{ if not .ssr }}
            <script data-page="app" type="application/json">{{ marshal .page }}</script>
            <div id="app"></div>
        {{ else }}
            {{ raw .ssr.Body }}
        {{ end }}
        <script src="js/app.js"></script>
    </body>
</html>

Vite Integration

For Vite integration, check out the Usage with Inertia section in the petaki/support-go package.

Example Apps

Satellite

Vite Vite / Vue3 Vue3

https://github.com/petaki/satellite

Homettp

Vite Vite / Vue3 Vue3

https://github.com/homettp/homettp

Waterkube

Vite Vite / Vue3 Vue3

https://github.com/waterkube/waterkube

Contributors

Reporting Issues

If you are facing a problem with this package or found any bug, please open an issue on GitHub.

License

The MIT License (MIT). Please see License File for more information.

Documentation

Index

Constants

View Source
const (
	// HeaderInertia header.
	HeaderInertia = "X-Inertia"

	// HeaderLocation header.
	HeaderLocation = "X-Inertia-Location"

	// HeaderVersion header.
	HeaderVersion = "X-Inertia-Version"

	// HeaderPartialComponent header.
	HeaderPartialComponent = "X-Inertia-Partial-Component"

	// HeaderPartialOnly header.
	HeaderPartialOnly = "X-Inertia-Partial-Data"

	// HeaderPartialExcept header.
	HeaderPartialExcept = "X-Inertia-Partial-Except"

	// HeaderExceptOnceProps header.
	HeaderExceptOnceProps = "X-Inertia-Except-Once-Props"

	// HeaderReset header.
	HeaderReset = "X-Inertia-Reset"
)

Variables

View Source
var (
	// ErrBadSsrStatusCode error.
	ErrBadSsrStatusCode = errors.New("inertia: bad ssr status code >= 400")

	// ErrInvalidContextValue error.
	ErrInvalidContextValue = errors.New("inertia: could not convert context value to expected type")
)

Functions

This section is empty.

Types

type Inertia

type Inertia struct {
	// contains filtered or unexported fields
}

Inertia type.

func New

func New(url, rootTemplate, version string, templateFS ...fs.FS) *Inertia

New function.

func (*Inertia) DisableSsr added in v1.5.0

func (i *Inertia) DisableSsr()

DisableSsr function.

func (*Inertia) EnableSsr added in v1.5.0

func (i *Inertia) EnableSsr(ssrURL string, client ...*http.Client)

EnableSsr function.

func (*Inertia) EnableSsrWithDefault added in v1.5.0

func (i *Inertia) EnableSsrWithDefault(client ...*http.Client)

EnableSsrWithDefault function.

func (*Inertia) IsSsrEnabled added in v1.5.0

func (i *Inertia) IsSsrEnabled() bool

IsSsrEnabled function.

func (*Inertia) Location added in v1.1.1

func (i *Inertia) Location(w http.ResponseWriter, r *http.Request, url string)

Location function.

func (*Inertia) Middleware

func (i *Inertia) Middleware(next http.Handler) http.Handler

Middleware function.

func (*Inertia) Render

func (i *Inertia) Render(w http.ResponseWriter, r *http.Request, component string, props map[string]any) error

Render function.

func (*Inertia) Share

func (i *Inertia) Share(key string, value any)

Share function.

func (*Inertia) ShareFunc

func (i *Inertia) ShareFunc(key string, value any)

ShareFunc function.

func (*Inertia) ShareViewData added in v1.10.0

func (i *Inertia) ShareViewData(key string, value any)

ShareViewData function.

func (*Inertia) WithAlwaysProp added in v1.14.0

func (i *Inertia) WithAlwaysProp(ctx context.Context, key string, value func() any) context.Context

WithAlwaysProp function.

func (*Inertia) WithClearHistory added in v1.14.0

func (i *Inertia) WithClearHistory(ctx context.Context) context.Context

WithClearHistory function.

func (*Inertia) WithDeepMergeProp added in v1.14.0

func (i *Inertia) WithDeepMergeProp(ctx context.Context, key string, value func() any, matchOn ...string) context.Context

WithDeepMergeProp function.

func (*Inertia) WithDeferredProp added in v1.14.0

func (i *Inertia) WithDeferredProp(ctx context.Context, key string, value func() any, group ...string) context.Context

WithDeferredProp function.

func (*Inertia) WithEncryptHistory added in v1.14.0

func (i *Inertia) WithEncryptHistory(ctx context.Context) context.Context

WithEncryptHistory function.

func (*Inertia) WithErrorProp added in v1.15.0

func (i *Inertia) WithErrorProp(ctx context.Context, key string, value any) context.Context

WithErrorProp function.

func (*Inertia) WithFlash added in v1.15.0

func (i *Inertia) WithFlash(ctx context.Context, data map[string]any) context.Context

WithFlash function.

func (*Inertia) WithMergeProp added in v1.14.0

func (i *Inertia) WithMergeProp(ctx context.Context, key string, value func() any, matchOn ...string) context.Context

WithMergeProp function.

func (*Inertia) WithOnce added in v1.14.0

func (i *Inertia) WithOnce(ctx context.Context, key string, prop ...OncePageProp) context.Context

WithOnce function.

func (*Inertia) WithOnceProp added in v1.14.0

func (i *Inertia) WithOnceProp(ctx context.Context, key string, value func() any) context.Context

WithOnceProp function.

func (*Inertia) WithOptionalProp added in v1.14.0

func (i *Inertia) WithOptionalProp(ctx context.Context, key string, value func() any) context.Context

WithOptionalProp function.

func (*Inertia) WithPrependProp added in v1.14.0

func (i *Inertia) WithPrependProp(ctx context.Context, key string, value func() any, matchOn ...string) context.Context

WithPrependProp function.

func (*Inertia) WithPreserveFragment added in v1.15.0

func (i *Inertia) WithPreserveFragment(ctx context.Context) context.Context

WithPreserveFragment function.

func (*Inertia) WithProp

func (i *Inertia) WithProp(ctx context.Context, key string, value any) context.Context

WithProp function.

func (*Inertia) WithScrollProp added in v1.14.0

func (i *Inertia) WithScrollProp(ctx context.Context, key string, prop ScrollPageProp) context.Context

WithScrollProp function.

func (*Inertia) WithViewData

func (i *Inertia) WithViewData(ctx context.Context, key string, value any) context.Context

WithViewData function.

type OncePageProp added in v1.14.0

type OncePageProp struct {
	Prop      string `json:"prop"`
	ExpiresAt *int64 `json:"expiresAt,omitempty"`
}

OncePageProp type.

type Page

type Page struct {
	Component        string                    `json:"component"`
	Props            map[string]any            `json:"props"`
	URL              string                    `json:"url"`
	Version          string                    `json:"version"`
	SharedProps      []string                  `json:"sharedProps,omitempty"`
	DeferredProps    map[string][]string       `json:"deferredProps,omitempty"`
	MergeProps       []string                  `json:"mergeProps,omitempty"`
	DeepMergeProps   []string                  `json:"deepMergeProps,omitempty"`
	PrependProps     []string                  `json:"prependProps,omitempty"`
	MatchPropsOn     []string                  `json:"matchPropsOn,omitempty"`
	ScrollProps      map[string]ScrollPageProp `json:"scrollProps,omitempty"`
	OnceProps        map[string]OncePageProp   `json:"onceProps,omitempty"`
	Flash            map[string]any            `json:"flash,omitempty"`
	ClearHistory     bool                      `json:"clearHistory,omitempty"`
	EncryptHistory   bool                      `json:"encryptHistory,omitempty"`
	PreserveFragment bool                      `json:"preserveFragment,omitempty"`
}

Page type.

type ScrollPageProp added in v1.14.0

type ScrollPageProp struct {
	PageName     string `json:"pageName"`
	CurrentPage  any    `json:"currentPage"`
	PreviousPage any    `json:"previousPage,omitempty"`
	NextPage     any    `json:"nextPage,omitempty"`
	Reset        bool   `json:"reset"`
}

ScrollPageProp type.

type Ssr added in v1.5.0

type Ssr struct {
	Head []string `json:"head"`
	Body string   `json:"body"`
}

Ssr type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL