> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hotglue.com/llms.txt
> Use this file to discover all available pages before exploring further.

# setCredentialsValidator

> Run custom validation before widget v3 submits connector credentials.

The `setCredentialsValidator` handler returned by `useHotglue` registers custom validation for credential forms in **Widget v3** before the widget sends a link or relink request.

## Types

```typescript theme={null}
type CredentialsFormValidationResult =
  | { success: true }
  | { success: false; errorMessage: string };

type CredentialsValidator<TConfig> = (
  oldConfig: TConfig | undefined,
  newConfig: TConfig,
  availableEntity: Record<string, unknown>,
  flowId: string,
  tenantId?: string
) =>
  | CredentialsFormValidationResult
  | Promise<CredentialsFormValidationResult>;

setCredentialsValidator<TConfig>(
  validator: CredentialsValidator<TConfig>
): void;
```

The generic passed to `setCredentialsValidator<TConfig>()` types both `oldConfig` and `newConfig` in the validator.

## Parameters

* `oldConfig`: The connector configuration already saved for the tenant. This is `undefined` when there is no existing config yet.
* `newConfig`: The values the user just entered in the widget form.
* `availableEntity`: The selected source, target, or connector metadata for the current link flow. This is provided as context.
* `flowId`: The flow being linked or relinked. This is provided as context.
* `tenantId`: The tenant id for the current session, when available. This is provided as context.

## Behavior

* Return `{ success: true }` when the credentials are valid.
* Return `{ success: false, errorMessage: string }` when the credentials are invalid. The widget stops submission and shows the message in the form.
* You can return the result directly or asynchronously from a promise.

## React Example

```ts theme={null}
const { setCredentialsValidator } = useHotglue({
  tenantId,
  environmentId,
  apiKey,
});

setCredentialsValidator<{ api_key: string }>(async (
  oldConfig,
  newConfig,
  availableEntity,
  flowId,
  tenantId,
) => {
  if (!newConfig.api_key) {
    return {
      success: false,
      errorMessage: 'API key is required',
    };
  }

  return { success: true };
});
```
