FormHostProvider
FormHostProvider is a component you implement in your own application. It acts as the bridge between Buildocs UI Engine and your backend — routing form events through your API and supplying an auth token at runtime.
Every Buildocs UI Engine integration requires a FormHostProvider. Without it, the form has no way to make API calls or communicate with your application.
How it works
Inside FormHostProvider you:
- Fetch an auth token from your backend on mount
- Call
useBuildocsApi(yourBackendUrl, token)to get pre-wired HTTP methods - Build a
HostBridgeobject — mapping each form event to an API call - Render
BuildocsHostProviderwith the bridge around your children
The form calls the HostBridge methods internally. You decide how each one is handled.
Boilerplate
Copy this into your project as a starting point.
import React, { useEffect, useState } from 'react';
import {
type TLoadForm,
type HostBridge,
type RunEventArgs,
type UploadArgs,
ChunkRequestArgs,
DeleteFileEventArgs,
DownloadFileEventArgs,
FileMetaEventArgs,
GetLinkedFileMetaEventArgs,
BuildocsHostProvider,
useBuildocsApi,
useViewport,
} from '@buildocsdev/sdk';
interface FormHostProviderProps {
readonly children: React.ReactNode;
}
export function FormHostProvider({ children }: FormHostProviderProps) {
const { isMobileDevice, width, height } = useViewport();
const [token, setToken] = useState<string | undefined>(undefined);
const buildocsApi = useBuildocsApi();
const myApiUrl = 'https://your-backend.com/api/v1/formspublic';
const myApi = useBuildocsApi(myApiUrl, token);
useEffect(() => {
fetch(`${myApiUrl}/token`, { method: 'POST' })
.then(r => r.json())
.then((d: { token: string }) => setToken(d.token))
.catch(e => console.error('Failed to fetch token:', e));
}, []);
const hostBridge: HostBridge = {
viewPort: { isMobileDevice, width, height },
runFormEvent: async (args: RunEventArgs) => {
return await myApi.runEvent(args, '/runevent');
},
runFormUploadFiles: async (args: UploadArgs) => {
return await myApi.uploadFiles(args, '/uploadfiles');
},
runFormDeleteFileEvent: async (args: DeleteFileEventArgs) => {
return await myApi.deleteFile(args, '/deletefile');
},
runFormDownloadFileEvent: async (args: DownloadFileEventArgs) => {
return await myApi.downloadFile(args, '/downloadfile');
},
runFormGetLinkedFileEvent: async (args: GetLinkedFileMetaEventArgs) => {
return await myApi.getLinkedFile(args, '/getlinkedfile');
},
runFormGetLinkedFileMetaEvent: async (args: GetLinkedFileMetaEventArgs) => {
return await myApi.getLinkedFileMetaEvent(args, '/getlinkedfilemeta');
},
runFormGetLinkedFileByChunks: async (args: ChunkRequestArgs) => {
return await myApi.getLinkedFileByChunks(args, '/getlinkedfilebychunks');
},
runFormGetPresignedUrl: async (args: FileMetaEventArgs) => {
return await myApi.getPresignedUrl(args, '/getpresignedurl');
},
runLoadFormEvent: async (args: TLoadForm) => {
return await buildocsApi.fetchFormDefinitionWithMeta(args.formCode);
},
};
return (
<BuildocsHostProvider hostBridge={hostBridge}>
{children}
</BuildocsHostProvider>
);
}
useBuildocsApi
useBuildocsApi returns pre-configured HTTP methods. It takes an optional backend URL and auth token.
// Form definition — calls Buildocs directly
const buildocsApi = useBuildocsApi();
// Form events — calls your backend with token auth
const myApi = useBuildocsApi('https://your-backend.com/api/v1/formspublic', token);
The token is passed as a Bearer token in the Authorization header of every request made through myApi.
Custom path per method
Each method accepts a customPath as its second argument. The final URL is baseUrl + customPath.
// POST https://your-backend.com/api/v1/formspublic/runevent
return await myApi.runEvent(args, '/runevent');
HostBridge methods
Each method in HostBridge must have a corresponding endpoint implemented in your own backend. The paths shown below are the ones used in the boilerplate — you can change them to match your own API structure.
| HostBridge method | buildocsApi method | Default path |
|---|---|---|
runFormEvent | runEvent | /runevent |
runFormUploadFiles | uploadFiles | /uploadfiles |
runFormDeleteFileEvent | deleteFile | /deletefile |
runFormDownloadFileEvent | downloadFile | /downloadfile |
runFormGetLinkedFileEvent | getLinkedFile | /getlinkedfile |
runFormGetLinkedFileMetaEvent | getLinkedFileMetaEvent | /getlinkedfilemeta |
runFormGetLinkedFileByChunks | getLinkedFileByChunks | /getlinkedfilebychunks |
runFormGetPresignedUrl | getPresignedUrl | /getpresignedurl |
runLoadFormEvent | fetchFormDefinitionWithMeta | — (direct to Buildocs) |
Customization patterns
Pre-populate form data on load
Pass existing data to fetchFormDefinitionWithMeta — fields will be pre-filled when the form opens. Each key must match the Name of a field in the Form Builder exactly.
runLoadFormEvent: async (args: TLoadForm) => {
const existingData = await myDb.getRecord(args.guid);
return await buildocsApi.fetchFormDefinitionWithMeta(args.formCode, existingData);
},
Intercept events before sending
Add logging, validation, or extra headers before the API call.
runFormEvent: async (args: RunEventArgs) => {
console.log('Form event fired:', args.widgetName, args.widgetEvent);
return await myApi.runEvent(args, '/runevent');
},
Replace a method entirely
Skip useBuildocsApi and call your backend directly using fetch or Axios.
runFormEvent: async (args: RunEventArgs) => {
const response = await fetch('/my-api/run-event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(args),
});
return response.json();
},