Apps

Module and runtime

module.ts, plugins, defineDesktopApp, configKey merge, and Tailwind registration.

src/module.ts

Since @owdproject/core 3.3.2: apps with a configKey should use defineDesktopModule instead of manual public.desktop assignment. See Migrate packages (3.3.2).
  • meta.name: stable module id (e.g. desktop-app-about).
  • meta.configKey: namespace on desktop.config.ts (e.g. terminalpublic.desktop.terminal). Required when using defineDesktopModule.
  • setup: register
    • addComponentsDir./runtime/components;
    • addPlugin./runtime/plugin;
    • registerTailwindPath (from @owdproject/core) so Tailwind scans your .vue/.ts.

Consumer config (configKey)

Import defineDesktopModule from @owdproject/core/runtime/utils/defineDesktopModule (not the root barrel):

import { createResolver, addComponentsDir, addPlugin } from '@nuxt/kit'
import { registerTailwindPath } from '@owdproject/kit-tailwind/kit/registerTailwindPath'
import { defineDesktopModule } from '@owdproject/core/kit/authoring'

export default defineDesktopModule({
  meta: { name: 'desktop-app-about', configKey: 'about' },
  defaults: { title: 'About', href: 'https://owdproject.org' },
  async setup(_options, nuxt) {
    const { resolve } = createResolver(import.meta.url)
    addComponentsDir({ path: resolve('./runtime/components') })
    addPlugin(resolve('./runtime/plugin'))
    registerTailwindPath(nuxt, resolve('./runtime/components/**/*.{vue,mjs,ts}'))
  },
})

Add types/desktop.d.ts augmenting DesktopConfig with your about shape.

Consumers override via desktop.config.ts:

export default defineDesktopConfig({
  theme: '@owdproject/theme-nova',
  apps: ['@owdproject/app-about'],
  about: {
    title: 'About (playground)',
    href: 'https://github.com/owdproject/app-about',
  },
})

In Vue, read useRuntimeConfig().public.desktop.about or useDesktopExtension('about') (auto-imported).

Resilience

During nuxt prepare or builds without a full desktop, runtimeConfig.public.desktop may be incomplete. Use optional chaining in Vue; do not assign public.desktop[configKey] manually in module.ts when using defineDesktopModule.

runtime/plugin.ts

Required for apps. desktop validate checks:

  • calls defineDesktopApp
  • sets name: 'desktop-<slug>-register' (for playground launch dependsOn)
  • guards with if (import.meta.server) return

Recommended pattern:

import { defineNuxtPlugin } from 'nuxt/app'
import { defineDesktopApp } from '@owdproject/core'
import config from './app.config'

export default defineNuxtPlugin({
  name: 'desktop-app-about-register',
  async setup() {
    if (import.meta.server) return
    await defineDesktopApp(config)
  },
})

defineDesktopApp registers the app with useApplicationManager. It must run on the client — the desktop shell is client-rendered (ssr: false).

Avoid the legacy app:created hook pattern; reference repos and the validator expect direct registration in plugin setup.

runtime/app.config.ts

Export an object compatible with ApplicationConfig:

  • id: stable string (often reverse-DNS like org.owdproject.myapp).
  • title, icon, category, singleton when needed.
  • windows: map of model → window config (async component, size, position).
  • entries: keys tied to commands.
  • commands: functions that receive the app controller and open windows / run actions.

Details: Windows and commands.

Tailwind

import { registerTailwindPath } from '@owdproject/kit-tailwind/kit/registerTailwindPath'

registerTailwindPath(nuxt, resolve('./runtime/components/**/*.{vue,mjs,ts}'))

The @owdproject/kit-tailwind package aggregates these paths and merges them during Nuxt boot into the Tailwind CSS configuration.