Locations
A custom integration enables you to extend the Uniform dashboard with custom user interfaces from a web application you build. This section describes the different locations in the Uniform dashboard where your custom integration can be included.
Install
When a custom integration is installed, it is helpful to show the Canvas administrator a description of the custom integration.
You are able to provide one or more paragraphs of text that is displayed to the Canvas administrator when the custom integration is assigned to a project.

This is not an interactive location. The information provided in this location is displayed to the user, but the user cannot change it.
Settings
Each custom integration has project-specific settings that might need to be configured. For example, an integration that creates a connection to a commerce system might enable a Uniform user to specify credentials for Uniform to use to communicate with the commerce system.
When a custom integration is added to a project, its settings are available as a new link in the left menu on the Settings section of the Uniform dashboard.

The user inteface displays the settings that are currently configured, and allows the user to make changes to those settings. You can implement this logic in your preferred framework.
The following describes the lifecycle of the settings page:
- Canvas injects your integration's user interface into the settings page using an iframe.
- Canvas user makes a change to the controls displayed in the iframe.
- This change is saved in memory. Custom logic from the integration handles this.
- Canvas user clicks the Save button.
- Changes that were previously saved in memory are saved to persistent storage. Uniform does this automatically.
The following code demonstrates the custom logic required to save a change to memory. This value can be used in the other location pages.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
export default function MyParameterConfig() {
const { value, setValue } = useUniformMeshLocation();
return (
<div>
<Input
id="api-key"
type="text"
value={value?.key}
onChange={(e) => setValue({ key: e.target.value })}
/>
</div>
);
}
Coming soon.
Canvas
Canvas locations allow you to define custom parameter types, and to provide a user interface for using these types. The following locations are supported.
Parameter configuration
Configuration happens when the parameter is added to a component definition. When a parameter is a simple value like text or a number, no additional options are necessary. But even a numeric type could have additional options, such as minimum and maximum values.
When you create a custom integration, you may want to allow the Canvas user who is adding the parameter to a component to be able to configure some additional settings. The parameter configuration location allows you to add form fields between the Type field and the OK button.

The following describes the lifecycle of the parameter configuration page:
- Canvas injects your integration's user interface into the parameter configuration page using an iframe.
- Canvas user makes a change to the controls displayed in the iframe.
- This change is saved in memory. Custom logic from the integration handles this.
- Canvas user clicks the OK button.
- Changes that were previously saved in memory are saved to persistent storage. Uniform does this automatically.
The following code demonstrates the custom logic required to save a change to memory. This value can be used in the parameter editing page to control the options presented to the editor.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
export default function MyParameterConfig() {
const { value, setValue } = useUniformMeshLocation();
return (
<div>
<Input
id="my-filter"
type="text"
value={value?.filter}
onChange={(e) => setValue({ filter: e.target.value })}
/>
</div>
);
}
Coming soon.
Parameter configuration validation
Your parameter configuration UI can participate in the parameter configuration
validation process by passing along optional validation information when calling
the setValue
function. The setValue
function accepts a second, optional, parameter with
the following shape:
{
isValid: boolean;
validationMessage: string;
}
When the isValid
property is false
, the value of the validationMessage
property
will be displayed in the parameter configuration validation results.
Setting the isValid
property to true
will remove any previous validation error
message that was provided and the validator will allow the configuration value to be saved.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
export default function MyParameterConfig() {
const { value, setValue } = useUniformMeshLocation();
return (
<div>
<Input
id="my-filter"
type="text"
value={value?.filter}
onChange={(e) =>
setValue(
{ filter: e.target.value },
{
isValid: false,
validationMessage: 'Parameter configuration is invalid',
}
)
}
/>
</div>
);
}
Coming soon.
You can also directly set a validation result without setting a configuration value. This is particularly useful on initial render of your configuration UI, when your configuration requires input from the user but no value has been set.
In this scenario, you can set your configuration as invalid by using the setValidationResult
function available via the useUniformMeshLocation
hook.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
import { useEffect } from 'react';
export default function MyParameterConfig() {
const { value, setValue, setValidationResult } = useUniformMeshLocation();
useEffect(() => {
// Note: `isValid` is an arbitrary function you could implement to determine
// if `value` is indeed valid and then proceed accordingly.
if (!isValid(value)) {
const runEffect = async () => {
await setValidationResult({
isValid: false,
validationMessage: 'Parameter configuration is required',
});
};
runEffect();
}
}, []);
return (
<div>
<Input
id="my-filter"
type="text"
value={value?.filter}
onChange={(e) =>
setValue(
{ filter: e.target.value },
{
isValid: false,
validationMessage: 'Parameter configuration is invalid',
}
)
}
/>
</div>
);
}
Coming soon.
Parameter editing
Editing happens when a Canvas user sets the value on a specific parameter on a specific component. If the parameter represents a product from a commerce system's product catalog, you might want to provide the Canvas user a visual representation of the product catalog to make it easier for the user to select the appropriate product.
The parameter editing location allows you to add form fields to the component parameters section.

The following describes the lifecycle of the parameter editing page:
- Canvas injects your integration's user interface into the parameter editing page using an iframe.
- Canvas user makes a change to the controls displayed in the iframe.
- This change is saved in memory. Custom logic from the integration handles this.
- Canvas user clicks the Save button.
- Changes that were previously saved in memory are saved to persistent storage. Uniform does this automatically.
The following code demonstrates the custom logic required to load the settings that were added in the parameter configuration page, use that value to control the user interface available to the editor, and then save a change to memory.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
export default function MyParameterEditing() {
const { value, setValue, metadata } = useUniformMeshLocation();
const filter = metadata?.parameterDefinition?.typeConfig?.filter;
if (filter) {
return (
<div>
<Input
id="input1"
type="text"
value={value?.filtered}
onChange={(e) => setValue({ filtered: e.target.value })}
/>
</div>
);
}
return (
<div>
<Input
id="input2"
type="text"
value={value?.unfiltered}
onChange={(e) => setValue({ unfiltered: e.target.value })}
/>
</div>
);
}
Coming soon.
Parameter editing validation
Your Canvas parameter editor can participate in the Canvas validation process
by passing along optional validation information when calling the setValue
function. The setValue
function accepts a second, optional, parameter with
the following shape:
{
isValid: boolean;
validationMessage: string;
}
When the isValid
property is false
, the value of the validationMessage
property
will be displayed in the Canvas validation results.
Setting the isValid
property to true
will remove any previous validation error
message that was provided and the Canvas validator will allow the parameter value to be saved.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
export default function MyParameterEditing() {
const { value, setValue, metadata } = useUniformMeshLocation();
const filter = metadata?.parameterDefinition?.typeConfig?.filter;
if (filter) {
return (
<div>
<Input
id="input1"
type="text"
value={value?.filtered}
onChange={(e) =>
setValue(
{ filtered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}
return (
<div>
<Input
id="input2"
type="text"
value={value?.unfiltered}
onChange={(e) =>
setValue(
{ unfiltered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}
Coming soon.
You can also directly set a validation result without setting a parameter editor value. This is particularly useful on initial render of your editor UI, when your editor UI requires input from the user but no value has been set.
In this scenario, you can set your parameter value as invalid by using the setValidationResult
function available via the useUniformMeshLocation
hook.
- React
- Vue
import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
export default function MyParameterEditing() {
const { value, setValue, metadata, setValidationResult } = useUniformMeshLocation();
useEffect(() => {
// Note: `isValid` is an arbitrary function you could implement to determine
// if `value` is indeed valid and then proceed accordingly.
if (!isValid(value)) {
const runEffect = async () => {
await setValidationResult({
isValid: false,
validationMessage: `Parameter value is invalid`,
});
};
runEffect();
}
}, []);
const filter = metadata?.parameterDefinition?.typeConfig?.filter;
if (filter) {
return (
<div>
<Input
id="input1"
type="text"
value={value?.filtered}
onChange={(e) =>
setValue(
{ filtered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}
return (
<div>
<Input
id="input2"
type="text"
value={value?.unfiltered}
onChange={(e) =>
setValue(
{ unfiltered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}
Coming soon.