nuxt

Nuxt module for Lunora — single-worker composition (mounts /_lunora/* into Nitro) plus reactive-loader server helpers


[![typescript-image][typescript-badge]][typescript-url] [![FSL-1.1-Apache-2.0 licence][license-badge]][license] [![npm version][npm-version-badge]][npm-version] [![npm downloads][npm-downloads-badge]][npm-downloads] [![PRs Welcome][prs-welcome-badge]][prs-welcome]
---

Daniel Bannert's open source work is supported by the community on GitHub Sponsors

--- A **Nuxt module** that runs Lunora and Nuxt as a **single Cloudflare Worker**. Instead of Lunora owning the Cloudflare worker entry (the two-worker split), it is mounted _inside_ Nitro: the module registers a server route at `/_lunora/**` that forwards every Lunora RPC, WebSocket upgrade, and admin request to your Lunora app in-process. One `wrangler.jsonc`, one deploy, a same-origin client. Part of the [Lunora](https://github.com/anolilab/lunora) framework — a type-safe, real-time backend on Cloudflare Workers + Durable Objects with a Vite-first DX. ## Install ```bash npm install @lunora/nuxt ``` ## Setup ```ts // nuxt.config.ts export default defineNuxtConfig({ modules: ["@lunora/nuxt"], nitro: { preset: "cloudflare_module" }, }); ``` Add `exports.cloudflare.ts` to the project root so the `ShardDO` Durable Object class is exported from the emitted worker entry: ```ts // exports.cloudflare.ts export { ShardDO } from "./lunora/server"; ``` `lunora/server.ts` is your built Lunora app (`defineApp().build()`) — its default export is the worker (a `fetch` entrypoint), and it re-exports `ShardDO`. The module aliases the `#lunora/app` virtual to it (configurable via the `lunora.appEntry` option, default `~/lunora/server`) and serves it at the `/_lunora/**` route (prefix configurable via `lunora.prefix`). ## Options | Option | Default | Description | | ---------- | ----------------- | --------------------------------------------------------- | | `appEntry` | `~/lunora/server` | Module specifier of the Lunora app entry (`#lunora/app`). | | `prefix` | `/_lunora` | URL prefix the Lunora realtime plane is mounted at. | ## How it works - **The route** (`addServerHandler` at `prefix/**`): reconstructs a Web `Request` from the H3 event, resolves the Cloudflare `env`/`ExecutionContext` off it (tolerating both `event.context.cloudflare` and `event.req.runtime.cloudflare`), and forwards to your app's `fetch`. A missing Cloudflare runtime answers a clear 500. - **`#lunora/app` alias**: points the route's worker import at your app entry, forwarded into the Nitro server bundle via `nuxt.options.alias`. - **`ShardDO`** rides to the worker entry through your root `exports.cloudflare.ts` (the `cloudflare_module` preset appends its exports). ## Verify before deploy Single-worker composition rides on two Nitro behaviours that vary across versions — verify them on your pinned toolchain: 1. **WebSocket upgrade pass-through.** The live feed needs Nitro to return your Lunora app's `101 Switching Protocols` response (carrying its Cloudflare `webSocket`) untouched. RPC (plain JSON) works regardless; if live subscriptions never connect while RPC does, Nitro is normalising the upgrade response and `/_lunora/ws` needs a deploy-boundary handoff instead of the H3 route return. 2. **`exports.cloudflare.ts` hook.** The `cloudflare_module` preset must append this file's exports onto the worker entry. If `wrangler deploy` fails with "ShardDO class not exported", your Nitro version may use a different hook (`nitro.cloudflare.additionalModules`, or a `rollupConfig` output export). The module `warn()`s when the file is missing but can't verify the hook fires. ## Server data-loading `@lunora/nuxt/server` re-exports the framework-neutral SSR helpers (`createServerClient`, `preloadQuery`, …) from `@lunora/client/ssr` for the reactive-loader handoff. Safe to import from a Nitro server route (no WebSocket, no browser globals). ## Feature flags `@lunora/nuxt` ships no flag composable — Nuxt _is_ Vue, so read `ctx.flags` server-side (a Nitro route, a function, or a reactive loader) and pass the resolved value down, or call `useFlag` / `useFlags` from [`@lunora/vue`](https://www.npmjs.com/package/@lunora/vue) directly in a component for live updates over the WebSocket. Requires [`@lunora/flags`](https://www.npmjs.com/package/@lunora/flags) wired in `lunora/flags.ts`. ```vue ``` ## Supported Node.js Versions Libraries in this ecosystem make the best effort to track [Node.js' release schedule](https://github.com/nodejs/release#release-schedule). Here's [a post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a). ## Contributing If you would like to help take a look at the [list of issues](https://github.com/anolilab/lunora/issues) and check our [Contributing](https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md) guidelines. > **Note:** please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. ## Credits - [Daniel Bannert](https://github.com/prisis) - [All Contributors](https://github.com/anolilab/lunora/graphs/contributors) ## Made with ❤️ at Anolilab This is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Anolilab](https://www.anolilab.com/open-source) is a Development and AI Studio. Contact us at [hello@anolilab.com](mailto:hello@anolilab.com) if you need any help with these technologies or just want to say hi! ## License The Lunora nuxt package is open-sourced software licensed under the [FSL-1.1-Apache-2.0][license]. [license-badge]: https://img.shields.io/badge/license-FSL--1.1--Apache--2.0-blue.svg?style=for-the-badge [license]: https://github.com/anolilab/lunora/blob/alpha/LICENSE.md [npm-version-badge]: https://img.shields.io/npm/v/@lunora/nuxt?style=for-the-badge [npm-version]: https://www.npmjs.com/package/@lunora/nuxt [npm-downloads-badge]: https://img.shields.io/npm/dm/@lunora/nuxt?style=for-the-badge [npm-downloads]: https://www.npmjs.com/package/@lunora/nuxt [prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge [prs-welcome]: https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md [typescript-badge]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript [typescript-url]: https://www.typescriptlang.org/