Skip to main content

Remote API

import {
loadRemoteForm,
parseFormDefinition,
parseRemoteFormPayload,
RemoteSchemaValidationError,
} from "formwright/remote";

The remote package provides a typed validation boundary for backend-provided schemas.

RemoteFormPayload

interface RemoteFormPayload {
version: "1.0";
form: FormDefinition;
initialValues?: Record<string, unknown>;
meta?: {
schemaId?: string;
schemaVersion?: string;
etag?: string;
source?: string;
};
}

Use it as the transport contract between backend and frontend.

parseFormDefinition(input)

Validates a raw value and returns a typed FormDefinition.

const form = parseFormDefinition(rawFormJson);

The parser checks:

  • version
  • formId
  • dataSchema.fields
  • uiSchema.layout
  • field references inside layout nodes
  • behaviorSchema structure

Throws RemoteSchemaValidationError on invalid input.

parseRemoteFormPayload(input)

Validates the full remote payload:

const payload = parseRemoteFormPayload(rawPayload);

This validates:

  • payload version
  • form
  • optional initialValues
  • optional meta

Use this when your app already has the payload in memory and you only need validation.

loadRemoteForm(options)

Fetches JSON and validates it as RemoteFormPayload.

const payload = await loadRemoteForm({
url: "/api/forms/profile",
});

Options

OptionTypeDescription
urlstringRequest URL
fetchertypeof fetchOptional custom fetch implementation
headersHeadersInitAdditional request headers
initRequestInitStandard fetch options

Example with auth headers:

const payload = await loadRemoteForm({
url: "/api/forms/profile",
headers: {
Authorization: `Bearer ${token}`,
},
});

Example with abort support:

const payload = await loadRemoteForm({
url: "/api/forms/profile",
init: {
signal,
},
});

RemoteSchemaValidationError

Thrown when a remote payload or form definition fails validation.

try {
const payload = parseRemoteFormPayload(rawPayload);
} catch (error) {
if (error instanceof RemoteSchemaValidationError) {
console.error(error.issues);
}
}

Shape

interface RemoteSchemaIssue {
path: string;
message: string;
}

Each issue points to the failing path so backend/frontend teams can debug payload mismatches quickly.

  • Use loadRemoteForm() for REST
  • Use parseRemoteFormPayload() for RPC, GraphQL, or server-rendered payloads
  • Pass the validated payload.form into createFormRuntime()

See Remote Schemas for end-to-end integration examples.