encore-inertia

Inertia.js adapter for Encore.ts. Lets you build React SPAs driven by Encore raw endpoints — no client-side router needed.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "encore-inertia" with this command: npx skills add simon-johansson/encore-inertia/simon-johansson-encore-inertia-encore-inertia

encore-inertia

Inertia.js adapter for Encore.ts. Lets you build React SPAs driven by Encore raw endpoints — no client-side router needed.

Quick Reference

Export Import path Purpose

createInertiaAdapter

encore-inertia

Create server-side adapter (render, share, getAssetTags)

mountInertiaApp

encore-inertia/react

Mount React app on the client

Installation

npm install encore-inertia npm install react react-dom @inertiajs/react # peer deps for React client npm install -D vite @vitejs/plugin-react # build tooling

Server Setup

  1. Create an Encore service

// frontend/encore.service.ts import { Service } from "encore.dev/service";

export default new Service("frontend");

  1. Create the adapter (one per app)

// frontend/inertia-setup.ts import { createInertiaAdapter } from "encore-inertia";

export const inertia = createInertiaAdapter({ viteEntry: "frontend/src/app.tsx", // must match Vite rollupOptions.input title: "My App", // optional, default "Encore App" });

Config options:

Option Default Description

viteEntry

(required) Vite manifest key matching your entry file

title

"Encore App"

HTML <title>

manifestPath

"frontend/dist/.vite/manifest.json"

Path to Vite manifest

devServerUrl

"http://localhost:5173"

Vite dev server URL

rootId

"app"

Root element ID for React mount

lang

"en"

HTML lang attribute

version

"1.0"

Inertia protocol version

head

""

Extra HTML for <head> (meta tags, fonts)

renderHtml

(built-in) Full custom HTML template function (page, assetTags) => string

  1. Define page endpoints using api.raw

// frontend/pages.ts import { api } from "encore.dev/api"; import { inertia } from "./inertia-setup"; import Home from "./src/pages/Home"; import About from "./src/pages/About";

export const home = api.raw( { expose: true, method: "GET", path: "/" }, async (req, res) => { inertia.render(req, res, Home, { greeting: "Hello!" }); }, );

export const about = api.raw( { expose: true, method: "GET", path: "/about" }, async (req, res) => { inertia.render(req, res, About); // no props needed }, );

Key rules:

  • Pass the component function (not a string name) — props are type-checked against the component

  • Props are required when the component expects them, optional when it doesn't

  • Use Encore api.raw endpoints — the adapter reads req /res directly

  1. Create page components

// frontend/src/pages/Home.tsx import { Link } from "@inertiajs/react";

interface HomeProps { greeting: string; }

export default function Home({ greeting }: HomeProps) { return ( <div> <h1>{greeting}</h1> <Link href="/about">About</Link> </div> ); }

Components are default-exported React functions. The adapter resolves them by component.name , so use named function exports (not arrow functions assigned to variables).

  1. Shared data

Use share() for request-scoped props merged into every page response:

export const home = api.raw( { expose: true, method: "GET", path: "/" }, async (req, res) => { inertia.share(req, { user: { name: "Alice" } }); inertia.share(req, { flash: { success: "Welcome!" } }); inertia.render(req, res, Home, { greeting: "Hello!" }); // final props = { user: ..., flash: ..., greeting: "Hello!" } }, );

  • Call share() before render() — accumulates across calls

  • Page-level props override shared props

  • Scoped to the request (no leaking between requests)

  1. Serve static assets

// frontend/static.ts import { api } from "encore.dev/api";

export const assets = api.static({ expose: true, path: "/assets/*path", dir: "./dist/assets", });

  1. Create the static assets directory

Encore requires the api.static directory to exist at startup. Before running encore run for the first time, create it:

mkdir -p frontend/dist/assets

After that, npm run build (Vite) will populate it automatically.

Client Setup

  1. Mount the React app

// frontend/src/app.tsx import { mountInertiaApp } from "encore-inertia/react";

mountInertiaApp({ pages: import.meta.glob("./pages/**/*.tsx", { eager: true }), });

mountInertiaApp resolves page components by matching the component name against the glob keys. The rootId option (default "app" ) must match the server adapter's rootId .

  1. Vite config

// vite.config.ts import { defineConfig } from "vite"; import react from "@vitejs/plugin-react";

export default defineConfig({ plugins: [react()], build: { manifest: true, outDir: "frontend/dist", rollupOptions: { input: "frontend/src/app.tsx", // must match adapter's viteEntry }, }, server: { origin: "http://localhost:5173", cors: { origin: "http://localhost:4000" }, }, });

Critical: rollupOptions.input must match the viteEntry passed to createInertiaAdapter .

  1. Custom HTML template

For full control over the HTML shell, provide a renderHtml function. When set, it overrides title , lang , head , and rootId :

const inertia = createInertiaAdapter({ viteEntry: "frontend/src/app.tsx", renderHtml: (page, assetTags) => &#x3C;!DOCTYPE html> &#x3C;html> &#x3C;head> &#x3C;meta charset="utf-8"> ${assetTags} &#x3C;/head> &#x3C;body> &#x3C;div id="app" data-page='${JSON.stringify(page)}'>&#x3C;/div> &#x3C;/body> &#x3C;/html>, });

  • page — the Inertia page object ({ component, props, url, version } )

  • assetTags — pre-built <script> and <link> tags from the Vite manifest

Running

Add scripts to package.json :

{ "scripts": { "build": "vite build", "dev:frontend": "vite dev" } }

The "build": "vite build" script is required for deploying to Encore Cloud — Encore runs npm run build during deployment to compile the frontend assets.

Development (two terminals):

encore run # Terminal 1: Encore backend npm run dev:frontend # Terminal 2: Vite dev server with HMR

The adapter automatically falls back to the Vite dev server when no production manifest is found.

Production:

npm run build # Build frontend assets encore run # Start Encore

How It Works

  • A browser request hits an Encore raw endpoint

  • The endpoint calls inertia.render(req, res, Component, { props })

  • First visit (no X-Inertia header): responds with a full HTML page containing Vite asset tags and the page object in a data-page attribute

  • Subsequent navigation (X-Inertia header present): responds with just the JSON page object — the Inertia client swaps the component without a full reload

Project Structure

my-app/ encore.app package.json vite.config.ts frontend/ encore.service.ts # Encore service definition inertia-setup.ts # createInertiaAdapter config pages.ts # api.raw endpoints calling inertia.render() static.ts # api.static for built assets src/ app.tsx # mountInertiaApp client entry pages/ Home.tsx # React page components About.tsx dist/ # Vite build output (gitignored)

Common Mistakes

Mistake Fix

viteEntry doesn't match rollupOptions.input

Both must be the same path string

Passing a string to render() instead of a component Import the React component and pass it directly

Using api() instead of api.raw()

Inertia needs raw HTTP access — always use api.raw

Forgetting manifest: true in Vite config Required for production asset resolution

rootId mismatch between server and client Both default to "app" — only change if you set it in both places

Calling share() after render()

share() must be called before render()

api.static dir doesn't exist on first run Run mkdir -p frontend/dist/assets before encore run

Peer Dependencies

{ "react": ">=18", "react-dom": ">=18", "@inertiajs/react": ">=2" }

The React/Inertia deps are optional — only needed when using the encore-inertia/react client export.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

openclaw-version-monitor

监控 OpenClaw GitHub 版本更新,获取最新版本发布说明,翻译成中文, 并推送到 Telegram 和 Feishu。用于:(1) 定时检查版本更新 (2) 推送版本更新通知 (3) 生成中文版发布说明

Archived SourceRecently Updated
Coding

ask-claude

Delegate a task to Claude Code CLI and immediately report the result back in chat. Supports persistent sessions with full context memory. Safe execution: no data exfiltration, no external calls, file operations confined to workspace. Use when the user asks to run Claude, delegate a coding task, continue a previous Claude session, or any task benefiting from Claude Code's tools (file editing, code analysis, bash, etc.).

Archived SourceRecently Updated
Coding

ai-dating

This skill enables dating and matchmaking workflows. Use it when a user asks to make friends, find a partner, run matchmaking, or provide dating preferences/profile updates. The skill should execute `dating-cli` commands to complete profile setup, task creation/update, match checking, contact reveal, and review.

Archived SourceRecently Updated
Coding

clawhub-rate-limited-publisher

Queue and publish local skills to ClawHub with a strict 5-per-hour cap using the local clawhub CLI and host scheduler.

Archived SourceRecently Updated