{"id":13514077,"url":"https://github.com/petaki/inertia-go","last_synced_at":"2026-04-04T14:03:55.767Z","repository":{"id":44171468,"uuid":"290590382","full_name":"petaki/inertia-go","owner":"petaki","description":"⏩ Inertia.js server-side adapter for Go.","archived":false,"fork":false,"pushed_at":"2025-02-14T22:22:27.000Z","size":36,"stargazers_count":231,"open_issues_count":4,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-14T22:29:28.992Z","etag":null,"topics":["go","golang","inertiajs"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/petaki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-26T19:48:13.000Z","updated_at":"2025-02-14T22:22:28.000Z","dependencies_parsed_at":"2024-04-10T01:49:43.367Z","dependency_job_id":"9944d857-3242-4ef6-b39a-0e33a20bb439","html_url":"https://github.com/petaki/inertia-go","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petaki%2Finertia-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petaki%2Finertia-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petaki%2Finertia-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petaki%2Finertia-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/petaki","download_url":"https://codeload.github.com/petaki/inertia-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246407401,"owners_count":20772126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","inertiajs"],"created_at":"2024-08-01T05:00:45.532Z","updated_at":"2026-04-04T14:03:55.758Z","avatar_url":"https://github.com/petaki.png","language":"Go","funding_links":[],"categories":["Go","Adapters"],"sub_categories":["Server-side"],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/user-attachments/assets/856bd49b-7bff-4f29-9a9e-fc84e7ab1b49\" width=\"320\" alt=\"Inertia GO\"\u003e\u003c/p\u003e\n\n# Inertia.js Go Adapter\n\n[![Build Status](https://github.com/petaki/inertia-go/workflows/tests/badge.svg)](https://github.com/petaki/inertia-go/actions)\n[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](LICENSE.md)\n\nAn Inertia.js server-side adapter for Go. Visit [inertiajs.com](https://inertiajs.com) to learn more.\n\n## Installation\n\nInstall the package using the `go get` command:\n\n```\ngo get github.com/petaki/inertia-go\n```\n\n## Usage\n\n### 1. Create new instance\n\n```go\nurl := \"http://inertia-app.test\" // Application URL for redirect\nrootTemplate := \"./app.gohtml\"   // Root template, see the example below\nversion := \"\"                    // Asset version\n\ninertiaManager := inertia.New(url, rootTemplate, version)\n```\n\nOr create with `embed.FS` for root template:\n\n```go\nimport \"embed\"\n\n//go:embed template\nvar templateFS embed.FS\n\n// ...\n\ninertiaManager := inertia.New(url, rootTemplate, version, templateFS)\n```\n\n### 2. Register the middleware\n\n```go\nmux := http.NewServeMux()\nmux.Handle(\"/\", inertiaManager.Middleware(homeHandler))\n```\n\n### 3. Render in handlers\n\n```go\nfunc homeHandler(w http.ResponseWriter, r *http.Request) {\n    // ...\n\n    err := inertiaManager.Render(w, r, \"home/Index\", nil)\n    if err != nil {\n        // Handle server error...\n    }\n}\n```\n\nOr render with props:\n\n```go\n// ...\n\nerr := inertiaManager.Render(w, r, \"home/Index\", map[string]any{\n    \"total\": 32,\n})\n\n//...\n```\n\n### 4. Server-side Rendering (Optional)\n\nFirst, enable SSR with the url of the Node server:\n\n```go\ninertiaManager.EnableSsrWithDefault() // http://127.0.0.1:13714/render\n```\n\nOr with custom url:\n\n```go\ninertiaManager.EnableSsr(\"http://ssr-host:13714/render\")\n```\n\nOr with the Vite dev server:\n\n```go\ninertiaManager.EnableSsr(\"http://localhost:5173/__inertia_ssr\")\n```\n\nYou can also provide a custom `*http.Client`:\n\n```go\nclient := \u0026http.Client{\n    Timeout: 10 * time.Second,\n}\n\ninertiaManager.EnableSsr(\"http://ssr-host:13714/render\", client)\ninertiaManager.EnableSsrWithDefault(client)\n```\n\nFor more information, please read the official Server-side Rendering documentation on [inertiajs.com](https://inertiajs.com).\n\n## Props\n\n| Prop Type | Method(s) | Evaluation | Full | Partial |\n|-----------|-----------|------------|------|---------|\n| Base | `Share`, `WithProp`, `Render` | Eager | ✅ | ✅ if requested |\n| Optional | `WithOptionalProp` | Lazy | ❌ | ✅ if requested |\n| Always | `WithAlwaysProp` | Lazy | ✅ | ✅ always |\n| Deferred | `WithDeferredProp` | Lazy | ❌ deferred | ✅ if requested |\n| Merge | `WithMergeProp` | Lazy | ✅ | ✅ if requested |\n| Deep Merge | `WithDeepMergeProp` | Lazy | ✅ | ✅ if requested |\n| Prepend | `WithPrependProp` | Lazy | ✅ | ✅ if requested |\n| Scroll | `WithScrollProp` | — | ✅ metadata | ✅ metadata |\n| Once | `WithOnceProp`, `WithOnce` | Lazy | ✅ | ❌ if in except-once |\n| Flash | `WithFlashProp` | Eager | ✅ | ✅ |\n\n`WithOnce` can be combined with Deferred, Merge, Deep Merge, Prepend, and Optional props.\n`WithScrollProp` adds scroll metadata to the page response for infinite scroll support.\n\n## Examples\n\nThe following examples show how to use the package.\n\n### Share a function with root template (globally)\n\n```go\ninertiaManager.ShareFunc(\"asset\", assetFunc)\n```\n\n```html\n\u003cscript src=\"{{ asset \"js/app.js\" }}\"\u003e\u003c/script\u003e\n```\n\n### Share data with root template (globally)\n\n```go\ninertiaManager.ShareViewData(\"env\", \"production\")\n```\n\n```html\n{{ if eq .env \"production\" }}\n    ...\n{{ end }}\n```\n\n### Share data with root template (context based)\n\n```go\nctx := inertiaManager.WithViewData(r.Context(), \"meta\", meta)\nr = r.WithContext(ctx)\n```\n\n```html\n\u003cmeta name=\"description\" content=\"{{ .meta }}\"\u003e\n```\n\n### Share a prop (globally)\n\n```go\ninertiaManager.Share(\"title\", \"Inertia App Title\")\n```\n\n### Share a prop (context based)\n\n```go\nfunc authenticate(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        // ...\n        \n        ctx := inertiaManager.WithProp(r.Context(), \"authUserID\", user.ID)\n        next.ServeHTTP(w, r.WithContext(ctx))\n    })\n}\n```\n\n### Optional prop (context based)\n\n```go\nctx := inertiaManager.WithOptionalProp(r.Context(), \"extra\", func() any {\n    return getExtra()\n})\nr = r.WithContext(ctx)\n```\n\n### Always prop (context based)\n\n```go\nctx := inertiaManager.WithAlwaysProp(r.Context(), \"errors\", func() any {\n    return getErrors()\n})\nr = r.WithContext(ctx)\n```\n\n### Deferred prop (context based)\n\n```go\nctx := inertiaManager.WithDeferredProp(r.Context(), \"comments\", func() any {\n    return getComments()\n})\nr = r.WithContext(ctx)\n```\n\n### Deferred prop with group (context based)\n\n```go\nctx := inertiaManager.WithDeferredProp(r.Context(), \"comments\", func() any {\n    return getComments()\n}, \"my-group\")\nr = r.WithContext(ctx)\n```\n\n### Merge prop (context based)\n\n```go\nctx := inertiaManager.WithMergeProp(r.Context(), \"results\", func() any {\n    return getResults()\n})\nr = r.WithContext(ctx)\n```\n\nOr with match on:\n\n```go\nctx := inertiaManager.WithMergeProp(r.Context(), \"results\", func() any {\n    return getResults()\n}, \"id\")\nr = r.WithContext(ctx)\n```\n\nOr with multiple nested match on paths:\n\n```go\nctx := inertiaManager.WithMergeProp(r.Context(), \"complexData\", func() any {\n    return getComplexData()\n}, \"users.data.id\", \"messages.uuid\")\nr = r.WithContext(ctx)\n```\n\n### Deep merge prop (context based)\n\n```go\nctx := inertiaManager.WithDeepMergeProp(r.Context(), \"settings\", func() any {\n    return getSettings()\n})\nr = r.WithContext(ctx)\n```\n\nOr with match on:\n\n```go\nctx := inertiaManager.WithDeepMergeProp(r.Context(), \"settings\", func() any {\n    return getSettings()\n}, \"id\")\nr = r.WithContext(ctx)\n```\n\n### Prepend prop (context based)\n\n```go\nctx := inertiaManager.WithPrependProp(r.Context(), \"notifications\", func() any {\n    return getNotifications()\n})\nr = r.WithContext(ctx)\n```\n\nOr with match on:\n\n```go\nctx := inertiaManager.WithPrependProp(r.Context(), \"notifications\", func() any {\n    return getNotifications()\n}, \"id\")\nr = r.WithContext(ctx)\n```\n\n### Scroll prop (context based)\n\n```go\nctx := inertiaManager.WithScrollProp(r.Context(), \"items\", inertia.ScrollPageProp{\n    PageName:    \"page\",\n    CurrentPage: 1,\n    NextPage:    2,\n})\nr = r.WithContext(ctx)\n```\n\n### Once prop (context based)\n\n```go\nctx := inertiaManager.WithOnceProp(r.Context(), \"plans\", func() any {\n    return getPlans()\n})\nr = r.WithContext(ctx)\n```\n\n### Once modifier (context based)\n\n```go\nctx := inertiaManager.WithMergeProp(r.Context(), \"activity\", func() any {\n    return getActivity()\n})\nctx = inertiaManager.WithOnce(ctx, \"activity\")\nr = r.WithContext(ctx)\n```\n\nOr with expiration:\n\n```go\nexpiresAt := time.Now().Add(24 * time.Hour).UnixMilli()\nctx := inertiaManager.WithDeferredProp(r.Context(), \"permissions\", func() any {\n    return getPermissions()\n})\nctx = inertiaManager.WithOnce(ctx, \"permissions\", inertia.OncePageProp{ExpiresAt: \u0026expiresAt})\nr = r.WithContext(ctx)\n```\n\n### Flash prop (context based)\n\n```go\nctx := inertiaManager.WithFlashProp(r.Context(), map[string]any{\n    \"success\": \"Item created successfully\",\n})\nr = r.WithContext(ctx)\n```\n\n### Clear history (context based)\n\n```go\nctx := inertiaManager.WithClearHistory(r.Context())\nr = r.WithContext(ctx)\n```\n\n### Encrypt history (context based)\n\n```go\nctx := inertiaManager.WithEncryptHistory(r.Context())\nr = r.WithContext(ctx)\n```\n\n### Root template\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cmeta charset=\"utf-8\"\u003e\n        \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n        \u003clink href=\"css/app.css\" rel=\"stylesheet\"\u003e\n        \u003clink rel=\"icon\" type=\"image/x-icon\" href=\"favicon.ico\"\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cscript data-page=\"app\" type=\"application/json\"\u003e{{ marshal .page }}\u003c/script\u003e\n        \u003cdiv id=\"app\"\u003e\u003c/div\u003e\n        \u003cscript src=\"js/app.js\"\u003e\u003c/script\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Root template with Server-side Rendering (SSR)\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cmeta charset=\"utf-8\"\u003e\n        \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n        \u003clink href=\"css/app.css\" rel=\"stylesheet\"\u003e\n        \u003clink rel=\"icon\" type=\"image/x-icon\" href=\"favicon.ico\"\u003e\n        {{ if .ssr }}\n            {{ raw .ssr.Head }}\n        {{ end }}\n    \u003c/head\u003e\n    \u003cbody\u003e\n        {{ if not .ssr }}\n            \u003cscript data-page=\"app\" type=\"application/json\"\u003e{{ marshal .page }}\u003c/script\u003e\n            \u003cdiv id=\"app\"\u003e\u003c/div\u003e\n        {{ else }}\n            {{ raw .ssr.Body }}\n        {{ end }}\n        \u003cscript src=\"js/app.js\"\u003e\u003c/script\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Example Apps\n\n### Satellite\n\n\u003cimg src=\"https://github.com/user-attachments/assets/216e9052-4a28-4540-9702-4f039ba0ecda\" width=\"16\" alt=\"Vite\"\u003e Vite /\n\u003cimg src=\"https://github.com/user-attachments/assets/5fb47ac4-cac5-4820-9701-8ea48fa426fc\" width=\"16\" alt=\"Vue3\"\u003e Vue3\n\nhttps://github.com/petaki/satellite\n\n### Homettp\n\n\u003cimg src=\"https://github.com/user-attachments/assets/216e9052-4a28-4540-9702-4f039ba0ecda\" width=\"16\" alt=\"Vite\"\u003e Vite /\n\u003cimg src=\"https://github.com/user-attachments/assets/5fb47ac4-cac5-4820-9701-8ea48fa426fc\" width=\"16\" alt=\"Vue3\"\u003e Vue3\n\nhttps://github.com/homettp/homettp\n\n### Waterkube\n\n\u003cimg src=\"https://github.com/user-attachments/assets/216e9052-4a28-4540-9702-4f039ba0ecda\" width=\"16\" alt=\"Vite\"\u003e Vite /\n\u003cimg src=\"https://github.com/user-attachments/assets/5fb47ac4-cac5-4820-9701-8ea48fa426fc\" width=\"16\" alt=\"Vue3\"\u003e Vue3\n\nhttps://github.com/waterkube/waterkube\n\n## Contributors\n\n- [@monstergron](https://github.com/monstergron) for logo ([ArtStation](https://www.artstation.com/danielmakaro))\n\n## Reporting Issues\n\nIf 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).\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetaki%2Finertia-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpetaki%2Finertia-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetaki%2Finertia-go/lists"}