Skip to content
58 changes: 57 additions & 1 deletion 16/umbraco-forms/developer/extending/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
# Extending

Umbraco Forms functionality can be extended in different ways. In this section we focus on techniques available to a back-end/C# developer.
Umbraco Forms functionality can be extended in different ways.

For front-end extensions, specifically via theming, see the [Themes](../themes.md) section.

## Extending the Backoffice
Umbraco Forms publishes an NPM package called `@umbraco-forms/backoffice` that holds typings and other niceties to build extensions.

{% hint style="warning" %}
Ensure that you install the version of the Backoffice package that is compatible with your Umbraco Forms installation. You can find the appropriate version on the [`@umbraco-forms/backoffice` npm page](https://www.npmjs.com/package/@umbraco-forms/backoffice).
{% endhint %}

You can install this package by running the command:

```bash
npm install -D @umbraco-forms/[email protected]
```

This will add a package to your devDependencies containing the TypeScript definitions for Umbraco Forms.

### TSConfig

Make sure to configure your TypeScript compiler so it includes the Global Types from the package. This enables you to utilize the declared Extension Types. If your project uses other Packages that provide their Extension Types, list those as well.

In your `tsconfig.json` file, add the array `types` inside `compilerOptions`, with the entry of `@umbraco-forms/backoffice`:

```json
{
"compilerOptions": {
...
"types": [
...
"@umbraco-forms/backoffice"
]
}
}
```

### Take extra care when using Vite

It is important that this namespace is ignored in your bundler. If you are using Vite, you can add the following to your `vite.config.ts` file:

```ts
import { defineConfig } from "vite";

export default defineConfig({
// other config
// ...
// add this to your config
build: {
rollupOptions: {
external: [/^@umbraco/],
},
}
});
```

This ensures that the Umbraco Backoffice packages are not bundled with your package.

Read more about using Vite with Umbraco in the [Vite Package Setup](../../../umbraco-cms/customizing/development-flow/vite-package-setup.md) article.

## Developing Custom Providers

Although the Forms package comes with many fields, workflows and other built-in types, you can still create and develop your own if needed.
Expand Down
43 changes: 29 additions & 14 deletions 16/umbraco-forms/developer/extending/adding-a-fieldtype.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ With Forms 14+, aspects of the presentation and functionality of the custom fiel

To create custom backoffice components for Umbraco 14, it's recommended to use a front-end build setup using Vite, TypeScript, and Lit. For more information, see the [Extension with Vite, TypeScript, and Lit](https://app.gitbook.com/s/G1Byxw7XfiZAj8zDMCTD/tutorials/creating-your-first-extension#extension-with-vite-typescript-and-lit) article.

The examples here are using the `@umbraco-forms/backoffice` package to get access to Forms-specific types and contexts. It is recommended to install this package as a development dependency in your project.

{% hint style="warning" %}
Ensure that you install the version of the Backoffice package that is compatible with your Umbraco Forms installation. You can find the appropriate version on the [`@umbraco-forms/backoffice` npm page](https://www.npmjs.com/package/@umbraco-forms/backoffice).
{% endhint %}

```bash
npm install -D @umbraco-forms/[email protected]
```

This will add a package to your devDependencies containing the TypeScript definitions for Umbraco Forms.

To display a name and description on a custom field, you need to register a JavaScript file as shown in the [Localization](https://app.gitbook.com/s/7MBVdnTbFiAgWuRsHpNS/customizing/extending-overview/extension-types/localization) article.

### Field Preview
Expand Down Expand Up @@ -240,14 +252,14 @@ And it is registered via a manifest:
import MyFieldPreviewSliderElement from './slider-preview.element.js';

const sliderPreviewManifest = {
type: "formsFieldPreview",
alias: "My.FieldPreview.Slider",
name: "Forms UUI Slider Field Preview",
api: MyFieldPreviewSliderElement,
element: () => import('./slider-preview.element.js')
};

export const manifests = [sliderPreviewManifest];
type: "formsFieldPreview",
alias: "My.FieldPreview.Slider",
name: "Forms UUI Slider Field Preview",
api: MyFieldPreviewSliderElement,
element: () => import('./slider-preview.element.js')
};

export const manifests = [sliderPreviewManifest];
```

### Field Editor
Expand Down Expand Up @@ -403,20 +415,23 @@ The following code shows the structure for these converter elements.

```javascript
import type { UmbPropertyValueData } from "@umbraco-cms/backoffice/property";
import type { FormsSettingValueConverterApi, Setting } from "@umbraco-forms/backoffice";

export class SliderSettingValueConverter {

async getSettingValueForEditor(setting, alias: string, value: string) {
export class SliderSettingValueConverter
implements FormsSettingValueConverterApi {
async getSettingValueForEditor(setting: Setting, alias: string, value: string) {
return Promise.resolve(value);
}

async getSettingValueForPersistence(setting, valueData: UmbPropertyValueData) {
return Promise.resolve(valueData.value);
async getSettingValueForPersistence(setting: Setting, valueData: UmbPropertyValueData) {
return Promise.resolve(valueData.value?.toString() || "");
}

async getSettingPropertyConfig(setting, alias: string, values: UmbPropertyValueData[]) {
async getSettingPropertyConfig(setting: Setting, alias: string, values: UmbPropertyValueData[]) {
return Promise.resolve([]);
}

destroy(): void { }
}
```

Expand Down
58 changes: 57 additions & 1 deletion 17/umbraco-forms/developer/extending/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
# Extending

Umbraco Forms functionality can be extended in different ways. In this section we focus on techniques available to a back-end/C# developer.
Umbraco Forms functionality can be extended in different ways.

For front-end extensions, specifically via theming, see the [Themes](../themes.md) section.

## Extending the Backoffice
Umbraco Forms publishes an NPM package called `@umbraco-forms/backoffice` that holds typings and other niceties to build extensions.

{% hint style="warning" %}
Ensure that you install the version of the Backoffice package that is compatible with your Umbraco Forms installation. You can find the appropriate version on the [`@umbraco-forms/backoffice` npm page](https://www.npmjs.com/package/@umbraco-forms/backoffice).
{% endhint %}

You can install this package by running the command:

```bash
npm install -D @umbraco-forms/[email protected]
```

This will add a package to your devDependencies containing the TypeScript definitions for Umbraco Forms.

### TSConfig

Make sure to configure your TypeScript compiler so it includes the Global Types from the package. This enables you to utilize the declared Extension Types. If your project uses other Packages that provide their Extension Types, list those as well.

In your `tsconfig.json` file, add the array `types` inside `compilerOptions`, with the entry of `@umbraco-forms/backoffice`:

```json
{
"compilerOptions": {
...
"types": [
...
"@umbraco-forms/backoffice"
]
}
}
```

### Take extra care when using Vite

It is important that this namespace is ignored in your bundler. If you are using Vite, you can add the following to your `vite.config.ts` file:

```ts
import { defineConfig } from "vite";

export default defineConfig({
// other config
// ...
// add this to your config
build: {
rollupOptions: {
external: [/^@umbraco/],
},
}
});
```

This ensures that the Umbraco Backoffice packages are not bundled with your package.

Read more about using Vite with Umbraco in the [Vite Package Setup](../../../umbraco-cms/customizing/development-flow/vite-package-setup.md) article.

## Developing Custom Providers

Although the Forms package comes with many fields, workflows and other built-in types, you can still create and develop your own if needed.
Expand Down
55 changes: 33 additions & 22 deletions 17/umbraco-forms/developer/extending/adding-a-fieldtype.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ With Forms 14+, aspects of the presentation and functionality of the custom fiel

To create custom backoffice components for Umbraco 14, it's recommended to use a front-end build setup using Vite, TypeScript, and Lit. For more information, see the [Extension with Vite, TypeScript, and Lit](https://app.gitbook.com/s/G1Byxw7XfiZAj8zDMCTD/tutorials/creating-your-first-extension#extension-with-vite-typescript-and-lit) article.

The examples here are using the `@umbraco-forms/backoffice` package to get access to Forms-specific types and contexts. It is recommended to install this package as a development dependency in your project.

{% hint style="warning" %}
Ensure that you install the version of the Backoffice package that is compatible with your Umbraco Forms installation. You can find the appropriate version on the [`@umbraco-forms/backoffice` npm page](https://www.npmjs.com/package/@umbraco-forms/backoffice).
{% endhint %}

```bash
npm install -D @umbraco-forms/[email protected]
```

This will add a package to your devDependencies containing the TypeScript definitions for Umbraco Forms.

To display a name and description on a custom field, you need to register a JavaScript file as shown in the [Localization](https://app.gitbook.com/s/7MBVdnTbFiAgWuRsHpNS/customizing/extending-overview/extension-types/localization) article.

### Field Preview
Expand All @@ -181,29 +193,24 @@ The alias of the preview to use is defined on the field type via the `PreviewVie
A preview for our slider, representing the selected setting values could look as follows:

```javascript
import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
import {
LitElement,
css,
customElement,
html,
property,
} from "@umbraco-cms/backoffice/external/lit";
import { FormsFieldPreviewBaseElement } from "@umbraco-forms/backoffice";

const elementName = "my-field-preview-slider";

@customElement(elementName)
export class MyFieldPreviewSliderElement extends UmbElementMixin(LitElement) {
export class MyFieldPreviewSliderElement extends FormsFieldPreviewBaseElement {
@property()
settings = {};

@property({ type: Array })
prevalues = [];

getSettingValue(key: string) {
return this.settings[key];
}

render() {
return html`<div
style="background-color:${this.getSettingValue("BgColor")}"
Expand Down Expand Up @@ -238,16 +245,16 @@ And it is registered via a manifest:

```javascript
import MyFieldPreviewSliderElement from './slider-preview.element.js';
import { ManifestFormsFieldPreview } from '@umbraco-forms/backoffice';

const sliderPreviewManifest = {
type: "formsFieldPreview",
alias: "My.FieldPreview.Slider",
name: "Forms UUI Slider Field Preview",
api: MyFieldPreviewSliderElement,
element: () => import('./slider-preview.element.js')
};
const sliderPreviewManifest: ManifestFormsFieldPreview = {
type: "formsFieldPreview",
alias: "My.FieldPreview.Slider",
name: "Forms UUI Slider Field Preview",
element: MyFieldPreviewSliderElement
};

export const manifests = [sliderPreviewManifest];
export const manifests = [sliderPreviewManifest];
```

### Field Editor
Expand Down Expand Up @@ -403,29 +410,33 @@ The following code shows the structure for these converter elements.

```javascript
import type { UmbPropertyValueData } from "@umbraco-cms/backoffice/property";
import type { FormsSettingValueConverterApi, Setting } from "@umbraco-forms/backoffice";

export class SliderSettingValueConverter {

async getSettingValueForEditor(setting, alias: string, value: string) {
export class SliderSettingValueConverter
implements FormsSettingValueConverterApi {
async getSettingValueForEditor(setting: Setting, alias: string, value: string) {
return Promise.resolve(value);
}

async getSettingValueForPersistence(setting, valueData: UmbPropertyValueData) {
return Promise.resolve(valueData.value);
async getSettingValueForPersistence(setting: Setting, valueData: UmbPropertyValueData) {
return Promise.resolve(valueData.value?.toString() || "");
}

async getSettingPropertyConfig(setting, alias: string, values: UmbPropertyValueData[]) {
async getSettingPropertyConfig(setting: Setting, alias: string, values: UmbPropertyValueData[]) {
return Promise.resolve([]);
}

destroy(): void { }
}
```

It's registered as follows. The `propertyEditorUiAlias` matches with the property editor UI that requires the conversions.

```javascript
import { SliderSettingValueConverter } from "./slider-setting-value-converter.api";
import { ManifestFormsSettingValueConverterPreview } from "@umbraco-forms/backoffice";

const sliderValueConverterManifest = {
const sliderValueConverterManifest: ManifestFormsSettingValueConverterPreview = {
type: "formsSettingValueConverter",
alias: "My.SettingValueConverter.Slider",
name: "Slider Value Converter",
Expand Down
8 changes: 8 additions & 0 deletions 17/umbraco-forms/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ If you are upgrading to a new major version, you can find information about the

This section contains the release notes for Umbraco Forms 17 including all changes for this version.

### 17.0.0-rc2 (November 13th 2025)

* Update dependencies to 17.0.0-rc2

### 17.0.0-rc1 (October 30th 2025)

* Update dependencies to 17.0.0-rc1

## Legacy release notes

You can find the release notes for versions out of support in the [Legacy documentation on GitHub](https://github.com/umbraco/UmbracoDocs/blob/umbraco-eol-versions/12/umbraco-forms/release-notes.md) and [Umbraco Forms Package page](https://our.umbraco.com/packages/developer-tools/umbraco-forms/).