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 }>,
mergeStrategy?: 'replace' | 'delta',
},
): {
manifest: Ref<object | null>
isLoading: Ref<boolean>
validationErrors: Ref<string[] | null>
orphanedDeltaPaths: Ref<string[]>
}
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.
options.mergeStrategy'replace' | 'delta'How to combine the fetched payload with the stub. Default 'replace' fully replaces the stub (unchanged). 'delta' treats the payload as a keyed structural delta applied to the stub base via mergeManifestDelta; orphaned patches surface on orphanedDeltaPaths.

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.
orphanedDeltaPathsRef<string[]>In delta mode, paths of delta entries that targeted a missing base entry and were skipped; [] otherwise.

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