Skip to main content

useRuntimeManifest

useRuntimeManifest(appId, stubManifest?, options?) is the runtime manifest loader for v2 manifests. It fetches GET /apps/{appId}/api/manifest via @nextcloud/axios + generateUrl, validates the response against the v2 schema, and falls back to a stub on failure.

Import

import { useRuntimeManifest } from '@conduction/nextcloud-vue'

Signature

function useRuntimeManifest(
appId: string,
stubManifest?: object | null,
options?: { fetcher?: (url: string) => Promise<{ status: number, data: object }> },
): {
manifest: Ref<object | null>
isLoading: Ref<boolean>
validationErrors: Ref<string[] | null>
}
ParamTypeDescription
appIdstringNextcloud app ID. Used to build GET /apps/{appId}/api/manifest.
stubManifestobject | nullFallback manifest used on 404/error/validation failure. When omitted, manifest.value stays null on failure.
options.fetcherFunctionOverride the fetch function. Must resolve to { status, data }. Defaults to axios.get. Useful in tests.

Return shape

FieldTypeDescription
manifestRef<object | null>The validated manifest, or the stub if the fetch/validation failed.
isLoadingRef<boolean>true until the fetcher promise settles.
validationErrorsRef<string[] | null>Schema errors when validation failed; null on success.

Replace-not-merge

Unlike v1's deep-merge behaviour, v2 manifests are replaced wholesale. A successful 200 response with a valid body completely replaces the stub — no deep merge, no partial-update semantics. This keeps the runtime surface deterministic.

When does it fall back to the stub?

  1. The fetcher rejects (network error, CORS, etc.).
  2. The response is non-200 or has no data.
  3. The response body fails validateManifest() (schema mismatch).

In every case manifest.value becomes the stubManifest you passed. validationErrors is populated only in case (3).

Example

import { useRuntimeManifest } from '@conduction/nextcloud-vue'
import bundledManifest from './manifest.json'

const { manifest, isLoading, validationErrors } =
useRuntimeManifest('openconnector', bundledManifest)

watch(validationErrors, (errs) => {
if (errs?.length) {
console.warn('[manifest] backend response failed validation, using bundled fallback:', errs)
}
})

Spec

  • REQ-MVR-001 (manifest-v2-renderer)
  • ADR-036 Decision 8 — backend-merge replaces, doesn't merge