Nuxt Helper
The devframe/helpers/nuxt module wires a Nuxt-built SPA up as a devframe client. It's an integration helper, not a deployment adapter — it runs inside the Nuxt app that consumes your devtool, not as part of the CLI that serves it.
It handles the three things every Nuxt-powered standalone devtool needs to get right:
- Base-agnostic assets. Forces
app.baseURL: './'andvite.base: './'so the same production build works at/, at/tool/, and on any other deployment path without build-time URL rewriting. - Runtime RPC connection. Adds a client plugin that calls
connectDevtool()once on page load and provides the result as$rpcon the Nuxt app. - TypeScript augmentation.
useNuxtApp().$rpcis typed asDevToolsRpcClientout of the box.
Install
export default defineNuxtConfig({
modules: ['devframe/helpers/nuxt'],
})That's it for the zero-config path. The module sets sane defaults for app.baseURL and vite.base, registers the client plugin, and exposes devframe/baseURL on useRuntimeConfig().public.
Using $rpc
<script setup>
const { $rpc } = useNuxtApp()
const payload = await $rpc.call('my-tool:get-payload')
</script>Or from a composable:
export function usePayload() {
const { $rpc } = useNuxtApp()
return useAsyncData('payload', () => $rpc.call('my-tool:get-payload'))
}Options
export default defineNuxtConfig({
modules: ['devframe/helpers/nuxt'],
devframe: {
baseURL: './', // where the devframe snapshot lives, relative to the page
skipAppDefaults: false, // opt out of the app.baseURL / vite.base defaults
},
})baseURLdefaults to'./', which resolves againstdocument.baseURIat runtime. The connection meta and dump shards sit next toindex.html, so the same build works at any deployment path — no need to pass--baseat build time.skipAppDefaults: truedisables theapp.baseURL: './'/vite.base: './'defaults. Use this only if you're deliberately shipping with absolute asset paths and have your own base-URL story.
How it works
At build time the module:
- Sets
nuxt.options.app.baseURLto'./'(unless already set) - Sets
nuxt.options.vite.baseto'./'(unless already set) - Merges
{ devframe: { baseURL } }intoruntimeConfig.public - Injects a client-only plugin (
helpers/nuxt/runtime/plugin.client) that:tsconst rpc = await connectDevtool({ baseURL: config.public.devframe.baseURL }) return { provide: { rpc } }
At runtime the built SPA fetches ./.connection.json (resolved against document.baseURI) and branches on the backend field — websocket in dev, static from a createBuild snapshot.
Relationship to createCli
The Nuxt helper is a client-side integration; it does not start a server. The typical shape is:
my-tool/
├── bin.mjs # createCli(devtool).parse()
├── src/
│ ├── cli.ts # defineDevtool + setup(ctx) { ctx.rpc.register(...) }
│ └── app/ # Nuxt SPA — uses `devframe/helpers/nuxt`
└── dist/
├── cli.mjs # bundled Node entry
└── public/ # Nuxt build output, pointed at by cli.distDircreateCli(fromdevframe/adapters/cli) runs the Node side — HTTP + WS + static build + MCP.devframe/helpers/nuxthandles the client side — RPC connection + base-URL plumbing.
They're decoupled: swap Nuxt for any other SPA framework as long as it calls connectDevtool() in the browser.
See also
- Standalone CLI recipe — end-to-end walk-through
- Client —
connectDevtoolreference - Adapters — CLI / Vite / Build / SPA / Kit / Embedded / MCP