+
+The documentation for Umbraco CMS provides information for experienced Umbraco and .NET developers. It also offers guides and high-level articles for people starting out with the CMS.
+
+{% content-ref url="tutorials/creating-a-basic-website/" %}
+[creating-a-basic-website](tutorials/creating-a-basic-website/)
+{% endcontent-ref %}
+
+{% content-ref url="reference/configuration/" %}
+[configuration](reference/configuration/)
+{% endcontent-ref %}
+
+{% content-ref url="fundamentals/setup/requirements.md" %}
+[requirements.md](fundamentals/setup/requirements.md)
+{% endcontent-ref %}
+
+{% content-ref url="reference/notifications/" %}
+[notifications](reference/notifications/)
+{% endcontent-ref %}
+
+***
+
+{% include ".gitbook/includes/umbraco-fundamentals-training-course.md" %}
+
diff --git a/16/umbraco-cms/SUMMARY.md b/16/umbraco-cms/SUMMARY.md
new file mode 100644
index 00000000000..af4a95a927e
--- /dev/null
+++ b/16/umbraco-cms/SUMMARY.md
@@ -0,0 +1,506 @@
+# Table of contents
+
+* [Umbraco CMS Documentation](README.md)
+* [Release Candidate Guide](release-candidate-guide.md)
+* [Legacy Documentation](legacy-documentation/README.md)
+ * [Our Umbraco](https://our.umbraco.com/documentation/)
+ * [GitHub](https://github.com/umbraco/UmbracoDocs/tree/umbraco-eol-versions)
+* [Release Notes](https://our.umbraco.com/download/releases/)
+* [Contribute](https://docs.umbraco.com/welcome/contribute/)
+* [Sustainability Best Practices](https://docs.umbraco.com/sustainability-best-practices/)
+
+## Fundamentals
+
+* [Get to know Umbraco](fundamentals/get-to-know-umbraco.md)
+* [Setup](fundamentals/setup/README.md)
+ * [Requirements](fundamentals/setup/requirements.md)
+ * [Installation](fundamentals/setup/install/README.md)
+ * [Install using .NET CLI](fundamentals/setup/install/install-umbraco-with-templates.md)
+ * [Running Umbraco in Docker using Docker Compose](fundamentals/setup/install/running-umbraco-on-docker-locally.md)
+ * [Install using Visual Studio](fundamentals/setup/install/visual-studio.md)
+ * [Local IIS With Umbraco](fundamentals/setup/install/iis.md)
+ * [Install using Visual Studio Code](fundamentals/setup/install/install-umbraco-with-vs-code.md)
+ * [Installing Nightly Builds](fundamentals/setup/install/installing-nightly-builds.md)
+ * [Running Umbraco on Linux/macOS](fundamentals/setup/install/running-umbraco-on-linux-macos.md)
+ * [Unattended Installs](fundamentals/setup/install/unattended-install.md)
+ * [Upgrade your project](fundamentals/setup/upgrading/README.md)
+ * [Version Specific Upgrades](fundamentals/setup/upgrading/version-specific/README.md)
+ * [Upgrade from Umbraco 8 to the latest version](fundamentals/setup/upgrading/version-specific/upgrade-from-8-to-latest.md)
+ * [Migrate content to Umbraco 15](fundamentals/setup/upgrading/version-specific/migrate-content-to-umbraco-15.md)
+ * [Migrate content to Umbraco 8](fundamentals/setup/upgrading/version-specific/migrate-content-to-umbraco-8.md)
+ * [Minor upgrades for Umbraco 8](fundamentals/setup/upgrading/version-specific/minor-upgrades-for-umbraco-8.md)
+ * [Upgrade to Umbraco 7](fundamentals/setup/upgrading/version-specific/upgrade-to-umbraco-7.md)
+ * [Minor upgrades for Umbraco 7](fundamentals/setup/upgrading/version-specific/minor-upgrades-for-umbraco-7.md)
+ * [Server setup](fundamentals/setup/server-setup/README.md)
+ * [Running Umbraco On Azure Web Apps](fundamentals/setup/server-setup/azure-web-apps.md)
+ * [Hosting Umbraco in IIS](fundamentals/setup/server-setup/iis.md)
+ * [File And Folder Permissions](fundamentals/setup/server-setup/permissions.md)
+ * [Runtime Modes](fundamentals/setup/server-setup/runtime-modes.md)
+ * [Umbraco in Load Balanced Environments](fundamentals/setup/server-setup/load-balancing/README.md)
+ * [Load Balancing Azure Web Apps](fundamentals/setup/server-setup/load-balancing/azure-web-apps.md)
+ * [Standalone File System](fundamentals/setup/server-setup/load-balancing/file-system-replication.md)
+ * [Advanced Techniques With Flexible Load Balancing](fundamentals/setup/server-setup/load-balancing/flexible-advanced.md)
+ * [Logging With Load Balancing](fundamentals/setup/server-setup/load-balancing/logging.md)
+* [Backoffice](fundamentals/backoffice/README.md)
+ * [Sections](fundamentals/backoffice/sections.md)
+ * [Property Editors](fundamentals/backoffice/property-editors/README.md)
+ * [Built-in Property Editors](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/README.md)
+ * [Checkbox List](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/checkbox-list.md)
+ * [Collection](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/collection.md)
+ * [Color Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/color-picker.md)
+ * [Content Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/content-picker.md)
+ * [Document Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/document-picker.md)
+ * [DateTime](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time.md)
+ * [Date](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date.md)
+ * [Decimal](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/decimal.md)
+ * [Email Address](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/email-address.md)
+ * [Eye Dropper Color Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/eye-dropper-color-picker.md)
+ * [File Upload](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/file-upload.md)
+ * [Image Cropper](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md)
+ * [Label](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/label.md)
+ * [Markdown Editor](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/markdown-editor.md)
+ * [Media Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/media-picker-3.md)
+ * [Member Group Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-group-picker.md)
+ * [Member Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-picker.md)
+ * [Multi Url Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multi-url-picker.md)
+ * [Repeatable Textstrings](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multiple-textbox.md)
+ * [Numeric](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/numeric.md)
+ * [Radiobutton List](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/radiobutton-list.md)
+ * [Slider](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/slider.md)
+ * [Tags](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/tags.md)
+ * [Textarea](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textarea.md)
+ * [Textbox](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textbox.md)
+ * [Toggle](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/true-false.md)
+ * [User Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/user-picker.md)
+ * [Block Editors](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/README.md)
+ * [Block Grid](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-grid-editor.md)
+ * [Block List](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-list-editor.md)
+ * [Block Level Variance](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-level-variance.md)
+ * [Dropdown](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/dropdown/README.md)
+ * [Rich Text Editor](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/README.md)
+ * [Configuration](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/configuration.md)
+ * [Extensions](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/extensions.md)
+ * [Blocks](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/blocks.md)
+ * [Change Rich Text Editor UI](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/change-rich-text-editor-ui.md)
+ * [Rich Text Editor TinyMce](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/README.md)
+ * [Configuration](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/configuration.md)
+ * [Styles](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/styles.md)
+ * [Plugins](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/plugins.md)
+ * [Blocks](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/blocks.md)
+ * [Login](fundamentals/backoffice/login.md)
+ * [Document Blueprints](fundamentals/backoffice/document-blueprints.md)
+ * [Sidebar](fundamentals/backoffice/sidebar.md)
+ * [Log Viewer](fundamentals/backoffice/logviewer.md)
+ * [Language Variants](fundamentals/backoffice/variants.md)
+ * [Settings Dashboards](fundamentals/backoffice/settings-dashboards.md)
+* [Data](fundamentals/data/README.md)
+ * [Defining Content](fundamentals/data/defining-content/README.md)
+ * [Default Document Types](fundamentals/data/defining-content/default-document-types.md)
+ * [Document Type Localization](fundamentals/data/defining-content/document-type-localization.md)
+ * [Creating Media](fundamentals/data/creating-media/README.md)
+ * [Default Data/Media Types](fundamentals/data/creating-media/default-media-types.md)
+ * [Members](fundamentals/data/members.md)
+ * [Data Types](fundamentals/data/data-types/README.md)
+ * [Default Data Types](fundamentals/data/data-types/default-data-types.md)
+ * [Scheduled Publishing](fundamentals/data/scheduled-publishing.md)
+ * [Using Tabs](fundamentals/data/adding-tabs.md)
+ * [Users](fundamentals/data/users/README.md)
+ * [API Users](fundamentals/data/users/api-users.md)
+ * [Relations](fundamentals/data/relations.md)
+ * [Dictionary Items](fundamentals/data/dictionary-items.md)
+ * [Content Version Cleanup](fundamentals/data/content-version-cleanup.md)
+* [Design](fundamentals/design/README.md)
+ * [Templates](fundamentals/design/templates/README.md)
+ * [Basic Razor Syntax](fundamentals/design/templates/basic-razor-syntax.md)
+ * [Razor Cheatsheet](fundamentals/design/templates/razor-cheatsheet.md)
+ * [Rendering Content](fundamentals/design/rendering-content.md)
+ * [Rendering Media](fundamentals/design/rendering-media.md)
+ * [Partial Views](fundamentals/design/partial-views.md)
+ * [Stylesheets And JavaScript](fundamentals/design/stylesheets-javascript.md)
+* [Code](fundamentals/code/README.md)
+ * [Service APIs](fundamentals/code/umbraco-services.md)
+ * [Subscribing To Notifications](fundamentals/code/subscribing-to-notifications.md)
+ * [Creating Forms](fundamentals/code/creating-forms.md)
+ * [Debugging](fundamentals/code/debugging/README.md)
+ * [Logging](fundamentals/code/debugging/logging.md)
+ * [Source Control](fundamentals/code/source-control.md)
+
+## Implementation
+
+* [Learn how Umbraco works](implementation/learn-how-umbraco-works.md)
+* [Routing](implementation/default-routing/README.md)
+ * [Controller & Action Selection](implementation/default-routing/controller-selection.md)
+ * [Execute Request](implementation/default-routing/execute-request.md)
+ * [Request Pipeline](implementation/default-routing/inbound-pipeline.md)
+* [Custom Routing](implementation/custom-routing/README.md)
+ * [Adding a hub with SignalR and Umbraco](implementation/custom-routing/signalR.md)
+* [Controllers](implementation/controllers.md)
+* [Data Persistence (CRUD)](implementation/data-persistence.md)
+* [Composing](implementation/composing.md)
+* [Integration Testing](implementation/integration-testing.md)
+* [Nullable Reference Types](implementation/nullable-reference-types.md)
+* [Services and Helpers](implementation/services/README.md)
+ * [Circular Dependencies](implementation/services/circular-dependencies.md)
+* [Unit Testing](implementation/unit-testing.md)
+
+## Customizing
+
+* [Extend and customize the editing experience](customizing/overview.md)
+* [Project Bellissima](customizing/project-bellissima.md)
+* [Setup Your Development Environment](customizing/development-flow/README.md)
+ * [TypeScript setup](customizing/development-flow/typescript-setup.md)
+ * [Vite Package Setup](customizing/development-flow/vite-package-setup.md)
+* [Extension Overview](customizing/extending-overview/README.md)
+ * [Extension Registry](customizing/extending-overview/extension-registry/README.md)
+ * [Extension Registration](customizing/extending-overview/extension-registry/extension-registry.md)
+ * [Extension Manifest](customizing/extending-overview/extension-registry/extension-manifest.md)
+ * [Replace, Exclude or Unregister](customizing/extending-overview/extension-registry/replace-exclude-or-unregister.md)
+ * [Extension Types](customizing/extending-overview/extension-types/README.md)
+ * [Sections](customizing/extending-overview/extension-types/sections/README.md)
+ * [Sections](customizing/extending-overview/extension-types/sections/section.md)
+ * [Section Sidebar](customizing/extending-overview/extension-types/sections/section-sidebar.md)
+ * [Section View](customizing/extending-overview/extension-types/sections/section-view.md)
+ * [Workspaces](customizing/extending-overview/extension-types/workspaces/README.md)
+ * [Workspace Actions](customizing/extending-overview/extension-types/workspaces/workspace-editor-actions.md)
+ * [Workspace Context](customizing/extending-overview/extension-types/workspaces/workspace-context.md)
+ * [Workspace Views](customizing/extending-overview/extension-types/workspaces/workspace-views.md)
+ * [Route Registration](customizing/extending-overview/extension-types/modals/route-registration.md)
+ * [Menu](customizing/extending-overview/extension-types/menu.md)
+ * [Header Apps](customizing/extending-overview/extension-types/header-apps.md)
+ * [Icons](customizing/extending-overview/extension-types/icons.md)
+ * [Block Custom View](customizing/extending-overview/extension-types/block-custom-view.md)
+ * [Bundle](customizing/extending-overview/extension-types/bundle.md)
+ * [Kind](customizing/extending-overview/extension-types/kind.md)
+ * [App Entry Point](customizing/extending-overview/extension-types/app-entry-point.md)
+ * [Backoffice Entry Point](customizing/extending-overview/extension-types/backoffice-entry-point.md)
+ * [Extension Conditions](customizing/extending-overview/extension-types/condition.md)
+ * [Dashboards](customizing/extending-overview/extension-types/dashboard.md)
+ * [Entity Actions](customizing/extending-overview/extension-types/entity-actions.md)
+ * [Entity Bulk Actions](customizing/extending-overview/extension-types/entity-bulk-actions.md)
+ * [Entity Create Option Action](customizing/extending-overview/extension-types/entity-create-option-action.md)
+ * [Property Value Preset](customizing/extending-overview/extension-types/property-value-preset.md)
+ * [Trees](customizing/extending-overview/extension-types/tree.md)
+ * [Global Context](customizing/extending-overview/extension-types/global-context.md)
+ * [Localization](customizing/extending-overview/extension-types/localization.md)
+ * [Modals](customizing/extending-overview/extension-types/modals/README.md)
+ * [Confirm Dialog](customizing/extending-overview/extension-types/modals/confirm-dialog.md)
+ * [Custom Modals](customizing/extending-overview/extension-types/modals/custom-modals.md)
+ * [Extension Kind](customizing/extending-overview/extension-kind.md)
+ * [Extension Conditions](customizing/extending-overview/extension-conditions.md)
+ * [Custom Extension types](customizing/extending-overview/custom-extension-type.md)
+* [Foundation](customizing/foundation/README.md)
+ * [Working with Data](customizing/foundation/working-with-data/README.md)
+ * [Repositories](customizing/foundation/working-with-data/repositories.md)
+ * [Context API](customizing/foundation/working-with-data/context-api.md)
+ * [Store](customizing/foundation/working-with-data/store.md)
+ * [States](customizing/foundation/working-with-data/states.md)
+ * [Contexts](customizing/foundation/contexts/README.md)
+ * [Property Dataset Context](customizing/foundation/contexts/property-dataset-context.md)
+ * [Umbraco Element](customizing/foundation/umbraco-element/README.md)
+ * [Controllers](customizing/foundation/umbraco-element/controllers/README.md)
+ * [Write your own controller](customizing/foundation/umbraco-element/controllers/write-your-own-controller.md)
+ * [Sorting](customizing/foundation/sorting.md)
+ * [Routes](customizing/foundation/routes.md)
+ * [Icons](customizing/foundation/icons.md)
+ * [Backoffice Localization](customizing/foundation/localization.md)
+ * [Terminology](customizing/foundation/terminology.md)
+* [Sections & Trees](customizing/section-trees.md)
+* [Searchable Trees (ISearchableTree)](customizing/searchable-trees.md)
+* [Property Editors](customizing/property-editors/README.md)
+ * [Property Editors Composition](customizing/property-editors/composition/README.md)
+ * [Property Editor Schema](customizing/property-editors/composition/property-editor-schema.md)
+ * [Property Editor UI](customizing/property-editors/composition/property-editor-ui.md)
+ * [Property Value Converters](customizing/property-editors/property-value-converters.md)
+ * [Property Actions](customizing/property-editors/property-actions.md)
+ * [Integrate Property Editors](customizing/property-editors/integrate-property-editors.md)
+ * [Tracking References](customizing/property-editors/tracking.md)
+ * [Content Picker Value Converter Example](customizing/property-editors/full-examples-value-converters.md)
+ * [Property Dataset](customizing/property-editors/property-dataset.md)
+ * [Integrate Validation](customizing/property-editors/integrate-validation.md)
+* [Workspaces](customizing/workspaces.md)
+* [Umbraco Package](customizing/umbraco-package.md)
+* [UI Library](customizing/ui-library.md)
+
+## Extending
+
+* [Build on Umbraco functionality](extending/build-on-umbraco-functionality.md)
+* [Health Check](extending/health-check/README.md)
+ * [Health Check Guides](extending/health-check/guides/README.md)
+ * [Click-Jacking Protection](extending/health-check/guides/clickjackingprotection.md)
+ * [Content Content Security Policy (CSP)](extending/health-check/guides/contentsecuritypolicy.md)
+ * [Content/MIME Sniffing Protection](extending/health-check/guides/contentsniffingprotection.md)
+ * [Cross-site scripting Protection (X-XSS-Protection header)](extending/health-check/guides/crosssitescriptingprotection.md)
+ * [Debug Compilation Mode](extending/health-check/guides/debugcompilationmode.md)
+ * [Excessive Headers](extending/health-check/guides/excessiveheaders.md)
+ * [Fixed Application Url](extending/health-check/guides/fixedapplicationurl.md)
+ * [Folder & File Permissions](extending/health-check/guides/folderandfilepermissions.md)
+ * [HTTPS Configuration](extending/health-check/guides/httpsconfiguration.md)
+ * [Notification Email Settings](extending/health-check/guides/notificationemail.md)
+ * [SMTP](extending/health-check/guides/smtp.md)
+ * [Strict-Transport-Security Header](extending/health-check/guides/stricttransportsecurityheader.md)
+* [Language Files & Localization](extending/language-files/README.md)
+ * [.NET Localization](extending/language-files/net-localization.md)
+* [Backoffice Search](extending/backoffice-search.md)
+* [Creating a Custom Database Table](extending/database.md)
+* [Creating a Custom Seed Key Provider](extending/creating-custom-seed-key-provider.md)
+* [Embedded Media Providers](extending/embedded-media-providers.md)
+* [Custom File Systems (IFileSystem)](extending/filesystemproviders/README.md)
+ * [Using Azure Blob Storage for Media and ImageSharp Cache](extending/filesystemproviders/azure-blob-storage.md)
+* [Configuring Azure Key Vault](extending/key-vault.md)
+* [Packages](extending/packages/README.md)
+ * [Creating a Package](extending/packages/creating-a-package.md)
+ * [Language file for packages](extending/packages/language-files-for-packages.md)
+ * [Listing a Package on the Umbraco Marketplace](extending/packages/listing-on-marketplace.md)
+ * [Good practice and defaults](extending/packages/good-practice-and-defaults.md)
+ * [Packages on Umbraco Cloud](extending/packages/packages-on-umbraco-cloud.md)
+ * [Installing and Uninstalling Packages](extending/packages/installing-and-uninstalling-packages.md)
+ * [Maintaining packages](extending/packages/maintaining-packages.md)
+ * [Create accessible Umbraco packages](extending/packages/accessibility.md)
+ * [Example Package Repository](extending/packages/example-package-repository.md)
+
+## Reference
+
+* [Dive into the code](reference/dive-into-the-code.md)
+* [Configuration](reference/configuration/README.md)
+ * [Basic Authentication Settings](reference/configuration/basicauthsettings.md)
+ * [Connection strings settings](reference/configuration/connectionstringssettings.md)
+ * [Content Dashboard Settings](reference/configuration/contentdashboard.md)
+ * [Content Settings](reference/configuration/contentsettings.md)
+ * [Data Types Settings](reference/configuration/datatypes.md)
+ * [Debug settings](reference/configuration/debugsettings.md)
+ * [Examine settings](reference/configuration/examinesettings.md)
+ * [Exception filter settings](reference/configuration/exceptionfiltersettings.md)
+ * [FileSystemProviders Configuration](reference/configuration/filesystemproviders.md)
+ * [Global Settings](reference/configuration/globalsettings.md)
+ * [Health checks](reference/configuration/healthchecks.md)
+ * [Hosting settings](reference/configuration/hostingsettings.md)
+ * [Imaging settings](reference/configuration/imagingsettings.md)
+ * [Indexing settings](reference/configuration/indexingsettings.md)
+ * [Install Default Data Settings](reference/configuration/installdefaultdatasettings.md)
+ * [Logging settings](reference/configuration/loggingsettings.md)
+ * [Maximum Upload Size Settings](reference/configuration/maximumuploadsizesettings.md)
+ * [Models builder settings](reference/configuration/modelsbuildersettings.md)
+ * [Cache Settings](reference/configuration/cache-settings.md)
+ * [Package Migration](reference/configuration/packagemigrationsettings.md)
+ * [Plugins settings](reference/configuration/pluginssettings.md)
+ * [Request handler settings](reference/configuration/requesthandlersettings.md)
+ * [Runtime settings](reference/configuration/runtimesettings.md)
+ * [Security Settings](reference/configuration/securitysettings.md)
+ * [Serilog settings](reference/configuration/serilog.md)
+ * [Type finder settings](reference/configuration/typefindersettings.md)
+ * [Unattended](reference/configuration/unattendedsettings.md)
+ * [Web routing](reference/configuration/webroutingsettings.md)
+* [Templating](reference/templating/README.md)
+ * [Models Builder](reference/templating/modelsbuilder/README.md)
+ * [Introduction](reference/templating/modelsbuilder/introduction.md)
+ * [Configuration](reference/templating/modelsbuilder/configuration.md)
+ * [Builder Modes](reference/templating/modelsbuilder/builder-modes.md)
+ * [Understand and Extend](reference/templating/modelsbuilder/understand-and-extend.md)
+ * [Using Interfaces](reference/templating/modelsbuilder/using-interfaces.md)
+ * [Tips and Tricks](reference/templating/modelsbuilder/coolthingswithmodels.md)
+ * [Working with MVC](reference/templating/mvc/README.md)
+ * [Working with MVC Views in Umbraco](reference/templating/mvc/views.md)
+ * [View/Razor Examples](reference/templating/mvc/examples.md)
+ * [Using MVC Partial Views in Umbraco](reference/templating/mvc/partial-views.md)
+ * [Using View Components in Umbraco](reference/templating/mvc/viewcomponents.md)
+ * [Querying & Traversal](reference/templating/mvc/querying.md)
+ * [Creating Forms](reference/templating/mvc/forms.md)
+ * [Macros](reference/templating/macros.md)
+* [Querying & Models](reference/querying/README.md)
+ * [IMemberManager](reference/querying/imembermanager.md)
+ * [IPublishedContentQuery](reference/querying/ipublishedcontentquery.md)
+ * [ITagQuery](reference/querying/itagquery.md)
+ * [UDI Identifiers](reference/querying/udi-identifiers.md)
+ * [UmbracoContext helper](reference/querying/umbraco-context.md)
+ * [UmbracoHelper](reference/querying/umbracohelper.md)
+ * [IPublishedContent](reference/querying/ipublishedcontent/README.md)
+ * [IPublishedContent Collections](reference/querying/ipublishedcontent/collections.md)
+ * [IPublishedContent IsHelpers](reference/querying/ipublishedcontent/ishelpers.md)
+ * [IPublishedContent Property Access & Extension Methods](reference/querying/ipublishedcontent/properties.md)
+* [Routing & Controllers](reference/routing/README.md)
+ * [Custom MVC controllers (Umbraco Route Hijacking)](reference/routing/custom-controllers.md)
+ * [Custom MVC Routes](reference/routing/custom-routes.md)
+ * [Custom Middleware](reference/routing/custom-middleware.md)
+ * [URL Rewrites in Umbraco](reference/routing/iisrewriterules.md)
+ * [Special Property Type aliases for routing](reference/routing/routing-properties.md)
+ * [URL Redirect Management](reference/routing/url-tracking.md)
+ * [Routing in Umbraco](reference/routing/request-pipeline/README.md)
+ * [FindPublishedContentAndTemplate()](reference/routing/request-pipeline/find-publishedcontent-and-template.md)
+ * [IContentFinder](reference/routing/request-pipeline/icontentfinder.md)
+ * [Inbound request pipeline](reference/routing/request-pipeline/inbound-pipeline.md)
+ * [Outbound request pipeline](reference/routing/request-pipeline/outbound-pipeline.md)
+ * [Published Content Request Preparation](reference/routing/request-pipeline/published-content-request-preparation.md)
+ * [Surface controllers](reference/routing/surface-controllers/README.md)
+ * [Surface controller actions](reference/routing/surface-controllers/surface-controllers-actions.md)
+ * [Umbraco API Controllers](reference/routing/umbraco-api-controllers/README.md)
+ * [Porting old Umbraco API Controllers](reference/routing/umbraco-api-controllers/porting-old-umbraco-apis.md)
+* [Content Delivery API](reference/content-delivery-api/README.md)
+ * [Custom property editors support](reference/content-delivery-api/custom-property-editors-support.md)
+ * [Extension API for querying](reference/content-delivery-api/extension-api-for-querying.md)
+ * [Media Delivery API](reference/content-delivery-api/media-delivery-api.md)
+ * [Protected content in the Delivery API](reference/content-delivery-api/protected-content-in-the-delivery-api/README.md)
+ * [Server to server access](reference/content-delivery-api/protected-content-in-the-delivery-api/server-to-server-access.md)
+ * [Output caching](reference/content-delivery-api/output-caching.md)
+ * [Property expansion and limiting](reference/content-delivery-api/property-expansion-and-limiting.md)
+ * [Additional preview environments support](reference/content-delivery-api/additional-preview-environments-support.md)
+* [Webhooks](reference/webhooks/README.md)
+ * [Expanding Webhook Events](reference/webhooks/expanding-webhook-events.md)
+* [API versioning and OpenAPI](reference/api-versioning-and-openapi.md)
+* [Searching](reference/searching/README.md)
+ * [Examine](reference/searching/examine/README.md)
+ * [Examine Management](reference/searching/examine/examine-management.md)
+ * [Examine Manager](reference/searching/examine/examine-manager.md)
+ * [Custom indexing](reference/searching/examine/indexing.md)
+ * [PDF indexes and multisearchers](reference/searching/examine/pdfindex-multisearcher.md)
+ * [Quick-start](reference/searching/examine/quick-start.md)
+ * [Corrupt Indexes](reference/searching/examine/corrupt-indexes.md)
+* [Using Notifications](reference/notifications/README.md)
+ * [Notification Handler](reference/notifications/notification-handler.md)
+ * [CacheRefresher Notifications Example](reference/notifications/cacherefresher-notifications.md)
+ * [ContentService Notifications Example](reference/notifications/contentservice-notifications.md)
+ * [Creating And Publishing Notifications](reference/notifications/creating-and-publishing-notifications.md)
+ * [Determining if an entity is new](reference/notifications/determining-new-entity.md)
+ * [MediaService Notifications Example](reference/notifications/mediaservice-notifications.md)
+ * [MemberService Notifications Example](reference/notifications/memberservice-notifications.md)
+ * [Sending Allowed Children Notification](reference/notifications/sendingallowedchildrennotifications.md)
+ * [Umbraco Application Lifetime Notifications](reference/notifications/umbracoapplicationlifetime-notifications.md)
+ * [EditorModel Notifications](reference/notifications/editormodel-notifications/README.md)
+ * [Customizing the "Links" box](reference/notifications/editormodel-notifications/customizing-the-links-box.md)
+ * [Hot vs. cold restarts](reference/notifications/hot-vs-cold-restarts.md)
+* [Inversion of Control / Dependency injection](reference/using-ioc.md)
+* [Management](reference/management/README.md)
+ * [Using Umbraco services](reference/management/using-services/README.md)
+ * [Consent Service](reference/management/using-services/consentservice.md)
+ * [Media Service](reference/management/using-services/mediaservice.md)
+ * [Relation Service](reference/management/using-services/relationservice.md)
+ * [Content Service](reference/management/using-services/contentservice.md)
+ * [Content Type Service](reference/management/using-services/contenttypeservice.md)
+ * [Localization Service](reference/management/using-services/localizationservice.md)
+ * [User Service](reference/management/using-services/userservice.md)
+* [Plugins](reference/plugins/README.md)
+ * [Creating Resolvers](reference/plugins/creating-resolvers.md)
+ * [Finding types](reference/plugins/finding-types.md)
+* [Cache & Distributed Cache](reference/cache/README.md)
+ * [Cache Seeding](reference/cache/cache-seeding.md)
+ * [Accessing the cache](reference/cache/application-cache.md)
+ * [ICacheRefresher](reference/cache/icacherefresher.md)
+ * [IServerMessenger](reference/cache/iservermessenger.md)
+ * [Getting/Adding/Updating/Inserting Into Cache](reference/cache/updating-cache.md)
+ * [Examples](reference/cache/examples/README.md)
+ * [Working with caching](reference/cache/examples/tags.md)
+* [Response Caching](reference/response-caching.md)
+* [Security](reference/security/README.md)
+ * [API rate limiting](reference/security/api-rate-limiting.md)
+ * [BackOfficeUserManager and Events](reference/security/backofficeusermanager-and-notifications.md)
+ * [Cookies](reference/security/cookies.md)
+ * [Replacing the basic username/password check](reference/security/custom-password-check.md)
+ * [External login providers](reference/security/external-login-providers.md)
+ * [Locking of Users and password reset](reference/security/password-reset.md)
+ * [Reset admin password](reference/security/reset-admin-password.md)
+ * [Umbraco Security Hardening](reference/security/security-hardening.md)
+ * [Umbraco Security Settings](reference/security/security-settings.md)
+ * [Sensitive data](reference/security/sensitive-data-on-members.md)
+ * [Sanitizing the Rich Text Editor](reference/security/serverside-sanitizing.md)
+ * [Setup Umbraco for a FIPS Compliant Server](reference/security/setup-umbraco-for-a-fips-server.md)
+ * [HTTPS](reference/security/ssl-https.md)
+ * [Two-factor Authentication](reference/security/two-factor-authentication.md)
+ * [Server-side file validation](reference/security/serverside-file-validation.md)
+* [Scheduling](reference/scheduling.md)
+* [Common Pitfalls & Anti-Patterns](reference/common-pitfalls.md)
+* [API Documentation](reference/api-documentation.md)
+* [Debugging with SourceLink](reference/debugging.md)
+* [Language Variation](reference/language-variation.md)
+* [UmbracoMapper](reference/mapping.md)
+* [Distributed Locks](reference/distributed-locks.md)
+* [Management API](reference/management-api/README.md)
+ * [External Access](reference/management-api/external-access.md)
+ * [Setup OAuth using Postman](reference/management-api/postman-setup-swagger.md)
+* [Custom Swagger API](reference/custom-swagger-api.md)
+* [Umbraco Flavored Markdown](reference/umbraco-flavored-markdown.md)
+* [Content Type Filters](reference/content-type-filters.md)
+
+## Tutorials
+
+* [Overview](tutorials/overview.md)
+* [Creating a Basic Website](tutorials/creating-a-basic-website/README.md)
+ * [Getting Started](tutorials/creating-a-basic-website/getting-started.md)
+ * [Document Types](tutorials/creating-a-basic-website/document-types.md)
+ * [Creating Your First Template](tutorials/creating-a-basic-website/creating-your-first-template-and-content-node.md)
+ * [CSS and Images](tutorials/creating-a-basic-website/css-and-images.md)
+ * [Displaying the Document Type Properties](tutorials/creating-a-basic-website/displaying-the-document-type-properties.md)
+ * [Creating a Master Template](tutorials/creating-a-basic-website/creating-master-template-part-1.md)
+ * [Creating Pages and Using the Master Template](tutorials/creating-a-basic-website/creating-master-template-part-2.md)
+ * [Setting the Navigation Menu](tutorials/creating-a-basic-website/setting-the-navigation-menu.md)
+ * [Articles and Article Items](tutorials/creating-a-basic-website/article-parent-and-article-items.md)
+ * [Adding Language Variants](tutorials/creating-a-basic-website/adding-language-variants.md)
+ * [Conclusions](tutorials/creating-a-basic-website/conclusion.md)
+* [Creating your First Extension](tutorials/creating-your-first-extension.md)
+* [Creating a Custom Dashboard](tutorials/creating-a-custom-dashboard/README.md)
+ * [Adding localization to the dashboard](tutorials/creating-a-custom-dashboard/adding-localization-to-the-dashboard.md)
+ * [Adding functionality to the Dashboard](tutorials/creating-a-custom-dashboard/adding-functionality-to-the-dashboard.md)
+ * [Using Umbraco UI library in the Dashboard](tutorials/creating-a-custom-dashboard/extending-the-dashboard-using-umbraco-ui-library.md)
+* [Creating a Property Editor](tutorials/creating-a-property-editor/README.md)
+ * [Adding configuration to a Property Editor](tutorials/creating-a-property-editor/adding-configuration-to-a-property-editor.md)
+ * [Integrating context with a Property Editor](tutorials/creating-a-property-editor/integrating-context-with-a-property-editor.md)
+ * [Custom value conversion for rendering](tutorials/creating-a-property-editor/custom-value-conversion-for-rendering.md)
+ * [Adding server-side validation](tutorials/creating-a-property-editor/adding-server-side-validation.md)
+ * [Default Property Editor Schema aliases](tutorials/creating-a-property-editor/default-property-editor-schema-aliases.md)
+* [Creating a Multilingual Site](tutorials/multilanguage-setup.md)
+* [Add Google Authentication (Users)](tutorials/add-google-authentication.md)
+* [Add Microsoft Entra ID authentication (Members)](tutorials/add-microsoft-entra-id-authentication.md)
+* [Creating Custom Database Tables with Entity Framework](tutorials/getting-started-with-entity-framework-core.md)
+* [The Starter Kit](tutorials/starter-kit/README.md)
+ * [Lessons](tutorials/starter-kit/lessons/README.md)
+ * [Customize the Starter Kit](tutorials/starter-kit/lessons/1-customize-the-starter-kit.md)
+ * [Add a Blog Post Publication Date](tutorials/starter-kit/lessons/2-add-a-blog-post-publication-date/README.md)
+ * [Add a Blog Post Publication Date](tutorials/starter-kit/lessons/2-add-a-blog-post-publication-date/part-2.md)
+ * [Add a Blog Post Publication Date](tutorials/starter-kit/lessons/2-add-a-blog-post-publication-date/part-3.md)
+ * [Add Open Graph](tutorials/starter-kit/lessons/3-add-open-graph/README.md)
+ * [Add Open Graph - Step 1](tutorials/starter-kit/lessons/3-add-open-graph/step-1.md)
+ * [Add Open Graph - Step 2](tutorials/starter-kit/lessons/3-add-open-graph/step-2.md)
+ * [Add Open Graph - Step 3](tutorials/starter-kit/lessons/3-add-open-graph/step-3.md)
+ * [Add Open Graph - Step 4](tutorials/starter-kit/lessons/3-add-open-graph/step-4.md)
+ * [Add Open Graph - Summary](tutorials/starter-kit/lessons/3-add-open-graph/summary.md)
+ * [Ask For Help and Join the Community](tutorials/starter-kit/lessons/4-help-and-community.md)
+* [Editor's Manual](tutorials/editors-manual/README.md)
+ * [Getting Started](tutorials/editors-manual/getting-started-with-umbraco/README.md)
+ * [Logging In and Out](tutorials/editors-manual/getting-started-with-umbraco/logging-in-and-out.md)
+ * [Umbraco Interface](tutorials/editors-manual/getting-started-with-umbraco/umbraco-interface.md)
+ * [Creating, Saving and Publishing Content Options](tutorials/editors-manual/getting-started-with-umbraco/creating-saving-and-publishing-content.md)
+ * [Finding Content](tutorials/editors-manual/getting-started-with-umbraco/finding-content.md)
+ * [Editing Existing Content](tutorials/editors-manual/getting-started-with-umbraco/editing-existing-content.md)
+ * [Sorting Pages](tutorials/editors-manual/getting-started-with-umbraco/ordering-pages.md)
+ * [Moving a Page](tutorials/editors-manual/getting-started-with-umbraco/moving-a-page.md)
+ * [Copying a Page](tutorials/editors-manual/getting-started-with-umbraco/copying-a-page.md)
+ * [Deleting and Restoring Pages](tutorials/editors-manual/getting-started-with-umbraco/deleting-and-restoring-pages.md)
+ * [Working with Rich Text Editor](tutorials/editors-manual/working-with-content/README.md)
+ * [Version Management](tutorials/editors-manual/version-management/README.md)
+ * [Comparing Versions](tutorials/editors-manual/version-management/comparing-versions.md)
+ * [Rollback to a Previous Version](tutorials/editors-manual/version-management/rollback-to-a-previous-version.md)
+ * [Media Management](tutorials/editors-manual/media-management/README.md)
+ * [Working with Folders](tutorials/editors-manual/media-management/working-with-folders.md)
+ * [Working with Media Types](tutorials/editors-manual/media-management/working-with-images-and-files.md)
+ * [Cropping Images](tutorials/editors-manual/media-management/cropping-images.md)
+ * [Tips & Tricks](tutorials/editors-manual/tips-and-tricks/README.md)
+ * [Refreshing the Tree View](tutorials/editors-manual/tips-and-tricks/working-with-folders.md)
+ * [Audit Trail](tutorials/editors-manual/tips-and-tricks/audit-trail.md)
+ * [Notifications](tutorials/editors-manual/tips-and-tricks/notifications.md)
+ * [Preview Pane Responsive View](tutorials/editors-manual/tips-and-tricks/preview-pane-responsive-view.md)
+ * [Session Timeout](tutorials/editors-manual/tips-and-tricks/session-timeout.md)
+* [Multisite Setup](tutorials/multisite-setup.md)
+* [Member Registration and Login](tutorials/members-registration-and-login.md)
+* [Custom Views for Block List](tutorials/creating-custom-views-for-blocklist.md)
+* [Connecting Umbraco Forms and Zapier](tutorials/connecting-umbraco-forms-and-zapier.md)
+* [Creating an XML Sitemap](tutorials/creating-an-xml-site-map.md)
+* [Implement Custom Error Pages](tutorials/custom-error-page.md)
+* [Create a custom maintenance page](tutorials/create-a-custom-maintenance-page.md)
+* [Creating a backoffice API](tutorials/creating-a-backoffice-api/README.md)
+ * [Documenting your controllers](tutorials/creating-a-backoffice-api/documenting-your-controllers.md)
+ * [Adding a custom Swagger document](tutorials/creating-a-backoffice-api/adding-a-custom-swagger-document.md)
+ * [Versioning your API](tutorials/creating-a-backoffice-api/versioning-your-api.md)
+ * [Polymorphic output in the Management API](tutorials/creating-a-backoffice-api/polymorphic-output-in-the-management-api.md)
+ * [Umbraco schema and operation IDs](tutorials/creating-a-backoffice-api/umbraco-schema-and-operation-ids.md)
+ * [Access policies](tutorials/creating-a-backoffice-api/access-policies.md)
+* [Extending the Help Menu](tutorials/extending-the-help-menu.md)
+* [Downloadable content](tutorials/downloadable-content/README.md)
+ * [YouTube: Create a simple Umbraco Website](tutorials/downloadable-content/youtube-create-a-simple-umbraco-website.md)
diff --git a/16/umbraco-cms/customizing/development-flow/README.md b/16/umbraco-cms/customizing/development-flow/README.md
new file mode 100644
index 00000000000..4a3df0dc1fe
--- /dev/null
+++ b/16/umbraco-cms/customizing/development-flow/README.md
@@ -0,0 +1,105 @@
+---
+description: Learn about the recommended development environment to extend Umbraco
+---
+
+# Setup Your Development Environment
+
+This article will take you through setting up everything you need to start building extensions and packages for Umbraco.
+
+## Required Software
+
+Make sure you have followed the [requirements](../../fundamentals/setup/requirements.md) article, especially having installed the following on your machine:
+* [Node.js version 20.15.0 (LTS)](https://nodejs.org/en) and higher
+
+{% hint style="info" %}
+Use Node Version Manager (NVM) for [Windows](https://github.com/coreybutler/nvm-windows) or [Mac/Linux](https://github.com/nvm-sh/nvm) to manage the Node.js versions.
+{% endhint %}
+
+## Package Setup
+
+### App\_Plugins
+
+Extensions such as JavaScript, CSS, and manifests, will go into a folder called `App_Plugins`. If you do not have this folder, you can create it at the root of your Umbraco project.
+
+### Source Code
+
+The source code for your extensions should ideally be placed in a different project. You can make great use of a [Razor Class Library (RCL) with static assets](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-8.0\&tabs=visual-studio#create-an-rcl-with-static-assets) for this purpose. This will make it easier to maintain and test your code. You can create a new project in the root of your Umbraco project, or you can create a new project in a separate folder.
+
+### Bundling
+
+If you are using a bundler like Webpack or Vite, you can configure it to output its files to a folder that Umbraco can see. If you have put your files directly in Umbraco project, you need to copy the compiled files over to the `App_Plugins` folder.
+
+With a Razor Class Library (RCL) project, you should instead configure your bundler to copy the files over to the `wwwroot` folder. You can then map your RCL project back to the `App_Plugins` web path, so Umbraco can read your files. You can do this by setting the `StaticWebAssetBasePath` in your `csproj` file:
+
+{% code title="MyExtension.csproj" lineNumbers="true" %}
+```xml
+
+
+
+ App_Plugins/MyExtension
+
+
+
+```
+{% endcode %}
+
+### Dependencies
+
+You can use any package manager you like to install dependencies. We recommend using NPM or Yarn. You can install packages by running the command:
+
+```bash
+npm install -D
+```
+
+This will install the package and save it to your `package.json` file.
+
+You need to setup a `package.json` file if you don't have one already. You can do this by running the command:
+
+```bash
+npm init -y
+```
+
+{% hint style="warning" %}
+Make sure that you do not install any NPM dependencies directly into the `App_Plugins` folder. This can cause issues with Build and Publish processes in MSBuild. Always install dependencies in a separate folder and use a bundler to copy the compiled files over to the `App_Plugins` folder.
+{% endhint %}
+
+### Umbraco Backoffice
+
+Umbraco publishes an NPM package called `@umbraco-cms/backoffice` that holds typings and other niceties to build extensions.
+
+You can install this package by running the command:
+
+```bash
+npm install -D @umbraco-cms/backoffice
+```
+
+This will add a package to your devDependencies containing the TypeScript definitions for the Umbraco Backoffice.
+
+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 package is not bundled with your package.
+
+Read more about using Vite with Umbraco in the [Vite Package Setup](vite-package-setup.md) article.
+
+## Visual Studio Code
+
+If you're using Visual Studio Code we recommend the extension called [Lit-Plugin](https://marketplace.visualstudio.com/items?itemName=runem.lit-plugin) to get IntelliSense for Lit Elements and Umbraco UI Library Components.
+
+## What's Next?
+
+Now that you have your development environment set up, you can start building your Umbraco extensions. Read more about [our recommended setup with Vite](vite-package-setup.md) to get started.
diff --git a/16/umbraco-cms/customizing/development-flow/typescript-setup.md b/16/umbraco-cms/customizing/development-flow/typescript-setup.md
new file mode 100644
index 00000000000..3113b51d9bf
--- /dev/null
+++ b/16/umbraco-cms/customizing/development-flow/typescript-setup.md
@@ -0,0 +1,16 @@
+# TypeScript setup
+
+Make sure to configure your TypeScript compiler so it includes the Global Types from the Backoffice. This enables you to utilize the declared Extension Types. If your project is using other Packages that provides their Extension Types then please list these as well.
+
+In your `tsconfig.json` file. Add the array `types` inside `compilerOptions`, with the entry of `@umbraco-cms/backoffice/extension-types`:
+
+```json
+{
+ "compilerOptions": {
+ ...
+ "types": [
+ "@umbraco-cms/backoffice/extension-types"
+ ]
+ }
+}
+```
diff --git a/16/umbraco-cms/customizing/development-flow/vite-package-setup.md b/16/umbraco-cms/customizing/development-flow/vite-package-setup.md
new file mode 100644
index 00000000000..8c4097981a3
--- /dev/null
+++ b/16/umbraco-cms/customizing/development-flow/vite-package-setup.md
@@ -0,0 +1,223 @@
+---
+description: Get started with a Vite Package, setup with TypeScript and Lit
+---
+
+# Vite Package Setup
+
+Umbraco recommends building extensions with a setup using TypeScript and a build tool such as Vite. Umbraco uses the library Lit for building web components which we will use throughout this guide.
+
+{% hint style="info" %}
+This guide is based on our **general recommendations** for working with and building extensions for the Umbraco backoffice.
+
+You can use **any framework or library**, as you are not limited to the mentioned frameworks.
+{% endhint %}
+
+## Getting Started With Vite
+
+Vite comes with a set of good presets to get you quickly up and running with libraries and languages. For example: Lit, Svelte, and Vanilla Web Components with both JavaScript and TypeScript.
+
+{% hint style="info" %}
+Before following this guide, read the [Setup Your Development Environment](./) article.
+{% endhint %}
+
+1. Open a terminal and navigate to the project folder where you want to create your new Vite Package.
+2. Run the following command in the folder to create a new Vite Package:
+
+```bash
+npm create vite@latest
+```
+
+This command will set up your new package and ask you to pick a framework and a compiler.
+
+3. Enter `Client` as both the **Project Name** and **Package name** when prompted.
+
+4. Choose **Lit** and **TypeScript** as the framework and language.
+
+{% hint style="info" %}
+For this tutorial, it is recommended to use the names given above. However, feel free to choose other names if preferred.
+{% endhint %}
+
+
Create vite command choices
+
+This creates a new folder called `Client`, sets up our new project, and creates a `package.json` file, which includes the necessary packages. This is where all your source files live.
+
+{% hint style="info" %}
+Alternatively, you can skip the interactive prompts and use this command:
+
+```typescript
+npm create vite@latest Client -- --template lit-ts
+```
+
+This will create a Vite Package with Lit and TypeScript in a folder called **Client**.
+{% endhint %}
+
+5. Navigate to the **Client** project folder and install the required packages:
+
+```bash
+npm install
+```
+
+Before proceeding, ensure that you install the version of the Backoffice package compatible with your Umbraco installation. You can find the appropriate version on the [@umbraco-cms/backoffice npm page](https://www.npmjs.com/package/@umbraco-cms/backoffice).
+
+6. Install the Backoffice package using the following command:
+
+```bash
+npm install -D @umbraco-cms/backoffice
+```
+
+{% hint style="info" %}
+To avoid installing Umbraco’s sub-dependencies such as TinyMCE and Monaco Editor, you can add the `--legacy-peer-deps` flag:
+{% endhint %}
+
+ ```bash
+npm install --legacy-peer-deps -D @umbraco-cms/backoffice
+ ```
+
+Using this flag will disable Intellisense for external references.
+
+7. Open the `tsconfig.json` file.
+8. Add the array `types` inside `compilerOptions`, with the entry of `@umbraco-cms/backoffice/extension-types`:
+
+```json
+{
+ "compilerOptions": {
+ ...
+ "types": [
+ "@umbraco-cms/backoffice/extension-types"
+ ]
+ }
+}
+```
+
+9. Create a new file called `vite.config.ts` in the folder and insert the following code:
+
+{% code title="vite.config.ts" lineNumbers="true" %}
+```ts
+import { defineConfig } from "vite";
+
+export default defineConfig({
+ build: {
+ lib: {
+ entry: "src/my-element.ts", // your web component source file
+ formats: ["es"],
+ },
+ outDir: "../App_Plugins/Client", // all compiled files will be placed here
+ emptyOutDir: true,
+ sourcemap: true,
+ rollupOptions: {
+ external: [/^@umbraco/], // ignore the Umbraco Backoffice package in the build
+ },
+ },
+ base: "/App_Plugins/Client/", // the base path of the app in the browser (used for assets)
+});
+```
+{% endcode %}
+
+{% hint style="info" %}
+The `outDir` parameter specifies where the compiled files are placed. In this example, they are stored in the `App_Plugins/Client` folder. If you are working with a different structure, such as a Razor Class Library (RCL) project, update this path to `wwwroot`.
+{% endhint %}
+
+This alters the Vite default output into a **library mode**, where the output is a JavaScript file with the same name as the `name` attribute in `package.json`. The name is `client.js` if you followed this tutorial with no changes.
+
+The source code that is compiled lives in the `src` folder of your package folder and that is where you can see a `my-element.ts` file. You can confirm that this file is the one specified as our entry on the Vite config file that we recently created.
+
+{% hint style="info" %}
+The `build:lib:entry` parameter can accept an array which will allow you to export multiple files during the build. You can read more about [Vite's build options here](https://vitejs.dev/config/build-options.html#build-lib).
+{% endhint %}
+
+Build the `ts` file in the `Client` folder so we can use it in our package:
+
+```bash
+npm run build
+```
+
+## Watch for changes and build
+
+If you like to continuously work on the package and have each change built, you can add a `watch`script in your `package.json` with `vite build --watch`. The example below indicates where in the structure this change should be implemented:
+
+{% code title="package.json" lineNumbers="true" %}
+```json
+{
+ "name": "Client",
+ ...
+ "scripts": {
+ "watch": "vite build --watch"
+ ...
+ },
+ ...
+```
+{% endcode %}
+
+Then in the terminal, you can run `npm run watch`.
+
+## Umbraco Package declaration
+
+Declare your package to Umbraco via a file called `umbraco-package.json`. This should be added at the root of your package. In this guide, it is inside the `Client/public` folder so that Vite automatically copies it over every time it builds.
+
+This example declares a Dashboard as part of your Package, using the Vite example element.
+
+{% code title="Client/public/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My Dashboard",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "dashboard",
+ "alias": "My.Dashboard.MyExtension",
+ "name": "My Dashboard",
+ "element": "/App_Plugins/Client/client.js",
+ "elementName": "my-element",
+ "meta": {
+ "label": "My Dashboard",
+ "pathname": "my-dashboard"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+{% hint style="info" %}
+Umbraco needs the name of the element that will render as default when our dashboard loads.
+
+* This is specified in the **manifest** as the `elementName`.
+* Another approach would be to define your default element in the TS code. To do this, in the `src/my-element.ts` add **`default`** to your `MyElement` class in the file like so:
+
+```ts
+export default class MyElement extends LitElement {
+```
+{% endhint %}
+
+Learn more about the abilities of the manifest file in the [Umbraco Package Manifest](../umbraco-package.md) article.
+
+#### Testing your package
+
+To be able to test your package, you will need to run your site.
+
+Before you do this, you need to make sure to run `npm run build` to compile your TypeScript files and copy them to the `App_Plugins/Client` folder.
+
+{% hint style="warning" %}
+If you try to include some of these resources via Visual Studio (VS), then make sure not to include TypeScript files. Otherwise, VS will try to include a few lines on your `.csproj` file to compile the TypeScript code that exists in your project folder. When you run your website, VS will try to compile these files and fail.
+{% endhint %}
+
+The final result looks like this:
+
+
My dashboard
+
+Back in the `src/my-element.ts` file, you can update the `styles` property to make any styling changes. You can change the `background-color` of the `button` to white so it is more visible:
+
+```css
+button {
+ background-color: white;
+}
+```
+
+## Summary
+
+With this, you have set up your Package and created an Extension for the Backoffice.
+
+In more advanced cases, you can add more elements to your package and create more complex extensions. In that case, you can benefit greatly from creating another project in your solution to hold the files. This way, you can keep your solution clean and organized. We recommend creating a [Razor Class Library (RCL)](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-8.0\&tabs=visual-studio#create-an-rcl-with-static-assets) for this purpose. You can read more about this in the [Development Flow](./#source-code) article.
+
+This Dashboard appears in all sections and does not do much. To extend it to interact with the Umbraco Backoffice, follow the tutorial on [Creating Your First Extension](../../tutorials/creating-your-first-extension.md).
diff --git a/16/umbraco-cms/customizing/extending-overview/README.md b/16/umbraco-cms/customizing/extending-overview/README.md
new file mode 100644
index 00000000000..3182b6dcb57
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/README.md
@@ -0,0 +1,19 @@
+---
+description: Getting started with backoffice setup and configurations
+---
+
+# Extension Overview
+
+The Backoffice architecture is based on Extensions, making different parts of the UI extendable. Enabling you to append, replace, or remove parts.
+
+
+
+In this section you can find the common terms, concepts and guides used to extend the Umbraco backoffice.
+
+## [Extension Registry](extension-registry/)
+
+How to registere extensions or manipulate others.
+
+## [Extension Types](extension-types/)
+
+An overview of the different ways to append funcationtlity.
diff --git a/16/umbraco-cms/customizing/extending-overview/custom-extension-type.md b/16/umbraco-cms/customizing/extending-overview/custom-extension-type.md
new file mode 100644
index 00000000000..48284d67b25
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/custom-extension-type.md
@@ -0,0 +1,23 @@
+# Custom Extension Types
+
+The extension registry is an open system, which can hold any Extension Manifest Type. This article describes how you can declare your types.
+Types can be declared for re-useability/maintainability or to open up for other package extensions.
+
+## Manifest Type Declaration
+
+A Manifest Type is declared via a TypeScript Interface, like shown below:
+
+```typescript
+import type { ManifestBase } from '@umbraco-cms/backoffice/extension-api';
+
+export interface ManifestPreviewAppProvider extends ManifestBase {
+ type: 'myPrefixedExtensionType';
+}
+
+// Declare the Manifest Type in the global UmbExtensionManifestMap interface:
+declare global {
+ interface UmbExtensionManifestMap {
+ MyPrefixedExtensionManifest: MyExtensionManifestType;
+ }
+}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-conditions.md b/16/umbraco-cms/customizing/extending-overview/extension-conditions.md
new file mode 100644
index 00000000000..44037a0ad4c
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-conditions.md
@@ -0,0 +1,70 @@
+---
+description: Learn how to use Extension Conditions when working with the Umbraco backoffice.
+---
+
+# Extension Conditions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Extension Manifest Conditions enable you to declare requirements for an Extension before it becomes available.
+
+## Utilizing Conditions in your Manifest
+
+Conditions are referenced via their alias. The Declaration of a Condition is shown in the following example:
+
+```typescript
+const manifest = {
+ type: 'workspaceView',
+ ...
+ conditions: [
+ {
+ alias: 'Umb.Condition.WorkspaceAlias',
+ match: 'Umb.Workspace.Document',
+ },
+ ],
+};
+```
+
+By declaring a condition the extension will become available only once the condition is permitted.
+
+The example above requires the nearest Workspaces Alias to be equal to `'Umb.Workspace.Document'`.
+
+When declaring multiple conditions all of them must be permitted for the extension to be available.
+
+## Built-in conditions types
+
+The following conditions are available out of the box, for all extension types that support Conditions.
+
+* `Umb.Condition.Switch` - Toggles on and off based on the `frequency` set in seconds.
+* `Umb.Condition.MultipleAppLanguages` - Requires the app to have more than one language, such as a multi-language site.
+* `Umb.Condition.SectionAlias` - Requires the current Section Alias to match the one specified.
+* `Umb.Condition.MenuAlias` - Requires the current Menu Alias to match the one specified.
+* `Umb.Condition.WorkspaceAlias` - Requires the current Workspace Alias to match the one specified.
+* `Umb.Condition.WorkspaceEntityType` - Requires the current workspace to work on the given Entity Type. Examples: 'document', 'block' or 'user'.
+* `Umb.Condition.WorkspaceContentTypeAlias` - Requires the current workspace to be based on a Content Type which Alias matches the one specified.
+* `Umb.Condition.Workspace.ContentHasProperties` - Requires the Content Type of the current Workspace to have properties.
+* `Umb.Condition.WorkspaceHasCollection` - Requires the current Workspace to have a Collection.
+* `Umb.Condition.WorkspaceEntityIsNew` - Requires the current Workspace data to be new, not yet persisted on the server.
+* `Umb.Condition.EntityIsTrashed` - Requires the current entity to be trashed.
+* `Umb.Condition.EntityIsNotTrashed` - Requires the current entity to not be trashed.
+* `Umb.Condition.SectionUserPermission` - Requires the current user to have permissions to the given Section Alias.
+* `Umb.Condition.UserPermission.Document` - Requires the current user to have specific Document permissions. Example: 'Umb.Document.Save'.
+* `Umb.Condition.CurrentUser.GroupId` - Requires the current user to belong to a specific group by GUID. Accepts `match` (GUID), `oneOf` (array), `allOf` (array), and `noneOf` (array). Example: '8d2b3c4d-4f1f-4b1f-8e3d-4a6b7b8c4f1e'.
+* `Umb.Condition.CurrentUser.IsAdmin` - Requires the current user to be an admin as defined by the backend, for example, that they belong to the Administrator group.
+
+## Condition Configuration
+
+The conditions are defined as an array of condition configurations. Each entry can contain the following properties:
+
+* `alias`- The alias of the condition to utilize.
+* `...` - The rest of the properties of the object are specific to the condition configuration.
+
+## Learn more
+
+Learn about built-in conditions and how to create your own:
+
+{% content-ref url="extension-types/condition.md" %}
+Condition Extension Type
+{% endcontent-ref %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-kind.md b/16/umbraco-cms/customizing/extending-overview/extension-kind.md
new file mode 100644
index 00000000000..7d6b711c1c9
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-kind.md
@@ -0,0 +1,56 @@
+---
+description: Learn how to use the Kind extension in your manifest files when extending the Umbraco CMS backoffice.
+---
+
+# Extension Kind
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The **Extension Manifest Kind** is used to declare a preset configuration that other extensions can inherit. It ensures maintainability and consistency when creating extensions for the Umbraco CMS backoffice. By using a Kind, developers can reuse predefined settings, which reduces redundancy across extensions.
+
+When a Kind is applied, the extension's manifest inherits the fields defined in the Kind. This approach prevents the need to repeat configuration details across multiple extensions.
+
+## Manifest Kind Declaration
+
+A **Kind** is declared in the `kind` field of the manifest, which is part of the extension registration process. The declaration is linked to a specific extension type.
+
+```typescript
+const manifest = {
+ type: 'headerApp', // The type of the extension
+ kind: 'button', // The kind alias to inherit settings from
+ ...
+};
+```
+
+By setting the `kind` field, the extension automatically inherits all properties associated with that **Kind**. This is useful when you want to standardize a component (like a button) across multiple extensions.
+
+## Using the Kind for Inheritance
+
+A Kind not only defines the basic configuration but may also require additional metadata to fully configure the element or component.
+
+### Example: Using the Button Kind in a Header App
+
+```typescript
+const manifest = {
+ type: 'headerApp',
+ kind: 'button',
+ name: 'My Header App Example',
+ alias: 'My.HeaderApp.Example',
+ meta: {
+ label: 'My Example',
+ icon: 'icon-home',
+ href: '/some/path/to/open/when/clicked',
+ },
+};
+```
+
+In this example:
+
+- The `kind: 'button'` inherits all default settings from the **Button Kind**.
+- The `meta` object is added to configure additional properties, such as the button's label, icon, and the URL to open when clicked.
+
+The Kind allows you to extend existing functionality and tailor it to specific needs while maintaining consistency.
+
+For a deeper dive into Kind and how to create your own, see the [Kind](extension-types/kind.md) article.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-registry/README.md b/16/umbraco-cms/customizing/extending-overview/extension-registry/README.md
new file mode 100644
index 00000000000..0a2ce0548c2
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-registry/README.md
@@ -0,0 +1,19 @@
+# Extension Registry
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Extensions Registry is your entry to extend or customize the Backoffice. Therefor it is crucial to understand the abilities of the Extension Registry.
+
+## [Extension Registration](extension-registry.md)
+
+The extension registry is a global registry that can be accessed and changed at anytime while Backoffice is running.
+
+## [Extension Manifest](extension-manifest.md)
+
+Each Extension Manifest has to declare its type, this is used to determine where it hooks into the system. It also looks at what data is required to declare within it.
+
+## [Replace, Exclude or Unregistere](./#replace-exclude-or-unregistere)
+
+Once you understand how to declare your own, you may want to replace or remove existing.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md b/16/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md
new file mode 100644
index 00000000000..b6766690d09
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md
@@ -0,0 +1,137 @@
+---
+description: Learn about the different methods for declaring an Extension Manifest.
+---
+
+# Extension Manifest
+
+The Extension Manifest is the first step for any extension. It is the declaration of what you want to register.
+
+In this section you will find all the Extension Types provided by the Backoffice. [See all Extension Types here.](../extension-types/README.md)
+
+## Extension Manifest Format
+
+An Extension Manifest can be written as a JavaScript or JSON Object.
+
+There are a few general properties, the required set of properties consists of the `type`, `alias`, and `name`.
+
+```typescript
+const manifest = {
+ type: '...',
+ alias: 'my.customization',
+ name: 'My customization'
+ ...
+};
+```
+
+The `type` defines what it is declaring. The `alias` is a unique identifier for this manifest. It must be globally unique, so make sure to prefix it with something that makes your extension unique. The `name` is a representational name of this manifest, this does not need to be unique but such can be beneficial when debugging extensions.
+
+## Manifest Data
+
+Each Extension Manifest has to declare its type. This is used to determine where it hooks into the system. It also determines what data is required of this manifest.
+
+The abilities of the extensions rely on the specific extension type. The Type sets the scene for what the extension can do and what it needs to be utilized. Some extension types can be made purely via the manifest. Other requires files, like a JavaScript file containing a Web Component.
+
+The required fields of any extension manifest are:
+
+* `type` - The type defines the type and purpose of the extension. It is used to determine where the extension will be used and defines the data needed for this manifest.
+* `alias`- The alias is used to identify the extension. This has to be unique for each extension.
+* `name` - The name of the extension. This is used to identify the extension in the UI.
+
+Additionally, many extensions support the use of the following fields:
+
+* `weight` - Define a weight, to determine the importance or visual order of this extension. The higher the weight, the higher in the list it will appear.
+* `overwrites` - Define one or more Extension Aliases that this extension should replace. Notice it only omits the listed Extensions when this is rendered in the same spot. [Read more in Replace, Exclude or Unregister](replace-exclude-or-unregister.md).
+* `conditions` - Define one or more conditions that must be permitted for the extension to become available. [Extension Conditions](../extension-conditions.md).
+* `kind` - Define a kind-alias of which this manifest should be based upon. Kinds acts like a preset for your manifest. [Extension Kinds](../extension-kind.md).
+
+Many of the Extension Types require additional information declared as part of a `meta` field.
+
+## Registration
+
+An Extension Manifest can be registered in multiple ways.
+
+The primary registration should take part of the Umbraco Package Manifest.
+
+You can choose to declare all Extensions in the Package Manifest, or use one of three Extension Types to registere more extensions.
+
+This enables you to locate your Manifests in files together with the implementation code and the ability to declare Extension Manifests in TypeScript.
+
+A typical structure would be to declare one or more `Bundle` extensions in the Package Manifest. Each of the Bundles points to a `manifests.js` file which declares the Extensions of interest.
+
+### The `bundle` extension type
+
+The Bundle extension type is used to declare multiple Extension Manifests from a single JavaScript file.
+
+The Bundle is loaded at startup. All the Extension Manifests exported of the JavaScript file will be registered.
+
+Read more about the `bundle` extension type in the [Bundle](../extension-types/bundle.md)article.
+
+### The `backofficeEntryPoint` extension type
+
+Run any JavaScript code when Backoffice startups, after the user is logged in. This can be used as an entry point for a package, registering more extensions or configuring your package.
+
+There are many use cases. To name a few, it could be to load external libraries shared by all your extensions or load **global CSS files** for the whole application.
+
+The entry point declares a single JavaScript file that will be loaded and run when the Backoffice starts.
+
+Read more about the `backofficeEntryPoint` extension type in the [Entry Point](extension-manifest.md#the-backofficeentrypoint-extension-type) article.
+
+### The `appEntryPoint` extension type
+
+Similar as `appEntryPoint` this runs as startup, the difference is that this runs before the user is logged in. Use this to initiate things before the user is logged in or to provide things for the Login screen.
+
+Read more about the `appEntryPoint` extension type in the [App Entry Point](../extension-types/app-entry-point.md) article.
+
+## Type intellisense
+
+It is recommend to make use of the Type intellisense that we provide.
+
+When writing your Manifest in TypeScript you should use the Type `UmbExtensionManifest`, see the [TypeScript setup](../../development-flow/typescript-setup.md) article to make sure you have Types correctly configured.
+
+{% code title="manifests.ts" %}
+```typescript
+export const manifests: Array = [
+ {
+ type: '...',
+ alias: 'my.customization',
+ name: 'My customization'
+ ...
+ }
+]
+```
+{% endcode %}
+
+When writing the Umbraco Package Manifest you can use the JSON Schema located in the root of your Umbraco project called `umbraco-package-schema.json`
+
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "Fast Track Customizations",
+ "extensions": [
+ {
+ "type": "...",
+ "alias": "my.customization",
+ "name": "My customization"
+ ...
+ },
+ ...
+ ]
+}
+```
+
+### Registration via any JavaScript code
+
+Alternatively, an Extension Manifest can be declared in JavaScript at any given point.
+
+The following example shows how to register an extension manifest via JavaScript code:
+
+```typescript
+import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"
+
+const manifest = {
+ type: '...',
+ ...
+};
+
+umbExtensionsRegistry.register(extension);
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md b/16/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md
new file mode 100644
index 00000000000..d80d526ae18
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md
@@ -0,0 +1,18 @@
+# Extension Registration
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The extension registry is the center piece of the Backoffice UI. It holds information about most of the Backoffice UI, as most are extensions. This includes the built-in UI. The registry can be manipulated at any time, meaning you can add or remove extensions at runtime.
+
+To provide new UI to the backoffice, you must register them via an Extension Manifest. This can be initiated via an Umbraco Package JSON file on the server. This will be your starting point.
+
+Declaring a new extension is done by declaring an [extension manifest](extension-manifest.md). This can be done in one of two ways:
+
+1. Via a manifest JSON file on the server.
+2. In a JavaScript/TypeScript file.
+
+These two options can be combined as you like.
+
+A typical use case of such is achieved by registering a single extension manifest in your Umbraco Package JSON file. This manifest would then load a JS file, that registers the rest of your extensions. Learn more about these abilities in the [bundle](../extension-types/bundle.md) or [backoffice entry point](../extension-types/backoffice-entry-point.md) articles.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-registry/replace-exclude-or-unregister.md b/16/umbraco-cms/customizing/extending-overview/extension-registry/replace-exclude-or-unregister.md
new file mode 100644
index 00000000000..d4ae61646a7
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-registry/replace-exclude-or-unregister.md
@@ -0,0 +1,67 @@
+---
+description: >-
+ You may want to replace or completely remove an extension. Depending on your
+ interest, 3 different options are available.
+---
+
+# Replace, Exclude or Unregister
+
+## Replace
+
+If you want to bring your own extension and remove an existing, define your Extension to replace one or more other Extensions.
+
+This can be done by defining `overwrites` of your manifest with one Extension-alias or an array of Extension-aliases. [Read more about the Manifest Declaration here.](extension-manifest.md)
+
+Overwrite a single extension:
+
+```typescript
+const manifest = {
+ type: 'workspaceAction',
+ alias: 'my.WorkspaceAction.ExternalPreview',
+ name: 'My workspace action for external preview',
+ overwrites: 'Umb.WorkspaceAction.Document.SaveAndPreview'
+ ...
+};
+```
+
+Overwrite multiple extensions:
+
+```typescript
+const manifest = {
+ type: 'workspaceAction',
+ alias: 'my.WorkspaceAction.ExternalPreview',
+ name: 'My workspace action for external preview',
+ overwrites: ['Umb.WorkspaceAction.Document.SaveAndPreview', 'Umb.WorkspaceAction.Document.Save']
+ ...
+};
+```
+
+Once your extension is displayed in the same spot as the one defined in `overwrites`, those will be hidden.
+
+If your extension has conditions, then the overwrites will only be hidden when your extension is displayed. This means that the overwrites only have an effect if all the conditions are permitted and the extensions are displayed at the same spot.
+
+## Exclude
+
+To make an extension go away completely, you should exclude it. This approach secures that the extension will never be presented.
+
+The following JavaScript code hides the `Save and Preview` button from the Document Workspace.
+
+```typescript
+import { UmbExtensionRegistry } from '@umbraco-cms/backoffice/extension-api';
+
+UmbExtensionRegistry.exclude('Umb.WorkspaceAction.Document.SaveAndPreview');
+```
+
+## Unregister
+
+You can also choose to unregister an extension, this is only preferred if you registered the extension and are in control of the flow. If its not your Extension please seek to use the `Overwrites` or `Exclude` feature.
+
+```typescript
+import { UmbExtensionRegistry } from '@umbraco-cms/backoffice/extension-api';
+
+UmbExtensionRegistry.unregister('My.WorkspaceAction.AutoFillWithUnicorns');
+```
+
+This will not prevent the Extension from being registered again.
+
+A use case for this is if you temporarily registered an extension and you like to remove it again.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/README.md b/16/umbraco-cms/customizing/extending-overview/extension-types/README.md
new file mode 100644
index 00000000000..f28761f0b51
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/README.md
@@ -0,0 +1,31 @@
+---
+description: >-
+ The Extension types have some general features and some are provide
+ specifically to a type.
+---
+
+# Extension Types
+
+### General features
+
+The general features of all Extension Types can be read as part of the [Extension Manifest Article](../extension-registry/extension-manifest.md)
+
+### General Extension Type
+
+The system provides Extension Types for certain needs and then there is a few that has a general prupose.
+
+### [Bundle](bundle.md)
+
+The `bundle` type enables you to gather many extension manifests into one. These will be registered at startup.
+
+### [Backoffice Entry Point](backoffice-entry-point.md)
+
+The `backofficeEntryPoint` type is used to execute the method of a JavaScript file when the backoffice is initialized. This file can be used to do anything, this enables more complex logic to take place on startup.
+
+### [Extension Conditions](condition.md)
+
+Most Extension Types support conditions. Defining conditions enables you to control when and where the Extension is available. This Type enables you to bring your own Conditions for the system.
+
+### [Kinds](kind.md)
+
+The Kind-type enables you to base your Extension registration on a preset manifest. A kind provides the base manifest that your manifest will be ammending. A typical Kind declaration would provide a default Element, making it posible for you to only configure the Element via properties of the Manifest.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/app-entry-point.md b/16/umbraco-cms/customizing/extending-overview/extension-types/app-entry-point.md
new file mode 100644
index 00000000000..d2f647283b6
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/app-entry-point.md
@@ -0,0 +1,13 @@
+---
+description: The App Entry Point extension type is used to run some JavaScript code before the user is logged in.
+---
+
+# App Entry Point
+
+This manifest declares a single JavaScript file that will be loaded and run when the Backoffice starts. Additionally, the code will also run on the login screen.
+
+It performs the same function as the `backofficeEntryPoint` extension type, but the difference is that this runs before the user is logged in. Use this to initiate things before the user is logged in or to provide things for the Login screen.
+
+Read more about `backofficeEntryPoint` to learn how to use it:
+
+{% content-ref url="./backoffice-entry-point.md" %} . {% endcontent-ref %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/auth-provider.md b/16/umbraco-cms/customizing/extending-overview/extension-types/auth-provider.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md b/16/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md
new file mode 100644
index 00000000000..81dfa73e2fb
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md
@@ -0,0 +1,161 @@
+---
+description: The Backoffice Entry Point extension type is used to run some JavaScript code at startup.
+---
+
+# Backoffice Entry Point
+
+This manifest declares a single JavaScript file that will be loaded and run when the Backoffice starts. In other words this can be used as an entry point for a package.
+
+The `backofficeEntryPoint` extension is also the way to go if you want to load in external libraries such as jQuery, Angular, React, etc. You can use the `backofficeEntryPoint` to load in the external libraries to be shared by all your extensions. Additionally, **global CSS files** can also be used in the `backofficeEntryPoint` extension.
+
+{% hint style="info" %}
+See also the [App Entry Point](./app-entry-point.md) article for a similar extension type that runs before the user is logged in.
+{% endhint %}
+
+**Register a Backoffice Entry Point in the `umbraco-package.json` manifest**
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "name": "Name of your package",
+ "alias": "My.Package",
+ "extensions": [
+ {
+ "type": "backofficeEntryPoint",
+ "alias": "My.EntryPoint",
+ "js": "/App_Plugins/YourFolder/index.js"
+ }
+ ]
+}
+```
+{% endcode %}
+
+**Base structure of the entry point file**
+
+{% hint style="info" %}
+All examples are in TypeScript, but you can use JavaScript as well. Make sure to use a bundler such as [Vite](../../development-flow/vite-package-setup.md) to compile your TypeScript to JavaScript.
+{% endhint %}
+
+{% code title="index.ts" %}
+```typescript
+import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
+
+/**
+ * Perform any initialization logic when the Backoffice starts
+ */
+export const onInit: UmbEntryPointOnInit = (host, extensionsRegistry) => {
+ // Your initialization logic here
+}
+
+/**
+ * Perform any cleanup logic when the Backoffice and/or the package is unloaded
+ */
+export const onUnload: UmbEntryPointOnUnload = (host, extensionsRegistry) => {
+ // Your cleanup logic here
+}
+```
+{% endcode %}
+
+{% hint style="info" %}
+The `onUnload` function is optional and can be used to perform cleanup logic when the Backoffice and/or the package is unloaded.
+{% endhint %}
+
+## Examples
+
+### Register additional UI extensions in the entry point file
+
+{% code title="index.ts" %}
+```typescript
+import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
+
+const manifest: UmbExtensionManifest = {
+ type: '', // type of extension
+ alias: '', // unique alias for the extension
+ elementName: '', // unique name of the custom element
+ js: '', // path to the javascript resource
+ meta: {
+ // additional props for the extension type
+ }
+};
+
+export const onInit: UmbEntryPointOnInit = (host, extensionsRegistry) => {
+ // Register the extension
+ extensionRegistry.register(manifest);
+}
+
+export const onUnload: UmbEntryPointOnUnload = (host, extensionsRegistry) => {
+ // Unregister the extension (optional)
+ extension.unregister(manifest);
+}
+```
+{% endcode %}
+
+{% hint style="info" %}
+If you only need to register extensions, then consider using a [bundle](./bundle.md) type instead.
+{% endhint %}
+
+### Register global CSS
+
+An entry point is a good place to load global CSS files for the whole application. You can do this by creating a link element and appending it to the head of the document:
+
+{% code title="index.ts" %}
+```typescript
+import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
+
+export const onInit: UmbEntryPointOnInit = (host, extensionsRegistry) => {
+ const css = document.createElement('link');
+ css.rel = 'stylesheet';
+ css.href = '/App_Plugins/YourFolder/global.css';
+ document.head.appendChild(css);
+}
+```
+{% endcode %}
+
+Alternatively, you can import the CSS file directly in your JavaScript file:
+
+{% code title="index.ts" %}
+```typescript
+import '/App_Plugins/YourFolder/global.css';
+```
+{% endcode %}
+
+## Type IntelliSense
+
+It is recommended to make use of the Type intellisense that we provide.
+
+When writing your Manifest in TypeScript you should use the Type `UmbExtensionManifest`, see the [TypeScript setup](../../development-flow/typescript-setup.md) article to make sure you have Types correctly configured.
+
+{% code title="index.ts" %}
+```typescript
+import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
+
+const manifests: Array = [
+ {
+ type: '...',
+ alias: 'my.customization',
+ name: 'My customization'
+ ...
+ },
+ ...
+];
+
+export const onInit: UmbEntryPointOnInit = (host, extensionsRegistry) => {
+ // Register the extensions
+ extensionRegistry.registerMany(manifests);
+}
+```
+{% endcode %}
+
+## What's next?
+
+See the Extension Types article for more information about all the different extension types available in Umbraco:
+
+{% content-ref url="./" %}
+[README](./)
+{% endcontent-ref %}
+
+Read about running code before log in using an `appEntryPoint`:
+
+{% content-ref url="./app-entry-point.md" %}
+[App Entry Point](./app-entry-point.md)
+{% endcontent-ref %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/block-custom-view.md b/16/umbraco-cms/customizing/extending-overview/extension-types/block-custom-view.md
new file mode 100644
index 00000000000..469cd2746f1
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/block-custom-view.md
@@ -0,0 +1,82 @@
+---
+description: Bring your own representation for Blocks.
+---
+
+# Block Custom View
+
+The Block Custom View extension type lets you define a Web Component for representing blocks.
+
+## Build a Custom View
+
+1. Make a Document Type with a Property using a Block Editor of choice.
+2. Configure at least one Block Type on the Block Editor.
+3. Ensure the Element Type of the Blocks Content Model has a property using `headline` as the Property Alias.
+4. Take note of the Element Type Alias as you will use that in the next step.
+5. Add the following code to the `umbraco-package.json` file:
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My.CustomViewPackage",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "blockEditorCustomView",
+ "alias": "my.blockEditorCustomView.Example",
+ "name": "My Example Custom View",
+ "element": "/App_Plugins/welcome-dashboard/dist/example-block-custom-view.js",
+ "forContentTypeAlias": "{Insert Element Type Alias here}"
+ }
+ ]
+
+```
+{% endcode %}
+
+The code of your Web Component could look like this:
+
+{% code title="example-custom-view.ts" %}
+```typescript
+import { html, customElement, LitElement, property, css } from '@umbraco-cms/backoffice/external/lit';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import type { UmbBlockDataType } from '@umbraco-cms/backoffice/block';
+import type { UmbBlockEditorCustomViewElement } from '@umbraco-cms/backoffice/block-custom-view';
+
+@customElement('example-block-custom-view')
+export class ExampleBlockCustomView extends UmbElementMixin(LitElement) implements UmbBlockEditorCustomViewElement {
+
+ @property({ attribute: false })
+ content?: UmbBlockDataType;
+
+ render() {
+ return html`
+
My Custom View
+
Headline: ${this.content?.headline}
+ `;
+ }
+
+ static styles = [
+ css`
+ :host {
+ display: block;
+ height: 100%;
+ box-sizing: border-box;
+ background-color: darkgreen;
+ color: white;
+ border-radius: 9px;
+ padding: 12px;
+ }
+ `,
+ ];
+
+}
+export default ExampleBlockCustomView;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'example-block-custom-view': ExampleBlockCustomView;
+ }
+}
+
+```
+{% endcode %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/block-editors-custom-view.md b/16/umbraco-cms/customizing/extending-overview/extension-types/block-editors-custom-view.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/bundle.md b/16/umbraco-cms/customizing/extending-overview/extension-types/bundle.md
new file mode 100644
index 00000000000..78470d31f30
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/bundle.md
@@ -0,0 +1,66 @@
+---
+description: Gather Extension Manifests in one file
+---
+
+# Bundle
+
+The `bundle` Extension Type points to a single JavaScript file that exports or re-exports Extension Manifests written in JavaScript.
+
+It can be used as the entry point for a package, or as a grouping for a set of manifests. A Bundle can reference other Bundles.
+
+## Use Bundle as an entry point for a package
+
+If you want to declare your manifests in JavaScript/TypeScript, the Bundle is a great choice.
+
+The following example shows an `umbraco-package.json` that refers to one bundle, which can then declare manifests.
+
+{% code title="umbraco-package.json" %}
+```json
+ {
+ "name": "My Package Name",
+ "version": "1.0.0",
+ "extensions": [
+ {
+ "type": "bundle",
+ "alias": "My.Package.Bundle",
+ "name": "My Package Bundle",
+ "js": "/App_Plugins/my-package/manifests.js"
+ }
+ ]
+ }
+```
+{% endcode %}
+
+{% code title="manifests.ts" %}
+```typescript
+export const manifests: Array = [
+ {
+ type: 'dashboard',
+ name: 'Example Dashboard',
+ alias: 'example.dashboard.demo',
+ element: () => import('./demo-dashboard.js'),
+ weight: 900,
+ meta: {
+ label: 'Demo example',
+ pathname: 'demo-example',
+ },
+ },
+ // ... insert as many manifests as you like
+]
+```
+{% endcode %}
+
+{% hint style="info" %}
+Ensure you have set up your `tsconfig.json` to include the extension-types as global types. Like this:
+
+```json
+{
+ "compilerOptions": {
+ ...
+ "types": [
+ "@umbraco-cms/backoffice/extension-types"
+ ]
+ }
+}
+```
+{% endhint %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/collections/README.md b/16/umbraco-cms/customizing/extending-overview/extension-types/collections/README.md
new file mode 100644
index 00000000000..323c657fb09
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/collections/README.md
@@ -0,0 +1,6 @@
+---
+description: >-
+ An overview of the available extension types related to collections.
+---
+
+# Extension Types: Collections
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/collections/collection-action.md b/16/umbraco-cms/customizing/extending-overview/extension-types/collections/collection-action.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/collections/collection-view.md b/16/umbraco-cms/customizing/extending-overview/extension-types/collections/collection-view.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/collections/collection.md b/16/umbraco-cms/customizing/extending-overview/extension-types/collections/collection.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/condition.md b/16/umbraco-cms/customizing/extending-overview/extension-types/condition.md
new file mode 100644
index 00000000000..df6ca44feec
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/condition.md
@@ -0,0 +1,119 @@
+---
+description: >-
+ Learn how to declare requirements for your extensions using the Extension
+ Conditions.
+---
+
+# Extension Conditions
+
+Extension Conditions declare requirements that should be permitted for the extension to be available. Many, but not all, Extension Types support Conditions.
+
+[Read about utilizing conditions in Manifests](../extension-conditions.md#utilizing-conditions-in-your-manifest).
+
+## Make your own conditions
+
+```html
+
+```
+
+You can make your own Conditions by creating a class that implements the `UmbExtensionCondition` interface.
+
+```typescript
+import {
+ UmbConditionConfigBase,
+ UmbConditionControllerArguments,
+ UmbExtensionCondition
+} from '@umbraco-cms/backoffice/extension-api';
+import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry';
+import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+
+export type MyExtensionConditionConfig = UmbConditionConfigBase<'My.Condition.CustomName'> & {
+ match?: string;
+};
+
+export class MyExtensionCondition extends UmbConditionBase implements UmbExtensionCondition {
+ constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) {
+ super(host, args);
+
+ // enable extension after 10 seconds
+ setTimeout(() => {
+ this.permitted = true;
+ args.onChange();
+ }, 10000);
+ }
+}
+
+// Declare the Condition Configuration Type in the global UmbExtensionConditionConfigMap interface:
+declare global {
+ interface UmbExtensionConditionConfigMap {
+ MyExtensionConditionConfig: MyExtensionConditionConfig;
+ }
+}
+```
+
+The global declaration on the last five lines makes your Condition appear valid for manifests using the type `UmbExtensionManifest`. Also, the Condition Config Type alias should match the alias given when registering the condition below.
+
+The Condition then needs to be registered in the Extension Registry:
+
+```typescript
+export const manifest: UmbExtensionManifest = {
+ type: 'condition',
+ name: 'My Condition',
+ alias: 'My.Condition.CustomName',
+ api: MyExtensionCondition,
+};
+```
+
+Finally, you can make use of your condition in any manifests:
+
+```typescript
+export const manifest: UmbExtensionManifest = {
+ type: 'workspaceAction',
+ name: 'example-workspace-action',
+ alias: 'My.Example.WorkspaceAction',
+ elementName: 'my-workspace-action-element',
+ conditions: [
+ {
+ alias: 'Umb.Condition.SectionAlias',
+ match: 'My.Example.Workspace'
+ },
+ {
+ alias: 'My.Condition.CustomName'
+ }
+ ]
+}
+```
+
+As shown in the code above, the configuration property `match` isn't used for our condition. We can do this by replacing the timeout with some other check:
+
+```typescript
+// ...
+
+export class MyExtensionCondition extends UmbConditionBase implements UmbExtensionCondition {
+ constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) {
+ super(host, args);
+
+ if (args.config.match === 'Yes') {
+ this.permitted = true;
+ args.onChange();
+ }
+ }
+}
+
+// ...
+```
+
+With all that in place, the configuration can look like shown below:
+
+```typescript
+{
+ // ...
+ conditions: [
+ // ...
+ {
+ alias: 'My.Condition.CustomName',
+ match: 'Yes'
+ }
+ ]
+}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/current-user-action.md b/16/umbraco-cms/customizing/extending-overview/extension-types/current-user-action.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/dashboard-collection.md b/16/umbraco-cms/customizing/extending-overview/extension-types/dashboard-collection.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md b/16/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md
new file mode 100644
index 00000000000..6d1272ac9ef
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md
@@ -0,0 +1,144 @@
+---
+description: A guide to creating custom dashboards in Umbraco
+---
+
+# Dashboards
+
+Each section of the Umbraco backoffice has its own set of default dashboards. Your own custom sections can show dashboards, and you can create your own custom dashboards for existing sections.
+
+
The Getting Started dashboard in Umbraco
+
+The dashboard area of Umbraco is used to display an "editor" for the selected item in the tree. If no item is selected, then the default set of section dashboards is shown in the dashboard area.
+
+Notice that [Section Views](sections/section-view.md) is another similar approach to append information to the root of a Section. Section views are thought mainly to be used as Secondary pages. These two approaches should ideally not be combined.
+
+## Default Dashboards in Umbraco
+
+The default dashboards in Umbraco are the ones that are displayed when you first enter a section in the backoffice. These dashboards are used to display information and functionality that is relevant to the section you are in.
+
+The default sections in Umbraco are:
+
+| Alias | Name |
+| ----------------------- | ---------- |
+| Umb.Section.Content | Content |
+| Umb.Section.Media | Media |
+| Umb.Section.Settings | Settings |
+| Umb.Section.Members | Members |
+| Umb.Section.Users | Users |
+| Umb.Section.Translation | Dictionary |
+
+Here is a table of the default dashboards in Umbraco and the sections they are used including their aliases:
+
+| Alias | Section | Weight | Description |
+| -------------------------------- | -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Umb.Dashboard.UmbracoNews | Umb.Section.Content | 20 | The Getting Started dashboard users see when they first enter Umbraco. Contains the latest news of Umbraco including outbound links to resources |
+| Umb.Dashboard.RedirectManagement | Umb.Section.Content | 10 | Contains a list of active URL redirects |
+| Umb.Dashboard.SettingsWelcome | Umb.Section.Settings | 500 | Contains a set of boxes with links to appropriate resources |
+
+Even though these dashboards are useful, you might want to create your own custom dashboard to display specific information or functionality.
+
+You can try and [create a custom dashboard](../../../tutorials/creating-a-custom-dashboard/) as a way on getting started on this topic.
+
+## Registering your Dashboard
+
+This section dives into the Dashboard Extension Manifest, shows how to register one, and append additional details.
+
+### Example Extension Manifest
+
+{% hint style="info" %}
+You can read more about manifests in the tutorial [Creating Your First Extension](../../../tutorials/creating-your-first-extension.md).
+{% endhint %}
+
+Insert this as an entry in the `extensions` list in a `umbraco-package.json` file.
+
+{% code title="~/App_Plugins/WelcomeDashboard/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "type": "dashboard",
+ "alias": "my.welcome.dashboard",
+ "name": "My Welcome Dashboard",
+ "element": "/App_Plugins/WelcomeDashboard/dashboard.js",
+ "weight": -1,
+ "meta": {
+ "label": "Welcome Dashboard",
+ "pathname": "welcome-dashboard"
+ }
+}
+```
+{% endcode %}
+
+This will register a dashboard with the alias `my.welcome.dashboard` and the name `My Welcome Dashboard`. The dashboard will be loaded from the file `/App_Plugins/WelcomeDashboard/dashboard.js`. The dashboard will be displayed with the label `Welcome Dashboard` and the URL `/welcome-dashboard` on _all sections_, e.g. `/section/content/dashboard/welcome-dashboard`.
+
+### Conditions
+
+You can specify conditions for when the dashboard should be displayed. This is done by adding a `conditions` property to the manifest. Ideally, we would like the dashboard to be shown only in a specific section. This can be done by specifying the condition called `Umb.Condition.SectionAlias` and providing the [alias of the section](dashboard.md#default-dashboards-in-umbraco) you want the dashboard to be displayed on:
+
+```json
+"conditions": [
+ {
+ "alias": "Umb.Condition.SectionAlias",
+ "match": "Umb.Section.Content"
+ }
+]
+```
+
+This will make the dashboard only be displayed on the Content section.
+
+{% hint style="info" %}
+You can read more about [Extension Conditions](condition.md) in the documentation.
+{% endhint %}
+
+### Properties
+
+The dashboard manifest can contain the following properties:
+
+| Property | Type | Description |
+| ----------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| type | string | The type of extension, should be `dashboard` |
+| alias | string | A unique alias for the dashboard extension |
+| name | string | The name of the dashboard extension |
+| element | string | The path to the JavaScript file that exports the dashboard |
+| elementName | string | (Optional) The name of the Web Component that contains the dashboard (only if not a default export) |
+| weight | number | (Optional) The weight of the dashboard, higher numbers are displayed first |
+| meta | object |
Additional metadata for the dashboard
Property
Type
Description
Label
string
The label shown to the user
pathname
string
The routable URL pathname
|
+| Property | Type | Description |
+| Label | string | The label shown to the user |
+| pathname | string | The routable URL pathname |
+| Property | Type | Description |
+| Label | string | The label shown to the user |
+| pathname | string | The routable URL pathname |
+| Property | Type | Description |
+| Label | string | The label shown to the user |
+| pathname | string | The routable URL pathname |
+| Property | Type | Description |
+| Label | string | The label shown to the user |
+| pathname | string | The routable URL pathname |
+| conditions | array | (Optional) [Conditions](condition.md) for when the dashboard should be displayed |
+
+### Full Example
+
+{% code title="~/App_Plugins/WelcomeDashboard/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "type": "dashboard",
+ "alias": "my.welcome.dashboard",
+ "name": "My Welcome Dashboard",
+ "element": "/App_Plugins/WelcomeDashboard/dashboard.js",
+ "weight": -1,
+ "meta": {
+ "label": "Welcome Dashboard",
+ "pathname": "welcome-dashboard"
+ },
+ "conditions": [
+ {
+ "alias": "Umb.Condition.SectionAlias",
+ "match": "Umb.Section.Content"
+ }
+ ]
+}
+```
+{% endcode %}
+
+
The Welcome Dashboard appears in the Content section
+
+You can learn about [creating a custom dashboard](../../../tutorials/creating-a-custom-dashboard/) in the tutorials section. Here you will learn how to build the dashboard itself as a Web Component.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/dynamic-root-origin.md b/16/umbraco-cms/customizing/extending-overview/extension-types/dynamic-root-origin.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/dynamic-root-query-step.md b/16/umbraco-cms/customizing/extending-overview/extension-types/dynamic-root-query-step.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md b/16/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md
new file mode 100644
index 00000000000..b91de56a43c
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md
@@ -0,0 +1,216 @@
+---
+description: Entity Actions perform an action on a specific item
+---
+
+# Entity Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+{% hint style="info" %}
+Entity Actions was previously called Tree Actions.
+{% endhint %}
+
+Entity Actions is a feature that provides a generic place for secondary or additional functionality for an entity type. An entity type can be a media, document and so on.
+
+Items in an Umbraco Tree can have associated Actions. The actions visible to the currently logged in user can be controlled via User Permissions.
+
+You can set a User's permissions for each item in the Umbraco Content tree from the User Section of the Umbraco Backoffice.
+
+If you are developing a custom section or a custom Dashboard, you might want to display some different options. This depends on a User's permission set on a particular item.
+
+## Entity Actions in the UI
+
+
+
+
Sidebar Context Menu
+
+
+
+
Workspace Entity Action Menu
+
+
+
+
+
+
Collection
+
+
+
+
Pickers
+
+
+
+### Sidebar Context Menu
+
+Sidebar Context Menu is an entity action that can be performed on a menu item. For example in the content section you can perform some extra actions on the content such as sorting, moving, etc.
+
+
Default Entity Action in the Content Section
+
+## Registering an Entity Action
+
+```typescript
+import { extensionRegistry } from '@umbraco-cms/extension-registry';
+import { MyEntityAction } from './entity-action';
+
+const manifest = {
+ type: 'entityAction',
+ alias: 'My.EntityAction',
+ name: 'My Entity Action',
+ weight: 10,
+ api: MyEntityAction,
+ forEntityTypes: ['my-entity'],
+ meta: {
+ icon: 'icon-add',
+ label: 'My Entity Action',
+ repositoryAlias: 'My.Repository',
+ },
+};
+
+extensionRegistry.register(manifest);
+```
+
+**Default Element**
+
+```typescript
+interface UmbEntityActionElement {}
+```
+
+### The Entity Action Class
+
+As part of the Extension Manifest you can attach a class that will be instanciated as part of the action. It will have access to the host element, a repository with the given alias and the unique (key etc) of the entity.
+
+The class either provides a getHref method, or an execute method. If the getHref method is provided, the action will use the link. Otherwise the `execute` method will be used. When the action is clicked the `execute` method on the api class will be run. When the action is completed, an event on the host element will be dispatched to notify any surrounding elements.
+
+Example of providing a `getHref` method:
+
+```typescript
+import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
+import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
+import type { MyRepository } from './my-repository';
+
+export class MyEntityAction extends UmbEntityActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
+ super(host, repositoryAlias, unique);
+ }
+
+ async getHref() {
+ return 'my-link/path-to-something';
+ }
+}
+```
+
+Example of providing a `execute` method:
+
+```typescript
+import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
+import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
+import type { MyRepository } from './my-repository';
+
+export class MyEntityAction extends UmbEntityActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
+ super(host, repositoryAlias, unique);
+ }
+
+ async execute() {
+ await this.repository.myAction(this.unique);
+ }
+}
+```
+
+If any additional contexts are needed, these can be consumed from the host element:
+
+```typescript
+import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
+import { UmbContextConsumerController } from '@umbraco-cms/controller';
+import { UMB_MODAL_SERVICE_CONTEXT } from '@umbraco-cms/modal';
+import { MyRepository } from './my-repository';
+
+export class MyEntityAction extends UmbEntityActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
+ super(host, repositoryAlias, unique);
+
+ new UmbContextConsumerController(this.host, UMB_MODAL_SERVICE_CONTEXT, (instance) => {
+ this.#modalService = instance;
+ });
+ }
+ ...
+}
+```
+
+We currently have a couple of generic actions that can be used across silos, so we don't have to write the same logic again. These actions include copy, move, trash, delete, etc. We can add more as we discover the needs.
+
+## User Permission Codes
+
+Here is a list of the entity actions and associated user permission codes shipped by Umbraco CMS and add-on projects, such as Umbraco Deploy. This list also includes codes used by some community packages.
+
+If you are building a package or adding custom entity actions to your solution, it's important to pick a permission letter. Ensure that it doesn't clash with one of these.
+
+If you have created a package using a custom entity action, please consider providing an update to this documentation page. You can do this via a PR to the [documentation repository](https://github.com/umbraco/UmbracoDocs). This will allow other developers to discover and avoid using the same permission letter.
+
+Currently, we allow two extension points on the client for user permissions:
+
+* **Entity User Permissions** - Relates to an entity (example document).
+
+
Entity User Permissions UI
+
+* **Granular User Permission** - Relates to a $type server schemaType.
+
+
Granular User Permission UI
+
+Each permission comes with a set of verbs, that will be checked against client and server-side.
+
+The Core currently ships with entity user permission for documents. The permissions are as follows:
+
+| Current Backoffice Letter | Verb |
+| ------------------------- | -------------------------------- |
+| C | Umb.Document.Create |
+| F | Umb.Document.Read |
+| A | Umb.Document.Update |
+| D | Umb.Document.Delete |
+| I | Umb.Document.CreateBlueprint |
+| N | Umb.Document.Notifications |
+| U | Umb.Document.Publish |
+| R | Umb.Document.Permissions |
+| Z | Umb.Document.Unpublish |
+| O | Umb.Document.Duplicate |
+| M | Umb.Document.Move |
+| S | Umb.Document.Sort |
+| I | Umb.Document.CultureAndHostnames |
+| P | Umb.Document.PublicAccess |
+| K | Umb.Document.Rollback |
+| V | Umb.DocumentRecycleBin.Restore |
+
+**Entity User Permissions** will be registered in the extension registry with a manifest with the following type. Example:
+
+```typescript
+{
+ "type": "entityUserPermission",
+ "alias": "Umb.UserPermission.Document.Rollback",
+ "name": "Document Rollback User Permission",
+ "meta": {
+ "entityType": "document",
+ "verbs": ["Umb.Document.Rollback"],
+ "labelKey": "actions_rollback",
+ "descriptionKey": "actionDescriptions_rollback",
+ "group": "administration",
+ },
+ },
+```
+
+**Granular permissions** will also be registered. It is possible to provide a custom element to build the needed UX for that type of permission:
+
+```typescript
+{
+ "type": "userGranularPermission",
+ "alias": "Umb.UserGranularPermission.Document",
+ "name": "Document Granular User Permission",
+ "element": "element.js",
+ "meta": {
+ "schemaType": "DocumentPermissionPresentationModel",
+ "label": "Documents",
+ "description": "Assign permissions to specific documents",
+ },
+ },
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md b/16/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md
new file mode 100644
index 00000000000..797b5aebc15
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md
@@ -0,0 +1,57 @@
+# Entity Bulk Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+**Entity Bulk Action:** Relates to an entity type: document, media, etc. Performs the action on a selection of items.
+
+
Entity Bulk Collection
+
+## Registering an Entity Bulk Action
+
+```typescript
+import { extensionRegistry } from '@umbraco-cms/extension-registry';
+import { MyEntityBulkAction } from './entity-bulk-action';
+
+const manifest = {
+ type: 'entityBulkAction',
+ alias: 'My.EntityBulkAction',
+ name: 'My Entity Bulk Action',
+ weight: 10,
+ api: MyEntityBulkAction,
+ meta: {
+ icon: 'icon-add',
+ label: 'My Entity Bulk Action',
+ repositoryAlias: 'My.Repository',
+ },
+ conditions: [
+ {
+ alias: 'Umb.Condition.CollectionAlias',
+ match: 'my-collection-alias',
+ },
+ ],
+};
+
+extensionRegistry.register(manifest);
+```
+
+## The Entity Bulk Action Class
+
+As part of the Extension Manifest you can attach a class that will be instantiated as part of the action. It will have access to the host element, a repository with the given alias and the unique (key etc) of the entity. When the action is clicked the `execute` method on the api class will be run. When the action is completed, an event on the host element will be dispatched to notify any surrounding elements.
+
+```typescript
+import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
+import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
+import { MyRepository } from './my-repository';
+
+export class MyEntityBulkAction extends UmbEntityBulkActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) {
+ super(host, repositoryAlias, selection);
+ }
+
+ async execute() {
+ await this.repository?.myBulkAction(this.selection);
+ }
+}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/entity-create-option-action.md b/16/umbraco-cms/customizing/extending-overview/extension-types/entity-create-option-action.md
new file mode 100644
index 00000000000..ec78f6ea732
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/entity-create-option-action.md
@@ -0,0 +1,67 @@
+# Entity Create Option Action
+
+An "Entity Create Option Action" is an additional option that can be added when creating an entity. For example, options like "Create Document Type" or "Create Document Type with Template" can be available when a Document Type is being created.
+
+These options will be displayed in a create options dialog when the "Create"-entity action is selected. The dialog will show the available options and allow the user to select one of them.
+
+To enable a "Create"-entity action to show the options dialog, use the 'create'-kind in the manifest when setting up the "Create"-entity action. This will display the options dialog if multiple options are available, or it will automatically execute the first option if only one is available.
+
+By using the "create"-kind for your create entity actions, you can ensure that your options are extendable by other developers. This also applies when you only have one option available
+
+The following code shows you to register a "Create"-entity action that can display a dialog with options:
+
+```typescript
+const manifest = {
+ type: "entityAction",
+ kind: "create",
+ alias: "My.EntityAction",
+ name: "My Create Entity Action",
+ forEntityTypes: ["my-entity"],
+};
+```
+
+The following code demonstrates how to register an Entity Create Option Action. If only one option is available, it will be executed immediately.
+
+```typescript
+const manifest = {
+ type: "entityCreateOptionAction",
+ alias: "My.EntityCreateOptionAction",
+ name: "My Create Option Action",
+ weight: 100,
+ api: () => import("./path-to-file.js"),
+ forEntityTypes: ["my-entity"],
+ meta: {
+ icon: "icon-unplug",
+ label: "My Create Option Action",
+ additionalOptions: false,
+ },
+};
+```
+
+The following code shows how to implement the Create Action Option.
+
+```typescript
+import {
+ UmbEntityCreateOptionActionBase,
+ type MetaEntityCreateOptionAction,
+ type UmbEntityCreateOptionActionArgs,
+} from "@umbraco-cms/backoffice/entity-create-option-action";
+import type { UmbControllerHostElement } from "@umbraco-cms/backoffice/controller-api";
+
+export class MyEntityCreateActionOption extends UmbEntityCreateOptionActionBase {
+ constructor(
+ host: UmbControllerHostElement,
+ args: UmbEntityCreateOptionActionArgs
+ ) {
+ super(host, args);
+ }
+
+ override async execute() {
+ alert("My Create Option Action executed!");
+ }
+}
+```
+
+We currently support Create Options for the following entity types:
+
+- User
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/entry-point.md b/16/umbraco-cms/customizing/extending-overview/extension-types/entry-point.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/global-context.md b/16/umbraco-cms/customizing/extending-overview/extension-types/global-context.md
new file mode 100644
index 00000000000..744314d195c
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/global-context.md
@@ -0,0 +1,24 @@
+---
+description: Establish the bond for extensions to communication across the application
+---
+
+# Global Context
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A global context manages the logic code from your Lit Element controllers.
+
+## Registration of a Global Context
+
+You can register a global context like so:
+
+```typescript
+{
+ type: 'globalContext',
+ alias: 'My.GlobalContext.Products',
+ name: 'My Products Context',
+ api: 'my-products.context.js',
+}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/granular-user-permissions.md b/16/umbraco-cms/customizing/extending-overview/extension-types/granular-user-permissions.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/header-apps.md b/16/umbraco-cms/customizing/extending-overview/extension-types/header-apps.md
new file mode 100644
index 00000000000..cffe04a2632
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/header-apps.md
@@ -0,0 +1,116 @@
+---
+description: Example how to work with extension registry
+---
+
+# Header Apps
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A header app appears next to the user profile and global search icon on the top-right corner of Umbraco's backoffice.
+
+In this article, you can find an example of an extension registry. This example details the creation of a Header App in two ways, similar to how the extension registry can be created:
+
+1. [Using a manifest file](header-apps.md#button-header-app-with-manifest).
+2. [Using the JavaScript/TypeScript file](header-apps.md#button-header-app-with-js-ts).
+
+
Header Apps
+
+## **Button Header App with Manifest**
+
+Below you can find an example of how to setup a Header App using the manifest file.
+
+1. Follow the [Vite Package Setup](../../development-flow/vite-package-setup.md) to create a header app and name it "`header-app`" when using the guide.
+2. Create a manifest file named `umbraco-package.json` at the root of the `header-app` folder. Here we define and configure our dashboard.
+3. Add the following code to `umbraco-package.json`:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```typescript
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My Header App",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "headerApp",
+ "alias": "My.HeaderApp",
+ "name": "My Header App",
+ "kind": "button",
+
+ "meta": {
+ "label": "Hello Umbraco",
+ "icon": "icon-hearts",
+ "href": "https://umbraco.com/"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+* First we define the type which is a `headerApp`. Then we add a unique alias and a name to define the extension UI.
+* Then we can define what kind of extension it is, where in this case we can use a pre-defined element called button.
+* The button requires some metdata: an icon, label of the button (name of the button) and a link which opens once clicked.
+
+4. In the `header-app` folder run `npm run build` and then run the project. Then in the backoffice you will see our new Header App extension with **heart icon**:
+
+
Header App in the Backoffice registered via Manifest File
+
+## **Button Header App with JS/TS**
+
+Below you can find an example of how to setup a Header App using the TypeScript file.
+
+This is a continuation of the above steps from the **Button Header App with Manifest** example. We will register a new Header App directly from the .ts file.
+
+1. Add a reference to the .js file. Update the `umbraco-package.json` with the following:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```typescript
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My Header App",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "headerApp",
+ "alias": "My.HeaderApp",
+ "name": "My Header App",
+ "kind": "button",
+ "element": "/App_Plugins/header-app/dist/header-app.js",
+ "meta": {
+ "label": "Hello Umbraco",
+ "icon": "icon-hearts",
+ "href": "https://umbraco.com/"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+2. Replace the content of the `src/my-element.ts file` with the following:
+
+{% code title="my-element.ts" lineNumbers="true" %}
+```typescript
+import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
+
+const manifest: UmbExtensionManifest = {
+ type: "headerApp",
+ alias: "My.HeaderApp.Documentation",
+ name: "My Header App Documentation",
+ kind: "button",
+ meta: {
+ label: "Hello Documentation",
+ icon: "icon-addressbook",
+ href: "https://docs.umbraco.com/"
+ }
+};
+
+umbExtensionsRegistry.register(manifest);
+```
+{% endcode %}
+
+3. In the `header-app` folder run `npm run build` and then run the project. Then in the backoffice you will see our new Header App extension with **address book** **icon**:
+
+
Header App in Backoffice registered via ts File
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/health-check.md b/16/umbraco-cms/customizing/extending-overview/extension-types/health-check.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/icons.md b/16/umbraco-cms/customizing/extending-overview/extension-types/icons.md
new file mode 100644
index 00000000000..d57653437e2
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/icons.md
@@ -0,0 +1,78 @@
+---
+description: Learn how to append and use Icons.
+---
+
+# Icons
+
+This article describes how to add and use more icons in your UI.
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## Register a new set of icons
+
+New icons can be added via an extension type called `icons`.
+
+You must add a new manifest to the Extension API to register icons. The manifest can be added through the `umbraco-package.json` file as shown in the snippet below.
+
+{% code title="umbraco-package.json" %}
+
+```json
+{
+ "name": "MyPackage",
+ "extensions": [
+ {
+ "type": "icons",
+ "alias": "MyPackage.Icons.Unicorn",
+ "name": "MyPackage Unicorn Icons",
+ "js": "/App_Plugins/MyPackage/Icons/icons.js"
+ }
+ ]
+}
+```
+
+{% endcode %}
+
+The file set in the `js` field holds the details about your Icons. The file should resemble the following:
+
+{% code title="icons.js" %}
+
+```typescript
+export default [
+ {
+ name: "myPackage-unicorn",
+ path: () => import("./icon-unicorn.js"),
+ },
+ {
+ name: "myPackage-giraffe",
+ path: () => import("./icon-giraffe.js"),
+ }
+]
+```
+
+{% endcode %}
+
+The icon name needs to be prefixed to avoid collision with other icons.
+
+Each icon must define a path, either as a string or a dynamic import as shown above. This file must be a JavaScript file containing a default export of an SVG string. See an example of this in the code snippet below.
+
+{% code title="icon-unicorn.js" %}
+
+```typescript
+export default ``;
+```
+
+{% endcode %}
+
+### Using Icons in your UI
+
+The `umb-icon` element is automatically able to consume any registered icon.
+
+The following example shows how to make a button using the above-registered icon.
+
+```html
+
+
+
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/kind.md b/16/umbraco-cms/customizing/extending-overview/extension-types/kind.md
new file mode 100644
index 00000000000..37bb77f1da4
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/kind.md
@@ -0,0 +1,123 @@
+---
+description: A kind extension provides the preset for other extensions to use.
+---
+
+# Kind
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A Kind is a preset configuration that can be inherited by extensions to ensure consistency and reduce redundancy. It defines a set of default properties or behaviors that extensions can adopt, making it easier to maintain and configure extensions that share similar functionality.
+
+A Kind is always linked to a specific extension type. Extensions using the same type and referencing a Kind automatically inherit its settings, ensuring uniformity across different extensions.
+
+## Benefits of Using a Kind
+
+- Reduces redundancy – Common settings are defined once and reused across extensions.
+- Ensures consistency – Extensions using the same Kind follow a standardized structure and behavior.
+- Simplifies extension definitions – Extensions inherit predefined properties, reducing manual configuration.
+
+## Kind Registration
+
+To register a Kind, use the same method as other extensions. The key properties that define a Kind registration are:
+
+- `type`: Always set to `kind`.
+- `alias`: A unique identifier for the Kind.
+- `matchType`: Specifies the extension type that the Kind applies to.
+- `matchKind`: Defines the Kind alias, which extensions must reference.
+- `manifest`: Contains the preset values that extensions will inherit.
+
+### Example: Registering a Button Kind for Header Apps
+
+The following example shows how to register a Button Kind for [**Header Apps**](../extension-types/header-apps.md). This kind provides a preset configuration for a button element that can be reused by other Header App extensions.
+
+```typescript
+const manifest: ManifestKind = {
+ type: 'kind',
+ alias: 'Umb.Kind.MyButtonKind', // Unique alias for the Kind
+ matchType: 'headerApp', // Applies to Header App extensions
+ matchKind: 'button', // Defines the Kind alias
+ manifest: {
+ // Add default properties for the 'button' Kind
+ elementName: 'umb-header-app-button',
+ },
+};
+```
+
+In this example:
+
+- `type` is set to 'kind' to register it as a Kind extension.
+- `matchType` is 'headerApp', specifying that this Kind is for Header App extensions.
+- `matchKind` is 'button', which is the alias of the Kind.
+- The `manifest` contains default properties like elementName that extensions using this Kind will inherit.
+
+## Using the Kind in Other Extensions
+
+To use the Kind in other extensions, the extension must reference it by setting the `type` and `kind` properties. The extension will automatically inherit the Kind's properties.
+
+### Example: Header App Extension Using the Button Kind
+
+```typescript
+const manifest = {
+ type: 'headerApp', // Extension type
+ kind: 'button', // References the 'button' Kind
+ name: 'My Header App Example',
+ alias: 'My.HeaderApp.Example',
+ meta: {
+ label: 'My Example',
+ icon: 'icon-home',
+ href: '/some/path/to/open/when/clicked',
+ },
+};
+
+extensionRegistry.register(manifest);
+```
+
+In this example, the Header App extension uses the `kind: 'button'`, meaning it inherits the `elementName` defined in the Button Kind. The extension can still add custom properties (like metadata in this case) to further customize the behavior or appearance.
+
+## Kind Example
+
+Here’s an example of how to register and use the Button Kind in a Header App extension:
+
+```typescript
+import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
+
+const manifest: UmbExtensionManifest = {
+ type: 'kind',
+ alias: 'Umb.Kind.MyButtonKind', // Alias for the Kind
+ matchType: 'headerApp', // Extension type the Kind applies to
+ matchKind: 'button', // Defines the Kind alias
+ manifest: {
+ elementName: 'umb-header-app-button',
+ },
+};
+
+umbExtensionsRegistry.register(manifest);
+```
+
+This code registers the Button Kind, so other Header App extensions using `type: 'headerApp'` and `kind: 'button'` will inherit the preset `elementName: 'umb-header-app-button'`.
+
+Now, another Header App extension can be created without defining `elementName`, as it will automatically inherit it from the Kind:
+
+```typescript
+import { extensionRegistry } from '@umbraco-cms/extension-registry';
+
+const manifest = {
+ type: 'headerApp', // Extension type
+ kind: 'button', // References the 'button' Kind
+ name: 'My Header App Example',
+ alias: 'My.HeaderApp.Example',
+ meta: {
+ label: 'My Example',
+ icon: 'icon-home',
+ href: '/some/path/to/open/when/clicked',
+ },
+};
+
+extensionRegistry.register(manifest);
+```
+
+By referencing the Kind, the extension inherits shared properties like `elementName`, ensuring consistency and reducing redundancy across extensions. This method also makes it easier to update configurations across multiple extensions.
+
+By using Kinds, you can create reusable, standardized configurations for extensions, helping to streamline development, ensure consistency, and reduce duplication. Understanding how to register and reference Kinds effectively will enhance the maintainability of your Umbraco extensions.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/localization.md b/16/umbraco-cms/customizing/extending-overview/extension-types/localization.md
new file mode 100644
index 00000000000..9efc9ffb4e5
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/localization.md
@@ -0,0 +1,83 @@
+---
+description: Learn how to manage and use the Backoffice UI Localization files.
+---
+
+# Localization
+
+## Registering Localization
+
+When registering localizations to a language, you must add a new manifest to the Extension API. The manifest can be added through the `umbraco-package.json` file.
+
+{% hint style="info" %}
+The `umbraco-package.json` file is only registered when placed directly in the `/App_Plugins/` or `/App_Plugins/{YourPackageName}` folder. It will not be recognized in nested subfolders.
+{% endhint %}
+
+Usually, the localization keys are provided through a JavaScript module. In this example, we will use a file named `en.js`:
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "name": "MyPackage",
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "MyPackage.Localize.EnUS",
+ "name": "English",
+ "meta": {
+ "culture": "en"
+ },
+ "js": "/App_Plugins/MyPackage/Localization/en.js"
+ }
+ ]
+}
+```
+{% endcode %}
+
+{% hint style="info" %}
+Read more about extensions in the [Package Manifest](../../umbraco-package.md) article.
+{% endhint %}
+
+## The Localization file
+
+The localization files for the UI are JavaScript modules with a default export containing a key-value structure organized in sections.
+
+{% code title="en.js" %}
+```javascript
+export default {
+ section: {
+ key1: 'value1',
+ key2: 'value2',
+ },
+};
+```
+{% endcode %}
+
+The sections and keys will be formatted into a map in Umbraco with the format `section_key1` and `section_key2.` These form the unique key they are requested.
+
+If you do not have many translations, you can also choose to include them directly in the meta-object using the `localizations` property:
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "name": "MyPackage",
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "MyPackage.Localize.EnUS",
+ "name": "English",
+ "meta": {
+ "culture": "en",
+ "localizations": {
+ "section": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ }
+ },
+ }
+ ]
+}
+```
+{% endcode %}
+
+In this case, the `en.js` file is not required and we can remove the "js" property from the manifest. Only strings can be used in the meta-object.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu-item.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu-item.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md
new file mode 100644
index 00000000000..e305a7b8155
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md
@@ -0,0 +1,263 @@
+# Menu
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+
Menu
+
+## Creating a custom menu
+
+In this section, you can learn how to register and create a custom Menu for the Umbraco backoffice.
+
+### Manifest
+
+The manifest file can be created using either JSON or TypeScript. Both methods are shown below.
+
+{% tabs %}
+
+{% tab title="JSON" %}
+
+We can create the manifest using JSON in the `umbraco-package.json`.
+
+```json
+{
+ "type": "menu",
+ "alias": "My.Menu",
+ "name": "My Menu"
+}
+```
+{% endtab %}
+
+{% tab title="TypeScript" %}
+
+The manifest can also be written in TypeScript.
+
+For this TypeScript example we used a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension to register the manifests.
+
+```typescript
+import type { ManifestMenu } from '@umbraco-cms/backoffice/menu';
+
+const menuManifest: Array = [
+ {
+ type: 'menu',
+ alias: 'My.Menu',
+ name: 'My Menu'
+ }
+];
+```
+
+{% endtab %}
+
+{% endtabs %}
+
+# Menu Item
+
+
Menu Item
+
+Menu items are the items that appear in the menu.
+
+## Creating a custom menu items
+
+In this section, you can learn how to add custom Menu Items to your Umbraco backoffice Menu.
+
+### Manifest
+
+To add custom menu items, you can define a single MenuItem manifest and link an element to it. In this element, you can fetch the data and render as many menu items as you want based on that data.
+
+The code snippets below show how to declare a new menu item using JSON or TypeScript.
+
+{% tabs %}
+
+{% tab title="JSON" %}
+
+We can create the manifest using JSON in the `umbraco-package.json`.
+
+```json
+{
+ "type": "menuItem",
+ "alias": "My.MenuItem",
+ "name": "My Menu Item",
+ "element": "./menu-items.ts",
+ "meta": {
+ "label": "My Menu Item",
+ "menus": ["My.Menu"]
+ }
+}
+```
+
+{% endtab %}
+
+{% tab title="TypeScript" %}
+
+The manifest can also be written in TypeScript.
+
+For this TypeScript example we used a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension to register the manifests.
+
+{% code title="manifest.ts" overflow="wrap" lineNumbers="true" %}
+```typescript
+const menuItemManifest: Array = [
+ {
+ type: 'menuItem',
+ alias: 'My.MenuItem',
+ name: 'My Menu Item',
+ meta: {
+ label: 'My Menu Item',
+ menus: ["My.Menu"]
+ },
+ element: () => import('./menu-items.ts')
+ }
+];
+```
+{% endcode %}
+
+
+{% endtab %}
+
+{% endtabs %}
+
+### The UI Element
+
+#### Rendering menu items with Umbraco's UI menu item component
+
+To render your menu items in Umbraco, you can use the [Umbraco UI Menu Item component](https://uui.umbraco.com/?path=/docs/uui-menu-item--docs). This component allows you to create nested menu structures with a few lines of code.
+
+By default, you can set the `has-children` attribute to display the caret icon indicating nested items. It will look like this: `?has-children=${bool}`.
+
+**Example:**
+
+```tsx
+
+
+
+
+```
+
+#### Custom menu item element example
+
+You can fetch the data and render the menu items using the Lit element above. By putting the result of the fetch in a `@state()`, we can trigger a re-render of the component when the data is fetched.
+
+{% code title="menu-items.ts" overflow="wrap" lineNumbers="true" %}
+```typescript
+import type { UmbMenuItemElement } from '@umbraco-cms/backoffice/menu';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { html, TemplateResult, customElement, state } from '@umbraco-cms/backoffice/external/lit';
+import { MyMenuItemResponseModel, MyMenuResource } from '../../../api';
+
+const elementName = 'my-menu-item';
+
+@customElement(elementName)
+class MyMenuItems extends UmbLitElement implements UmbMenuItemElement {
+ @state()
+ private _items: MyMenuItemResponseModel[] = []; // Store fetched items
+
+ @state()
+ private _loading: boolean = true; // Track loading state
+
+ @state()
+ private _error: string | null = null; // Track any errors
+
+ override firstUpdated() {
+ this.fetchInitialItems(); // Start fetching on component load
+ }
+
+ // Fetch initial items
+ async fetchInitialItems() {
+ try {
+ this._loading = true;
+ this._items = ((await MyMenuResource.getMenuApiV1()).items); // Fetch root-level items
+ } catch (e) {
+ this._error = 'Error fetching items';
+ } finally {
+ this._loading = false;
+ }
+ }
+
+ // Render items
+ renderItems(items: MyMenuItemResponseModel[]): TemplateResult {
+ return html`
+ ${items.map(element => html`
+
+ ${element.type === 1
+ ? html``
+ : html``}
+
+ ${element.hasChildren ? this.renderItems(element.children) : ''}
+
+ `)}
+ `;
+ }
+
+ // Main render function
+ override render() {
+ if (this._loading) {
+ return html``;
+ }
+
+ if (this._error) {
+ return html`
+ `;
+ }
+
+ // Render items if loading is done and no error occurred
+ return this.renderItems(this._items);
+ }
+}
+
+export { MyMenuItems as element };
+
+declare global {
+ interface HTMLElementTagNameMap {
+ [elementName]: MyMenuItems;
+ }
+}
+
+```
+{% endcode %}
+
+
+## Tree Menu Item
+
+### Manifest
+
+```json
+// it will be something like this
+{
+ "type": "menuItem",
+ "kind": "tree",
+ "alias": "My.TreeMenuItem",
+ "name": "My Tree Menu Item",
+ "meta": {
+ "label": "My Tree Menu Item",
+ "menus": ["My.Menu"]
+ }
+}
+```
+
+#### Default Element
+
+The default element supports rendering a subtree of menu items.
+
+```typescript
+class UmbMenuItemTreeDefaultElement {}
+```
+
+### Adding menu items to an existing menu
+
+The backoffice comes with a couple of menus.
+
+* Content, Media, Settings, Templating, Dictionary, etc.
+
+To add a menu item to an existing menu, you can use the `meta.menus` property.
+
+```typescript
+{
+ "type": "menuItem",
+ "alias": "My.MenuItem",
+ "name": "My Menu Item",
+ "meta": {
+ "label": "My Menu Item",
+ "menus": ["Umb.Menu.Content"]
+ }
+}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/mfa-login-provider.md b/16/umbraco-cms/customizing/extending-overview/extension-types/mfa-login-provider.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/modals/README.md b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/README.md
new file mode 100644
index 00000000000..a5402abd2f6
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/README.md
@@ -0,0 +1,104 @@
+---
+description: >-
+ A modal is a popup layer that darkens the surroundings and comes with a focus
+ lock. There are two types of modals: "dialog" and "sidebar".
+---
+
+# Modals
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## **Modal Types**
+
+The Dialog modal appears in the middle of the screen. and the Sidebar Modal slide in from the right.
+
+## Modal Token
+
+For type safety, we recommend that you use Modal Tokens. The Modal Token binds the Modal Type with a Modal Data Type and a Modal Result Type.
+
+This can also come with defaults, for example, settings for the modal type and size.
+
+This is an example of a Modal Token declaration:
+
+```ts
+import { UmbModalToken } from "@umbraco-cms/backoffice/modal";
+
+export type OurSomethingPickerModalData = {
+ // We do not have any data to parse for this example
+};
+
+export type OurSomethingPickerModalValue = {
+ key: string;
+};
+
+export const MY_SOMETHING_PICKER_MODAL = new UmbModalToken<
+ OurSomethingPickerModalData,
+ OurSomethingPickerModalValue
+>("Our.Modal.SomethingPicker", {
+ modal: {
+ type: "sidebar",
+ size: "small",
+ },
+});
+```
+
+## Make a custom Modal Element
+
+To create your own modal, read the [Implementing a Custom Modal article](custom-modals.md) before proceeding with this article.
+
+### Basic Usage
+
+Consume the `UMB_MODAL_MANAGER_CONTEXT` and then use the modal manager context to open a modal. This example shows how to consume the Modal Manager Context:
+
+```ts
+import { LitElement } from "@umbraco-cms/backoffice/external/lit";
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import {
+ UMB_MODAL_MANAGER_CONTEXT,
+} from "@umbraco-cms/backoffice/modal";
+
+export class MyElement extends UmbElementMixin(LitElement) {
+ #modalManagerContext?: typeof UMB_MODAL_MANAGER_CONTEXT.TYPE;
+
+ constructor() {
+ super();
+ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
+ this.#modalManagerContext = instance;
+ // modalManagerContext is now ready to be used.
+ });
+ }
+}
+```
+
+#### Open a modal
+
+A modal can be opened in two ways. Either you register the modal with a route or at runtime open the modal. The initial option allows users to deep-link to the modal, a potential preference in certain cases; otherwise, consider the latter.
+
+#### Directly open a Modal
+
+In this case, we use the Modal Token from above, this takes a key as its data. And if submitted then it returns the new key.
+
+```typescript
+const modalContext = this.#modalManagerContext?.open(this, MY_SOMETHING_PICKER_MODAL, {
+ value: {
+ key: this.selectedKey,
+ },
+});
+
+modalContext
+ ?.onSubmit()
+ .then((value) => {
+ this.selectedKey = value.key;
+ })
+ .catch(() => undefined);
+```
+
+[See the implementing a Confirm Dialog for a more concrete example.](confirm-dialog.md)
+
+**Modal Route Registration**
+
+You can register modals with a route, making it possible to link directly to that specific modal. This also means the user can navigate back and forth in the browser history. This makes it an ideal solution for modals containing an editorial experience.
+
+For a more concrete example, check out the [Implementing a Confirm Dialog article](route-registration.md).
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/modals/confirm-dialog.md b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/confirm-dialog.md
new file mode 100644
index 00000000000..4546976d68c
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/confirm-dialog.md
@@ -0,0 +1,74 @@
+---
+description: Ask the user for confirmation
+---
+
+# Confirm Dialog
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+This example shows how to open a confirm dialog. The `UMB_CONFIRM_MODAL` is a token that represents the confirm dialog. The `open` method takes the token and an object with the data for the confirm dialog. The `onSubmit` method returns a promise that resolves when the user confirms the dialog and rejects when the user cancels the dialog.
+
+The confirm modal itself is built-in and does not need to be registered in the extension registry.
+
+The modal token describes the options that you can pass to the modal. The confirm modal token has the following properties:
+
+* `headline` - The headline of the modal.
+* `content` - The content of the modal, which can be a TemplateResult or a string.
+* `color` - (Optional) The color of the modal. This can be `positive` or `danger`.
+* `confirmLabel` - (Optional) The label of the confirm button.
+
+## Basic Usage
+
+{% code title="my-element.ts" %}
+```typescript
+import { html, LitElement, customElement } from "@umbraco-cms/backoffice/external/lit";
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UMB_MODAL_MANAGER_CONTEXT, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal';
+
+@customElement('my-element')
+export class MyElement extends UmbElementMixin(LitElement) {
+ #modalManagerContext?: typeof UMB_MODAL_MANAGER_CONTEXT.TYPE;
+
+ constructor() {
+ super();
+ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
+ this.#modalManagerContext = instance;
+ });
+ }
+
+ #onRequestDisable() {
+ const modalContext = this.#modalManagerContext?.open(
+ this, UMB_CONFIRM_MODAL,
+ {
+ data: {
+ headline: `${this.localize.term("actions_disable")}`,
+ content: `${this.localize.term(
+ "defaultdialogs_confirmdisable"
+ )}`,
+ color: "danger",
+ confirmLabel: "Disable",
+ }
+ }
+ );
+ modalContext
+ ?.onSubmit()
+ .then(() => {
+ console.log("User has approved");
+ })
+ .catch(() => {
+ console.log("User has rejected");
+ });
+ }
+
+ render() {
+ return html``;
+ }
+}
+```
+{% endcode %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/modals/custom-modals.md b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/custom-modals.md
new file mode 100644
index 00000000000..321382a9159
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/custom-modals.md
@@ -0,0 +1,147 @@
+---
+description: >-
+ New modals can be added to the system via the extension registry. This article
+ goes through how this is done.
+---
+
+# Custom Modals
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+There are two parts to creating a custom modal:
+
+* First, you need to create a modal element which you need to register in the extension registry.
+* Second, you need to create and export a modal token.
+
+## Create a modal token
+
+A modal token is a string that identifies a modal. This is the modal extension alias. It is used to open a modal and is also to set default options for the modal. It should also have a unique alias to avoid conflicts with other modals.
+
+```ts
+import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
+
+export type MyModalData = {
+ headline: string;
+}
+
+export type MyModalValue = {
+ myData: string;
+}
+
+export const MY_MODAL_TOKEN = new UmbModalToken('My.Modal', {
+ modal: {
+ type: 'sidebar',
+ size: 'small'
+ }
+});
+```
+
+A modal token is a generic type that takes two type arguments. The first is the type of the data that is passed to the modal when it is opened. The second is the type of the value that is returned when the modal is closed.
+
+## Create a modal element
+
+A modal element is a web component that is used to render the modal. It should implement the `UmbModalExtensionElement` interface. The modal context is injected into the element when the modal is opened in the `modalContext` property. The modal context is used to close the modal, update the value and submit the modal.
+
+Additionally, the modal element can see its data parameters through the `modalContext` property. In this example, the modal data is of type `MyModalData` and the modal value is of type `MyModalValue`. The modal context is of type `UmbModalContext`. We are using the data to render a headline and the value to update the value and submit the modal.
+
+{% code title="my-modal.element.ts" %}
+```ts
+import { customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbModalExtensionElement } from '@umbraco-cms/backoffice/modal';
+import type { UmbModalContext } from '@umbraco-cms/backoffice/modal';
+import type { MyModalData, MyModalValue } from './my-modal.token.js';
+
+@customElement('my-dialog')
+export default class MyDialogElement
+ extends UmbLitElement
+ implements UmbModalExtensionElement {
+
+ @property({ attribute: false })
+ modalContext?: UmbModalContext;
+
+ @property({ attribute: false })
+ data?: MyModalData;
+
+ private _handleCancel() {
+ this.modalContext?.submit();
+ }
+
+ private _handleSubmit() {
+ this.modalContext?.updateValue({ myData: 'hello world' });
+ this.modalContext?.submit();
+ }
+
+ render() {
+ return html`
+
+ `;
+ }
+}
+```
+{% endcode %}
+
+## Register in the extension registry
+
+The modal element needs to be registered in the extension registry. This is done by defining the modal in the manifest file. The `element` property should point to the file that contains the modal element.
+
+```json
+{
+ "type": "modal",
+ "alias": "My.Modal",
+ "name": "My Modal",
+ "element": "../path/to/my-modal.element.js"
+}
+```
+
+## Open the modal
+
+To open the modal, you need to consume the `UmbModalManagerContext` and then use the modal manager context to open a modal. This example shows how to consume the Modal Manager Context:
+
+{% code title="my-element.ts" %}
+```ts
+import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { MY_MODAL_TOKEN } from './my-modal.token.js';
+import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
+
+@customElement('my-element')
+class MyElement extends UmbLitElement {
+ #modalManagerContext?: typeof UMB_MODAL_MANAGER_CONTEXT.TYPE;
+
+ constructor() {
+ super();
+ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
+ this.#modalManagerContext = instance;
+ // modalManagerContext is now ready to be used.
+ });
+ }
+
+ override render() {
+ return html`
+
+ `;
+ }
+
+ private _openModal() {
+ this.#modalManagerContext?.open(this, MY_MODAL_TOKEN, {
+ data: {
+ headline: "My modal headline",
+ },
+ });
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'my-element': MyElement;
+ }
+}
+```
+{% endcode %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/modals/route-registration.md b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/route-registration.md
new file mode 100644
index 00000000000..82245a956de
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/modals/route-registration.md
@@ -0,0 +1,126 @@
+# Route Registration
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+You can register modals with a route, making it possible to link directly to that specific modal. This also means the user can navigate back and forth in the browser history.
+
+A modal can be registered via the `UmbModalRouteRegistrationController`. The registration accepts a modal token (or extension alias).
+
+```ts
+this.myModalRegistration = new UmbModalRouteRegistrationController(
+ this,
+ UMB_LINK_PICKER_MODAL
+)
+ .onSubmit((submitData) => {
+ console.log("Modal submitted with data".submitData);
+ })
+ .observeRouteBuilder((routeBuilder) => {
+ this._modalRouteBuilder = routeBuilder;
+ });
+```
+
+The registration holds an instance of its `UmbModalHandler` when the modal is active. The modal registration accepts 4 different callbacks:
+
+* `onSetup` - called when the modal is opened
+* `onSubmit` - called when the modal is submitted
+* `onReject` - called when the modal is rejected
+* `observeRouteBuilder` - called when the modal route changes. Use the given route builder to build a route to open the modal
+
+**Additional features of the route Registration:**
+
+* Adds unique parts to the path.
+* A modal registered in a dashboard can be setup in few steps
+* A modal registered in a property editor needs to become specific for the property and the variant of that property.
+* Builds some data for the setup.
+* Rejects a modal by returning false in setup.
+* Uses a parameter as part of the setup to determine the data going to the modal.
+
+## Modal registration for UI as part of a Property Editor
+
+When configuring a routed modal from a Property Editor, it's important to be aware of some facts. Those facts are that the Property Editor shares the same URL path as other Property Editors. This means we need to ensure the registration is unique so it doesn't collide with other Property Editors. To do so we will make use of the Property Alias and the Variant ID.
+
+```ts
+
+
+ @property()
+ public set alias(value: string | undefined) {
+ this.myModalRegistration.setUniquePathValue('propertyAlias', value);
+ }
+
+ @property()
+ public set variantId(value: string | UmbVariantId | undefined) {
+ this.myModalRegistration.setUniquePathValue('variantId', value?.toString());
+ }
+
+ private _items = [
+ { name: 'Item 1' },
+ { name: 'Item 2' },
+ { name: 'Item 3' },
+ ]
+
+
+ constructor() {
+ super();
+
+ this.myModalRegistration = new UmbModalRouteRegistrationController(
+ this,
+ MY_MODAL_TOKEN
+ )
+ .addAdditionalPath(`:index`)
+ .addUniquePaths(['propertyAlias', 'variantId'])
+ .onSetup((params) => {
+ // Get item index:
+ const indexParam = params.index;
+ if (!indexParam) return false;
+ let index: number | null = parseInt(params.index);
+ if (Number.isNaN(index)) return false;
+
+ // Use the index to find data:
+ let data = null;
+ if (index >= 0 && index < this._items.length) {
+ data = this._items[index];
+ } else {
+ // If not then make a new pick:
+ index = null;
+ }
+
+ return {
+ index: index,
+ itemData: {
+ name: data?.name
+ },
+ };
+ })
+ .onSubmit((submitData) => {
+ if (!submitData) return;
+ this._items[submitData.index] = submitData.itemData;
+ })
+ .observeRouteBuilder((routeBuilder) => {
+ this._modalRouteBuilder = routeBuilder;
+ });
+ }
+
+ render() {
+ return html`
+ ${this._items?.map((item, index) =>
+ html`Add`
+ )}
+ `;
+ }
+```
+
+**Generate the URL to a Modal Route Registration**
+
+The Modal registration has an option to retrieve a URL Builder. This is a function that can be used to generate a URL to a modal:
+
+```ts
+const modalLink = _myUrlBuilder?.({ alias: "my-input-alias" });
+```
+
+The `modalLink` from above could look like this: `/umbraco/backoffice/my/location/modal/Our.Modal.SomethingPicker/my-input-alias`
+
+Notice the Property Editor registration will add the property alias and variant ID to the URL, so it becomes:
+
+`/umbraco/backoffice/my/location/modal/Our.Modal.SomethingPicker/my-property-alias/en-us/my-input-alias`
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/monaco-markdown-editor-action.md b/16/umbraco-cms/customizing/extending-overview/extension-types/monaco-markdown-editor-action.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/package-view.md b/16/umbraco-cms/customizing/extending-overview/extension-types/package-view.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/preview-app-provider.md b/16/umbraco-cms/customizing/extending-overview/extension-types/preview-app-provider.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/property-action.md b/16/umbraco-cms/customizing/extending-overview/extension-types/property-action.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/property-editor-schema.md b/16/umbraco-cms/customizing/extending-overview/extension-types/property-editor-schema.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/property-editor-ui.md b/16/umbraco-cms/customizing/extending-overview/extension-types/property-editor-ui.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/property-value-preset.md b/16/umbraco-cms/customizing/extending-overview/extension-types/property-value-preset.md
new file mode 100644
index 00000000000..f5535e6339d
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/property-value-preset.md
@@ -0,0 +1,88 @@
+---
+description: Provide a preset value for a Property.
+---
+
+# Property Value Preset
+
+The Property Value Preset is an Extension Type that uses an API to provide a Preset Value. The preset value is used when a user scaffolds a new set of Content.
+
+The following Manifest declares a preset for the `Umb.PropertyEditorUi.TextBox` Property Editor UI:
+
+```typescript
+export const manifest = {
+ type: 'propertyValuePreset';
+ alias: 'my.propertyValuePreset.TextBox',
+ name: 'My Property Value Preset for TextBox',
+ api: () => import('./my-property-value-preset.js'),
+ forPropertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox'
+}
+```
+
+Such Property Preset Value API could look like this:
+
+{% code title="my-property-value-preset.js" %}
+```typescript
+export class MyPropertyValuePresetApi implements UmbPropertyValuePreset {
+ async processValue(value: undefined | string, config: UmbPropertyEditorConfig) {
+ return value ? value : 'Hello there';
+ }
+
+ destroy(): void {}
+}
+
+export { UmbTrueFalsePropertyValuePreset as api };
+```
+{% endcode %}
+
+This API will set the value to "Hello there" for all properties using the `Umb.PropertyEditorUi.TextBox` Property Editor UI.
+
+### Target a Property Editor Schema
+
+You can also choose to target your Preset for a Property Editor Schema.\
+\
+Define `forPropertyEditorSchemaAlias` to show the Preset Value for all Properties based on that Schema.
+
+If both `forPropertyEditorSchemaAlias` and `forPropertyEditorUiAlias` are defined, it will not limit the target. The matching is independently for each of them.
+
+Notice that `forPropertyEditorSchemaAlias` only targets the Properties used on the Content Type based data. This could affect Documents, Media, Members, and Blocks, and not properties of a Data Type Configuration.
+
+## Utilize the Data-Type configuration
+
+The `processValue` method takes two arguments, the current value of the Preset and the Data-Type Configuration.
+
+The following example is the built-in Property Value Preset for the Umbraco Toggle. The Toggle Data Type has a 'preset state' configuration that is used as the value of the Toggle.
+
+{% code title="my-property-value-preset.js" %}
+```typescript
+export class UmbTrueFalsePropertyValuePreset
+ implements UmbPropertyValuePreset
+{
+ async processValue(value: undefined | UmbTogglePropertyEditorUiValue, config: UmbPropertyEditorConfig) {
+ const initialState = (config.find((x) => x.alias === 'presetState')?.value as boolean | undefined) ?? false;
+ return value !== undefined ? value : initialState;
+ }
+
+ destroy(): void {}
+}
+
+export { UmbTrueFalsePropertyValuePreset as api };
+```
+{% endcode %}
+
+## Utilize anything
+
+The `processValue` method is async. You can request the server or use the Context-API to retrieve the necessary information to construct your value.
+
+{% hint style="info" %}
+**Only relevant for Umbraco 16 (release date: June 12th, 2025)**
+
+For retrieving contexts, upgrading to version 16, where the `getContext` method will have a timeout feature is recommended. In this case, such will be needed for the preset not to get stuck if the context is unavailable when the reset is constructed.
+{% endhint %}
+
+## Extend Presets
+
+Because the `processValue` method takes a value as its first argument, you can append the value constructed by other Presets. In this way, multiple Presets can shape the preset value for a property.
+
+In the case of multiple Property Value Presets targeting the same Property. The `weight` of the Manifest determines the order they are executed.
+
+This opens up for you to overwrite or alter the Preset Value for Properties that use a Built-in Property Value Preset.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/search-provider.md b/16/umbraco-cms/customizing/extending-overview/extension-types/search-provider.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/search-result-item.md b/16/umbraco-cms/customizing/extending-overview/extension-types/search-result-item.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/sections/README.md b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/README.md
new file mode 100644
index 00000000000..b3c2aa0ce97
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/README.md
@@ -0,0 +1,6 @@
+---
+description: >-
+ An overview of the availabe extension types related to sections.
+---
+
+# Extension Types: Sections
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-route.md b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-route.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-sidebar.md b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-sidebar.md
new file mode 100644
index 00000000000..3b008c02fe2
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-sidebar.md
@@ -0,0 +1,75 @@
+# Section Sidebar
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+
Section Sidebar
+
+## Section Sidebar Apps
+
+
Section Sidebar Apps
+
+**Manifest**
+
+```typescript
+{
+ "type": "sectionSidebarApp",
+ "alias": "My.SectionSidebarApp",
+ "name": "My Section Sidebar App",
+ "meta": {
+ "sections": ["My.Section"]
+ }
+}
+```
+
+**Default Element**
+
+```typescript
+interface UmbSectionSidebarAppElement {}
+```
+
+## **Menu Sidebar App**
+
+**Sidebar Menu**:
+
+* The Backoffice comes with a menu sidebar app that can be used to create a menu in the sidebar.
+* To register a new menu sidebar app, add the following to your manifest
+* The menu sidebar app will reference a menu that you have registered in the menu with a menu manifest
+
+
Menu Sidebar App
+
+**Manifest**
+
+```typescript
+{
+ "type": "sectionSidebarApp",
+ "kind": "menu",
+ "alias": "My.SectionSidebarApp.MyMenu",
+ "name": "My Menu Section Sidebar App",
+ "meta": {
+ "label": "My Sidebar Menu",
+ "menu": "My.Menu"
+ },
+ "conditions": [
+ {
+ "alias": "Umb.Condition.SectionAlias",
+ "match": "My.Section"
+ }
+ ]
+}
+```
+
+**Default Element**
+
+```typescript
+interface UmbMenuSectionSidebarAppElement {}
+```
+
+**Adding Items to an existing menu**
+
+This will make it possible to compose a sidebar menu from multiple Apps:
+
+
Composed sidebar menu
+
+You can read more about this in the [Menu](../menu.md) article.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-view.md b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-view.md
new file mode 100644
index 00000000000..39be2284a63
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section-view.md
@@ -0,0 +1,119 @@
+---
+description: >-
+ Append a secondary view for a Section, use it for additional features or
+ information.
+---
+
+# Section View
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+
Section View
+
+## Creating a custom Section View
+
+In this section, you can learn how to register and create a custom Section View for the Umbraco backoffice.
+
+### Manifest
+
+The manifest file can be created using either JSON or TypeScript. Both methods are shown below.
+
+{% tabs %}
+{% tab title="Json" %}
+We can create the manifest using json in the `umbraco-package.json`.
+
+```json
+{
+ "type": "sectionView",
+ "alias": "My.SectionView",
+ "name": "My Section View",
+ "element": "./my-section.element.js",
+ "meta": {
+ "label": "My View",
+ "icon": "icon-add",
+ "pathname": "my-view"
+ },
+ "conditions": [
+ {
+ "alias": "Umb.Condition.SectionAlias",
+ "match": "My.Section",
+ }
+ ]
+}
+```
+{% endtab %}
+
+{% tab title="TypeScript" %}
+The manifest can also be written in TypeScript.
+
+For this TypeScript example we used a [Backoffice Entry Point](../backoffice-entry-point.md) extension to register the manifests.
+
+```typescript
+import { ManifestSectionView } from '@umbraco-cms/backoffice/section';
+
+const sectionViews: Array = [
+ {
+ type: "sectionView",
+ alias: "My.SectionView",
+ name: "My Section View",
+ element: () => import('./my-section.element.ts'),
+ meta: {
+ label: "My View",
+ icon: "icon-add",
+ pathname: "my-view",
+ },
+ conditions: [
+ {
+ alias: 'Umb.Condition.SectionAlias',
+ match: 'My.Section',
+ }
+ ]
+ }
+]
+```
+{% endtab %}
+{% endtabs %}
+
+### Lit Element
+
+Creating the Section View Element using a Lit Element.
+
+**my-section.element.ts:**
+
+```typescript
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
+
+@customElement('my-sectionview-element')
+export class MySectionViewElement extends UmbLitElement {
+
+ override render() {
+ return html`
+
+ Sectionview content goes here
+
+ `
+ }
+
+ static override readonly styles = [
+ css`
+ :host {
+ display: block;
+ padding: 20px;
+ }
+ `,
+ ];
+
+}
+
+export default MySectionViewElement;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'my-sectionview-element': MySectionViewElement;
+ }
+}
+
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section.md b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section.md
new file mode 100644
index 00000000000..ea01a688e02
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/sections/section.md
@@ -0,0 +1,76 @@
+---
+description: A guide to creating a section
+---
+
+# Sections
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Umbraco backoffice consists of Sections. Section is the main division shown in the top navigation.
+
+For example, when you load the backoffice, you'll see the 'Content' section, 'Settings' section, and so on.
+
+You can create your own sections to extend Umbraco with room for more features.
+
+
Section
+
+## **Creating a section**
+
+### **Manifests**
+
+When creating a new section it's recommended to use a [Entry Point](../backoffice-entry-point.md)-extension in your [Umbraco Package Manifest](../../../umbraco-package.md). This is to get better control over all the additional extensions required for the new section.
+
+Create a section by defining a manifest for it:
+
+```typescript
+{
+ "type": "section",
+ "alias": "My.Section",
+ "name": "My Section",
+ "meta": {
+ "label": "My.Section",
+ "pathname": "my-section"
+ }
+}
+```
+
+Once registered, you will be able to select this action for your User Group Permissions. Once that is permitted, you can view your section.
+
+
Section
+
+#### **Extend with Sidebar, Dashboards and more**
+
+Once a section is registered, it can be extended like any other section.
+
+Here is a list of appropriate extensions to append to your section:
+
+* [Creating a Custom Dashboard](../../../../tutorials/creating-a-custom-dashboard/)
+* [Section Sidebar](section-sidebar.md)
+* [Section View](section-view.md)
+
+#### **Manifest with empty element**
+
+If you prefer full control over the content of your section you can choose to define an element for the content of your section.
+
+{% hint style="warning" %}
+This is not recommended as it limits the content of your section to this element. Instead, it is recommended to use a single Dashboard or Section View.
+{% endhint %}
+
+If you like to have full control, you can define an element like this:
+
+```typescript
+const section : UmbExtensionManifest = {
+ type: "section",
+ alias: "Empty.Section",
+ name : 'Empty Section',
+ element : () => import('./empty-section.element.js'),
+ meta : {
+ label : 'Empty Section',
+ pathname : 'empty-section'
+ }
+}
+```
+
+The element file must have an `element` or `default` export, or specify the element name in the `elementName` field.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/README.md b/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/README.md
new file mode 100644
index 00000000000..a87681d96ef
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/README.md
@@ -0,0 +1,6 @@
+---
+description: >-
+ An overview of the available extension types related to stores and repositories.
+---
+
+# Extension Types: Stores and repositories
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/item-store.md b/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/item-store.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/repository.md b/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/repository.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/store.md b/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/store.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/tree-store.md b/16/umbraco-cms/customizing/extending-overview/extension-types/stores-and-repositories/tree-store.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/theme.md b/16/umbraco-cms/customizing/extending-overview/extension-types/theme.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/tiny-mce-plugin.md b/16/umbraco-cms/customizing/extending-overview/extension-types/tiny-mce-plugin.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/tree-item.md b/16/umbraco-cms/customizing/extending-overview/extension-types/tree-item.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/tree.md b/16/umbraco-cms/customizing/extending-overview/extension-types/tree.md
new file mode 100644
index 00000000000..705fe19ac59
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/tree.md
@@ -0,0 +1,141 @@
+---
+description: A guide to creating a custom tree in Umbraco
+---
+
+# Trees
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The tree is a hierarchical structure of nodes and is registered in the Backoffice extension registry. A tree can be rendered anywhere in the Backoffice with the help of the umb-tree element.
+
+## Creating trees
+
+To Create a Tree in a section of the Umbraco backoffice, you need to take multiple steps:
+
+### Registering a tree
+
+The backoffice comes with two different tree item kinds out of the box: entity and fileSystem.
+
+Tree Manifest:
+
+```typescript
+// TODO: add interface
+{
+ "type": "tree",
+ "alias": "My.Tree.Alias",
+ "name": "My Tree",
+ "meta": {
+ "repositoryAlias": "My.Repository.Alias"
+ }
+},
+{
+ "type": "treeItem",
+ "kind": "entity",
+ "alias": "My.TreeItem.Alias",
+ "name": "My Tree Item",
+ "conditions": {
+ "entityType": "my-entity-type",
+ },
+}
+```
+
+### Rendering a tree
+
+```typescript
+
+```
+
+### Render a Custom Tree Item
+
+#### **The Tree Item Manifest**
+
+```typescript
+{
+ "type": "treeItem",
+ "alias": "Umb.TreeItem.Alias",
+ "name": "My Tree Item",
+ "element": "./my-tree-item.element.js",
+ "conditions": {
+ "entityType": "my-entity-type",
+ },
+};
+```
+
+#### The Tree Item Element
+
+```typescript
+import { css, html, nothing } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbMyTreeItemContext, MyTreeItemDataModel } from './my-tree-item.context';
+
+@customElement('my-tree-item')
+export class MyTreeItemElement extends UmbElementMixin(LitElement) {
+ private _item?: MyTreeItemDataModel;
+ @property({ type: Object, attribute: false })
+ public get item() {
+ return this._item;
+ }
+ public set item(value: MyTreeItemDataModel | undefined) {
+ this._item = value;
+ this.#context.setTreeItem(value);
+ }
+
+ #context = new UmbMyTreeItemContext(this);
+
+ render() {
+ if (!this.item) return nothing;
+ return html` Some custom markup `;
+ }
+}
+
+export default MyTreeItemElement;
+```
+
+#### The Tree Item Context
+
+```typescript
+// TODO: auto-generate this from the interface
+export interface UmbTreeItemContext {
+ host: UmbControllerHostElement;
+ unique?: string;
+ type?: string;
+
+ treeItem: Observable;
+ hasChildren: Observable;
+ isLoading: Observable;
+ isSelectable: Observable;
+ isSelected: Observable;
+ isActive: Observable;
+ hasActions: Observable;
+ path: Observable;
+
+ setTreeItem(treeItem: T | undefined): void;
+
+ requestChildren(): Promise<{
+ data: PagedResponse | undefined;
+ error: ProblemDetails | undefined;
+ asObservable?: () => Observable;
+ }>;
+ toggleContextMenu(): void;
+ select(): void;
+ deselect(): void;
+ constructPath(pathname: string, entityType: string, unique: string): string;
+}
+```
+
+#### Extending the Tree Item Context base
+
+We provide a base class for the tree item context. This class provides some default implementations for the context. You can extend this class to overwrite any of the default implementations.
+
+```typescript
+export class UmbMyTreeItemContext extends UmbTreeItemContextBase {
+ constructor(host: UmbControllerHostElement) {
+ super(host, (x: MyTreeItemDataModel) => x.unique);
+ }
+
+ // overwrite any methods or properties here if needed
+}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/ufm-component.md b/16/umbraco-cms/customizing/extending-overview/extension-types/ufm-component.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/user-profile-app.md b/16/umbraco-cms/customizing/extending-overview/extension-types/user-profile-app.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/README.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/README.md
new file mode 100644
index 00000000000..5581b2339ac
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/README.md
@@ -0,0 +1,6 @@
+---
+description: >-
+ An overview of the available extension types related to workspaces.
+---
+
+# Extension Types: Workspaces
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-action-menu-item.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-action-menu-item.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-context.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-context.md
new file mode 100644
index 00000000000..4ec5f1af6ed
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-context.md
@@ -0,0 +1,83 @@
+---
+description: Establish an extension to communicate across the application.
+---
+
+# Workspace Context
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A Workspace context is a container for the data of a workspace. It is a wrapper around the data of the entity that the workspace is working on. It is responsible for loading and saving the data to the server. Workspace Contexts are used to bring additional context alongside the default context of a workspace.
+
+* A workspace context knows about its entity type (for example content, media, member, etc.) and holds its unique string (for example: key).
+* Most workspace contexts hold a draft state of its entity data. It is a copy of the entity data that can be modified at runtime and sent to the server to be saved.
+
+If a workspace wants to utilize Property Editor UIs, then it must provide a variant context for the property editors. The variant-context is the generic interface between workspace and property editors.
+
+```ts
+interface UmbWorkspaceContext {}
+```
+
+## Example of Workspace
+
+## Example of Workspace Context
+
+The API will be initiated with the same host as the default Workspace Context.
+
+```typescript
+{
+ type: 'workspaceContext',
+ alias: 'My.WorkspaceContext.Counter',
+ name: 'My Counter Context',
+ api: 'my-workspace-counter.context.js',
+ conditions: [
+ {
+ alias: 'Umb.Condition.WorkspaceAlias',
+ match: 'Umb.Workspace.Document',
+ }
+ ]
+}
+```
+
+The code of such an API file could look like this:
+
+```typescript
+import {
+ UmbController,
+ UmbControllerHost,
+} from "@umbraco-cms/backoffice/controller-api";
+import { UmbContextToken } from "@umbraco-cms/backoffice/context-api";
+import { UmbNumberState } from "@umbraco-cms/backoffice/observable-api";
+
+export class MyContextApi extends UmbController {
+ #counter = new UmbNumberState(0);
+ readonly counter = this.#counter.asObservable();
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+ this.provideContext(UMB_APP_CONTEXT, this);
+ }
+
+ increment() {
+ this.#counter.next(this.#counter.value + 1);
+ }
+}
+
+export const api = MyContextCounterApi;
+```
+
+{% hint style="info" %}
+Context APIs have to be self-providing. To do so it has to be an Umbraco Controller.
+{% endhint %}
+
+A Context Token for a Workspace Context Extension should look like this:
+
+```typescript
+export const UMB_APP_CONTEXT = new UmbContextToken(
+ "UmbWorkspaceContext",
+ "My.WorkspaceContext.Counter"
+);
+```
+
+We recommend using `UmbWorkspaceContext` as the Context Alias for your Context Token. This will ensure that the requester only retrieves this Context if it's present at their nearest Workspace Context. Use the Extension Manifest Alias as the API Alias for your Context Token. For more information, see the [Context API](../../../foundation/working-with-data/context-api.md) article.
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-editor-actions.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-editor-actions.md
new file mode 100644
index 00000000000..2eb896ea50a
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-editor-actions.md
@@ -0,0 +1,55 @@
+# Workspace Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Workspace actions are a set of functionalities or operations that can be performed within a workspace. These actions involve creating documents within the workspace, organizing and categorizing documents, publishing content and so on.
+
+Workspace action relates to a workspace alias (Umb.Workspace.Document) and has Access to the workspace context.
+
+
+
+## The Workspace Action Class
+
+As part of the Extension Manifest you can attach a class that will be instantiated as part of the action. It will have access to the host element and the Workspace Context. When the action is clicked the `execute` method on the API class will be run. When the action is completed, an event on the host element will be dispatched to notify any surrounding elements.
+
+```ts
+import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace';
+
+export class MyWorkspaceAction extends UmbWorkspaceActionBase {
+ execute() {
+ this.workspaceContext.myAction(this.selection);
+ }
+}
+```
+
+**Default Element**
+
+```typescript
+interface UmbWorkspaceActionElement {}
+```
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-footer-app.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-footer-app.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-views.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-views.md
new file mode 100644
index 00000000000..7f46a46edf0
--- /dev/null
+++ b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace-views.md
@@ -0,0 +1,100 @@
+---
+description: Append a view to any Workspace
+---
+
+# Workspace Views
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+{% hint style="info" %}
+Workspace Views was previously called Content Apps.
+{% endhint %}
+
+Workspace Views are customizable companion **tabs** with the ability to take place in any workspace.
+
+
Workspace Views
+
+**In Content Section**
+
+With Workspace Views, editors can switch from editing 'Content' to accessing contextual information related to the item they are editing.
+
+The default workspace view is **'Info'** - displaying Links, History and Status of the current content item.
+
+## Example of a Workspace View
+
+1. Follow the [Vite Package Setup](../../../development-flow/vite-package-setup.md) by creating a new project folder called "`workspaceview`" in `App_Plugins`.
+2. Create a manifest file named `umbraco-package.json` at the root of the `workspaceview` folder. Here we define and configure our workspace view.
+3. Add the following code to `umbraco-package.json`:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My workspace",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "workspaceView",
+ "alias": "My.WorkspaceView",
+ "name": "My Workspace View",
+ "element": "/App_Plugins/workspaceview/dist/workspaceview.js",
+ "meta": {
+ "label": "My Workspace View",
+ "pathname": "/my-workspace-view",
+ "icon": "icon-add"
+ },
+ "conditions": [
+ {
+ "alias": "Umb.Condition.WorkspaceAlias",
+ "match": "Umb.Workspace.Document"
+ }
+ ]
+ }
+ ]
+}
+```
+{% endcode %}
+
+4. Add the following code to the existing `my-element.ts` from the `src`folder:
+
+{% code title="my-element.ts" lineNumbers="true" %}
+```typescript
+import { LitElement, html, customElement, css } from "@umbraco-cms/backoffice/external/lit";
+import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
+
+@customElement('my-workspaceview')
+export default class MyWorspaceViewElement extends UmbElementMixin(LitElement) {
+
+ render() {
+ return html`
+
+ Welcome to my newly created workspace view.
+
+ `
+ }
+
+ static styles = css`
+ uui-box {
+ margin: 20px;
+ }
+ `
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'my-workspaceview': MyWorspaceViewElement
+ }
+}
+
+```
+{% endcode %}
+
+In the `workspaceview` folder run `npm run build` and then run the project. Then in the content section of the Backoffice you will see our new Workspace View:
+
+
Workspace View Example
+
+{% hint style="info" %}
+To see the Workspace View that we have created in the content section, first you will need to have some content created.
+{% endhint %}
diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace.md b/16/umbraco-cms/customizing/extending-overview/extension-types/workspaces/workspace.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/16/umbraco-cms/customizing/foundation/README.md b/16/umbraco-cms/customizing/foundation/README.md
new file mode 100644
index 00000000000..a71168b8642
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/README.md
@@ -0,0 +1,35 @@
+---
+description: Getting started with backoffice setup and configurations
+---
+
+# Foundation
+
+In this section, you can find the common terms, concepts, and guides used to extend the Umbraco backoffice.
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## [Working with Bellissima](https://github.com/umbraco/Umbraco.Packages/tree/main/bellissima)
+
+An overview of community articles related to the New backoffice "Bellissima".
+
+## [Working with Data](working-with-data/)
+
+An overview of concepts on how to work with data when extending the backoffice.
+
+## [Contexts](contexts/)
+
+An overview of concepts on how to work with contexts when extending the backoffice.
+
+## [Umbraco Element](umbraco-element/)
+
+An overview of concepts on how to work with Umbraco element when extending the backoffice.
+
+## [Sorting](sorting.md)
+
+An overview of concepts on how to work with sorting when extending the backoffice.
+
+## [Routes](routes.md)
+
+An overview of concepts on how to work with routes when extending the backoffice.
diff --git a/16/umbraco-cms/customizing/foundation/contexts/README.md b/16/umbraco-cms/customizing/foundation/contexts/README.md
new file mode 100644
index 00000000000..b9e7ce16f9a
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/contexts/README.md
@@ -0,0 +1,15 @@
+---
+description: Contexts
+---
+
+# Contexts
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Below you can find some articles on how you can work with different contexts:
+
+## [Property Dataset Context](./property-dataset-context.md)
+
+A Dataset Context is the connection point between a Property Editor and a Workspace and covers a set of properties.
diff --git a/16/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md b/16/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md
new file mode 100644
index 00000000000..8fb610ae303
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md
@@ -0,0 +1,25 @@
+---
+description: The Variant Context is a context that holds the data for a set of properties.
+---
+
+# Property Dataset Context
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Property Editors UIs require the Dataset Context to be present to work. This enables Property Editor UIs to have a generic relation with its ownership.
+
+The Dataset Context holds a name and a set of properties. What makes a property can vary but an alias and a value are required.
+
+### Dataset Context Concerning Property Editors and Workspaces
+
+A Dataset Context is the connection point between a Property Editor and a Workspace.
+
+The hierarchy is as follows:
+
+* Workspace Context
+ * Dataset Context
+ * Property Editor UIs
+
+A dataset context covers a set of properties, in some cases a workspace then needs to have multiple variants. An example of such is Document Workspace. Each variant has its own set of properties and a name.
diff --git a/16/umbraco-cms/customizing/foundation/icons.md b/16/umbraco-cms/customizing/foundation/icons.md
new file mode 100644
index 00000000000..255b38b2040
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/icons.md
@@ -0,0 +1,3 @@
+# Icons
+
+The icons from the Umbraco backoffice are based on [Lucide Icons](https://lucide.dev/). The syntax for getting the icons starts with`icon-`. You can find the list of all icons in the [Icon registry list on GitHub](https://github.com/umbraco/Umbraco.CMS.Backoffice/tree/762e43b2f49ca483df9cfe28de20f31ca07bb22b/src/packages/core/icon-registry/icons).
diff --git a/16/umbraco-cms/customizing/foundation/localization.md b/16/umbraco-cms/customizing/foundation/localization.md
new file mode 100644
index 00000000000..d96f6ce4663
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/localization.md
@@ -0,0 +1,194 @@
+---
+description: Learn how to manage and use the Backoffice UI Localization files.
+---
+
+# Backoffice Localization
+
+This article describes how you can translate the Umbraco Backoffice UI into different languages. You can use the existing localizations from Umbraco or register your own localizations. You can also use the localization in your custom elements and controllers.
+
+## Registering Localization
+
+Localizations can be registered via the Extension Registry. [Read more about the Localization Extension Type](../extending-overview/extension-types/localization.md).
+
+### Missing Localization Keys
+
+As Umbraco is an evolving product, new text is regularly added to the English version of these files. Therefore, some of the languages may no longer be up-to-date.
+
+If a key is not found in the current language, the fallback language will be used. The fallback language is **English** with the culture code **en**.
+
+If a translation is missing, the default value within `umb-localize` will be shown in the user interface:
+
+```html
+Default value
+```
+
+Instead of showing the default value we can show the key alias if we set `debug="true"`:
+
+```html
+
+```
+
+## Using the Localizations
+
+### Localize Element
+
+The following example shows how you can display localized text with the `umb-localize` element:
+
+```html
+
+```
+
+{% hint style="info" %}
+You can have a look and try out the element in the [UI API Documentation](https://apidocs.umbraco.com/v15/ui/?path=/docs/api-localization-umblocalizeelement--docs).
+{% endhint %}
+
+### **Localize Controller**
+
+In some situations, you need the localization as a variable that can be parsed. In this case, the Localization Controller can be used in your `element.ts` file. This can be setup in two ways:
+
+* Using [Umbraco Element](localization.md#umbraco-element)
+* Using [Umbraco Controller](localization.md#umbraco-controller)
+
+#### Umbraco Element
+
+When using an [**Umbraco Element**](../../customizing/foundation/umbraco-element/)**,** the **Localization Controller** is already initialized on the `localize` property via the `UmbElementMixin`.
+
+```typescript
+import { LitElement, css, html } from "lit";
+import { customElement } from "@umbraco-cms/backoffice/external/lit";
+import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
+
+export default class MyElement extends UmbElementMixin(LitElement) {
+ render() {
+ return html`
+ `;
+ }
+}
+```
+
+The arguments will be passed to the function in the localization file if it is a function.
+
+#### Umbraco Controller
+
+If you are working with an Umbraco Controller, then you need to initialize the Localization Controller on your own via the `UmbLocalizationController`:
+
+```typescript
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
+
+export class MyController extends UmbControllerBase {
+ // Create a new instance of the controller and attach it to the element
+ #localize = new UmbLocalizationController(this);
+
+ render() {
+ return html` `;
+ }
+}
+```
+
+## Using arguments
+
+Sometimes you need to pass arguments to the localization to return different values based on the arguments. A localization value can be either a string or a function. Given a localization file like this, we can return different values based on the number of items:
+
+```javascript
+export default {
+ section: {
+ numberOfItems: (count) => {
+ count = parseInt(count, 10);
+ if (count === 0) return 'Showing nothing';
+ if (count === 1) return 'Showing only one item';
+ return `Showing ${count} items`;
+ },
+ },
+};
+```
+
+{% hint style="info" %}
+You can try out the arguments feature in the [UI API Documentation](https://apidocs.umbraco.com/v15/ui/?path=/story/api-localization-umblocalizeelement--with-arguments).
+{% endhint %}
+
+**Using the Localize Element**
+
+You can pass arguments to the localization by adding them as additional attributes:
+
+```html
+
+Showing items
+```
+
+The arguments will be passed to the function in the localization file if it is a function. The `args` attribute must be JSON-serializable and each array value will be passed to the function as an extra argument.
+
+**Using the Localize Controller**
+
+You can pass arguments to the localization by calling the `term` method with the arguments:
+
+```typescript
+// Outputs: Showing 5 items
+this.localize.term('section_numberOfItems', 5);
+```
+
+The arguments will be passed to the function in the localization file if it is a function. Each argument of `term` will be passed to the function as an extra argument.
+
+### Using placeholders
+
+You can also use placeholders in the localization keys to replace parts of the string with dynamic values. Placeholders are defined by curly braces `{0}` or percentage signs `%0%` in the localization key. The placeholders will be replaced one-to-one with the arguments passed to the localization. It works the same as the arguments feature, except you cannot calculate the value based on the arguments.
+
+Given a localization file like this:
+
+{% code title="en.js" %}
+```javascript
+export default {
+ section: {
+ numberOfItems: 'Showing {0} items',
+ },
+};
+```
+{% endcode %}
+
+You can use the same `args` attribute to pass the arguments:
+
+```html
+
+
+```
+
+### Using with manifests
+You can localize values in a manifest. For example, prefix the name of the dashboard tab visible in the UI with a `#`.
+
+#### Example
+A manifest registering a dashboard with `umbraco-package.json` or JavaScript can localize the `label` property in the `meta` object like this.
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+
+```json
+{
+ "name": "My.WelcomePackage",
+ "extensions": [
+ {
+ "type": "dashboard",
+ ...
+ "meta": {
+ "label": "#welcomeDashboard_label",
+ "pathname": "welcome-dashboard"
+ },
+ },
+ ]
+}
+```
+
+{% endcode %}
+
+
+## Examples
+
+You can add your own localization keys using the principles you have learned, and apply them in a number of ways:
+
+### Using localization in a custom element
+
+You can find a localization example in the [Adding localization to the dashboard](../../tutorials/creating-a-custom-dashboard/adding-localization-to-the-dashboard.md) article. This will get you started with using localization in your custom elements. You can apply the same principles to all extensions.
+
+### Using localization in property descriptions and labels
+
+Property descriptions and labels can also be localized. They are formatted as Markdown and can contain localization keys using the built-in [Umbraco Flavored Markdown](../../reference/umbraco-flavored-markdown.md) syntax.
diff --git a/16/umbraco-cms/customizing/foundation/routes.md b/16/umbraco-cms/customizing/foundation/routes.md
new file mode 100644
index 00000000000..8dd3d3f0340
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/routes.md
@@ -0,0 +1,72 @@
+---
+description: Get started with Routing in the backoffice.
+---
+
+# Routes
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## Routing
+
+The routing in the backoffice is flexible and customizable. In this article, you can find a couple of starting points for routing.
+
+The overall **divider** is the [Section](../extending-overview/extension-types/sections/README.md) which is a `ManifestSection` extension type. It is also used internally by the following sections: Content, Media, Settings, Members, and so on.
+
+Depending on which section you are working on, there are different options:
+
+* **SectionView**: The [Section View](../extending-overview/extension-types/sections/section-view.md) is a view in a section and one of the automatic router extension types. It can be an entry point to a section. If a section has multiple views defined (or both dashboards and views) then the tabs and icons will be rendered. As some examples, you can check the **Packages** and **Member** sections.
+* **Dashboard**: The [Dashboard](../extending-overview/extension-types/dashboard.md) is an entry point to a section. If there is more than one section view or dashboard then the defined tabs and icons will be rendered to make it possible to navigate.
+* **Workspace**: The [Workspace](../../customizing/workspaces.md) concept has built-in features to facilitate editing of an entity of a certain entity type. It is used by many entities in the backoffice like content, media, content types, data types, dictionaries and so on.
+* **Custom element**: A [Custom Element](umbraco-element/README.md) is a section that can be configured to use any web component as the **entry point**. The `element()` can be configured in the manifest. By doing this we'll disable the possibility of using dashboards and section views for the section since they will not be automatically routed/rendered. This option should be used only when necessary.
+
+### Building routing
+
+Almost any component can host routable sub-components by defining a list of routes and render a `umb-router-slot` element. Let's assume we have a **custom section** with pathname `custom-section` and a **section view** with pathname `organization`. In this context we can create an element with routes, like this:
+
+```typescript
+@state()
+_routes: UmbRoute[] = [
+ {
+ // Adding :personId as a parameter
+ path: 'person/:personId',
+ component: () => import('./person.element.js'),
+ setup: (_component, info) => {
+
+ console.log('personId:',info.match.params.personId);
+ },
+ },
+ {
+ path: 'people',
+ component: () => import('./people.element.js'),
+ setup: (_component, info) => {
+
+ console.log('view-route-info',info);
+
+ },
+ },
+ {
+ path: '',
+ redirectTo: 'people',
+ },
+];
+```
+
+{% hint style="info" %}
+The order in which the routes are defined is important as the first match will be used. So make sure to add more specific routes in the beginning.
+{% endhint %}
+
+In the render method of the element, render the `umb-router-slot`:
+
+```html
+
+```
+
+One can create links to allow navigation to a given route:
+
+```html
+People
+Person 1
+Person 2
+```
diff --git a/16/umbraco-cms/customizing/foundation/sorting.md b/16/umbraco-cms/customizing/foundation/sorting.md
new file mode 100644
index 00000000000..1e7449deeee
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/sorting.md
@@ -0,0 +1,96 @@
+---
+description: Enable sorting elements via drag and drop
+---
+
+# Sorting
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Umbraco Sorter enables you to make a list of elements sortable via drag-and-drop interaction. You have to set up the sorter once on the Element that renders the items to be sorted. As part of the configuration, you shall provide an `onChange` callback method, which will be executed every time the sorter makes a difference to the data.
+
+### Configuration
+
+The following example shows a basic setup of the Sorter.
+
+```typescript
+
+type ModelEntryType = {
+ id: string;
+ name: string;
+}
+
+this.#sorter = new UmbSorterController(this, {
+ itemSelector: '.sorter-item',
+ containerSelector: '.sorter-container',
+ getUniqueOfElement: (element) => {
+ return element.getAttribute('data-sorter-id');
+ },
+ getUniqueOfModel: (modelEntry) => {
+ return modelEntry.id;
+ },
+ onChange: ({ model }) => {
+ const oldValue = this._items;
+ this._items = model;
+ this.requestUpdate('_items', oldValue);
+ },
+});
+```
+
+The properties provided are the following:
+
+* `itemSelector`: A query selector that matches the items that should be draggable.
+* `containerSelector`: A query elector that matches the parent element of the items.
+* `getUniqueOfElement`: A method that returns the unique element
+* `getUniqueOfModel`: Provide a method that returns the unique of a given model entry
+* `onChange`: Provide a method to retrieve the changed model. This is called every time the model is changed, including when the user is dragging around.
+
+### Data Model
+
+The model given to the Sorter must be an Array. The following example extends the example from above:
+
+```typescript
+
+ const model: Array = [
+ {
+ id: 1,
+ name: 'First item'
+ },
+ {
+ id: 2,
+ name: 'second item'
+ }
+ {
+ id: 3,
+ name: 'Third item'
+ }
+ ]
+
+ // Set the Model, if you have changes to the model not coming from the Sorter. Then set the model again:
+ this.#sorter.setModel(model);
+```
+
+### Rendering
+
+The Sorter does not move elements, instead, it updates the model as the user drags an item around. This puts higher pressure on the rendering of the sortable Elements. This means we need to make sure that the rendering re-uses the same element despite sorting the data differently.
+
+Lit does provide a render helper method called `repeat` that does this for us. The following example shows a render method that continues the work of the examples above:
+
+```typescript
+
+
+ render() {
+ return html`
+
+ ${repeat(
+ this._items,
+ (item) => item.id,
+ (item) =>
+ html`${item.name}
+ `,
+ )}
+
+ `;
+ }
+```
diff --git a/16/umbraco-cms/customizing/foundation/terminology.md b/16/umbraco-cms/customizing/foundation/terminology.md
new file mode 100644
index 00000000000..9651ea3064f
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/terminology.md
@@ -0,0 +1,23 @@
+---
+description: A list of some of the key concepts with working the Umbraco Backoffice.
+---
+
+# Terminology
+
+Understanding certain key concepts is essential when customizing the backoffice. These terminologies can help you decode the purpose of code effectively:
+
+* **Repository:** An API enables communication with a server.
+* **Store:** An API representing data, generally coming from the server. Most stores would talk with one or more resources. You can read more about this in the [Store](../../customizing/foundation/working-with-data/store.md) article.
+* **State:** A reactive container holding data, when data is changed all its Observables will be notified. You can read more about state and observables in the [States](../../customizing/foundation/working-with-data/states.md) article.
+ * **Observable:** An observable is the hook for others to subscribe to the data of a State.
+ * **Observe:** Observe describes what we do when subscribing to an Observable.
+* **Context-API:** The name used to serve APIs (instances/classes) for a certain context in the DOM. An API that is served via the Context-API is called a Context. You can read more about this in the [Context API](../../customizing/foundation/working-with-data/context-api.md) article.
+ * **Context Provider:** One that provides a class instance as a Context API.
+ * **Context Consumer:** One that consumer subscribes to a class instance as a Context API.
+* **Controller:** An abstract term for a thing that hooks into the lifecycle of an element. Many things in our system are Controllers.
+* **Umbraco Controller:** Enables hosting controllers. Additionally, it provides a few shortcut methods for initializing core Umbraco Controllers. You can read more about this in the [Controllers](../../customizing/foundation/umbraco-element/controllers/) article.
+ * **Controller Host:** A class that can host controllers.
+ * **Controller Host Element:** The element that can host controllers.
+* **Umbraco Element:** The `UmbLitElement` or `UmbElemenMixin` enables hosting controllers. Additionally, it provides a few shortcut methods for initializing core Umbraco Controllers. You can read more about this in the [Umbraco Element](../../customizing/foundation/umbraco-element/) article.
+
+Read more about how to get started with extending the backoffice in the [Backoffice Setup](../../customizing/extending-overview/) article.
diff --git a/16/umbraco-cms/customizing/foundation/umbraco-element/README.md b/16/umbraco-cms/customizing/foundation/umbraco-element/README.md
new file mode 100644
index 00000000000..d0a557de110
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/umbraco-element/README.md
@@ -0,0 +1,29 @@
+---
+description: Ease the integration with Backoffice by using a Umbraco Element
+---
+
+# Umbraco Element
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+This provides a few methods to connect with the Backoffice, giving you the ability to:
+
+* Consume a Context — [Learn more about Consuming Contexts](../working-with-data/context-api.md)
+* Provide Context — [Learn more about Providing Contexts](../working-with-data/context-api.md#provide-a-context-api)
+* Observe a State — [Learn more about States](../working-with-data/states.md#observe-a-state-via-umbraco-element-or-umbraco-controller)
+* Localization — [Learn more about Localization](../../../extending/language-files/)
+* Host Controllers — [Learn more about Controllers](controllers/)
+
+## Create an Umbraco Element
+
+You can turn any Web Component into an Umbraco Element by using the Umbraco Element Mixin, as done in the following example:
+
+```ts
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'
+
+class MyExtensionElement extends UmbElementMixin(HTMLElement) {
+
+}
+```
diff --git a/16/umbraco-cms/customizing/foundation/umbraco-element/controllers/README.md b/16/umbraco-cms/customizing/foundation/umbraco-element/controllers/README.md
new file mode 100644
index 00000000000..986f1f6e350
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/umbraco-element/controllers/README.md
@@ -0,0 +1,48 @@
+# Controllers
+
+A Controller enables a class to hook into the life cycle of a Web Component
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Controllers have the ability to declare the following methods:
+
+* `hostConnected()` — Called when the Host Element is Connected to the DOM.
+* `hostDisconnected()` — Called when the Host Element is Disconnected from the DOM.
+* `destroy()` — Called when the controller is taken out of commission.
+
+Additionally, the Umbraco Controllers implement a `getHostElement()` method, which enables any Controller to receive the Element that hosts the Controllers.
+
+### Host Element
+
+A Controller will have to be assigned to a Host Element. An assignment can be indirect as Controllers can host other Controllers.
+
+The Host Element is a Controller Host Web Component. The Umbraco Element turns any Web Component into a Controller Host. For more information check the [Umbraco Element](../) article.
+
+### Controller Alias
+
+Any controller can be identified by a Controller Alias, using either a **String** or **Symbol**.\
+If you utilize a Controller with a Controller Alias, then it will be destroyed when another Controller with same Alias gets Added to same Host.\
+\
+In this way, you can keep your controllers tidy, without a lot of managing.\
+\
+The example below shows how to initialize a Controller with a Controller Alias.
+
+
+function mySetActiveDocument(id: string) {
+ new UmbObserverController(
+ this.#host,
+ this.myGetObservableForDocumentOfId(id),
+ (document) => {
+ // Callback receiving the specific document.
+ Console.log("Active document data ", document)
+ },
+ '_observeStateById',
+ );
+}
+
+
+The creation of this Controller will replace its previous instance. Leaving only the latest observation to be present, as the previous instance will be removed and destroyed.
+
+You can find another example in the [Write your own Controller](write-your-own-controller.md) article.
diff --git a/16/umbraco-cms/customizing/foundation/umbraco-element/controllers/write-your-own-controller.md b/16/umbraco-cms/customizing/foundation/umbraco-element/controllers/write-your-own-controller.md
new file mode 100644
index 00000000000..6c160b48ffe
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/umbraco-element/controllers/write-your-own-controller.md
@@ -0,0 +1,31 @@
+---
+description: Reuse functionality across components by writing it as a Controller
+---
+
+# Write your own Controller
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A Controller must follow the interface of UmbController. To ease the implementation you can base your class on the `UmbControllerBase`:
+
+```typescript
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+class MyController extends UmbControllerBase {
+
+ hostConnected() {
+ super.hostConnected();
+ // Your code when the Host element is connected.
+ }
+ hostDisconnected() {
+ super.hostDisconnected();
+ // Your code when the Host element is disconnected.
+ }
+ destroy() {
+ super.destroy();
+ // Your code for when this controller gets destroyed.
+ }
+}
+```
diff --git a/16/umbraco-cms/customizing/foundation/working-with-data/README.md b/16/umbraco-cms/customizing/foundation/working-with-data/README.md
new file mode 100644
index 00000000000..bff06641049
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/working-with-data/README.md
@@ -0,0 +1,23 @@
+# Working with Data
+
+Learn how to work with data or request the data when extending the backoffice.
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## [Repositories](repositories.md)
+
+Repositories are used for talking to the server by requesting data and getting notified about updates.
+
+## [Context API](context-api.md)
+
+Context APIs work with “local/runtime” data and enables receiving APIs.
+
+## [Store](store.md)
+
+A store holds data throughout the session. It is used to create reactivity across different parts.
+
+## [States](states.md)
+
+A reactive container holding data, when data is changed all its Observables will be notified.
diff --git a/16/umbraco-cms/customizing/foundation/working-with-data/context-api.md b/16/umbraco-cms/customizing/foundation/working-with-data/context-api.md
new file mode 100644
index 00000000000..bb2c8ed5f9c
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/working-with-data/context-api.md
@@ -0,0 +1,200 @@
+---
+description: Communicate across different boundaries with the Context API
+---
+
+# Context API
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Context API enables receiving APIs. Depending on where your code is executed from, it affects which and what instances of APIs can be received.
+
+The Context API enables an element or a controller to receive an API provided via any ascending element. In other words, it can receive APIs provided via a parent element or parent of a parent element, and so forth.
+
+The Context API enables connections between Elements and APIs. DOM structure defines the context of which an API is exposed for. APIs are provided via an element and can then be consumed by any decending element.
+
+## Consume a Context API
+
+There are different ways to consume a Context API. The most straightforward implementation is done on an Umbraco Element with a Context Token.
+
+All Umbraco Context APIs have a Context Token which can be imported and used for consumption, for example:
+
+```typescript
+import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
+
+...
+
+this.consumeContext(UMB_NOTIFICATION_CONTEXT, (context) => {
+ // Notice this is a subscription, as the context might change or a new one appears.
+ console.log("I've got the typed context: ", context);
+});
+```
+
+The above example takes place in an Umbraco Element or Umbraco Controller.
+
+### Alternative solutions
+
+The above examples utilize an Umbraco Controller to hook into an element's life cycle. This Controller is named `UmbContextConsumerController`.
+
+If you need to consume a Context API from a non-controller host, then look at the `UmbContextConsumer`.
+
+## **Write your own Context Token**
+
+A Context Token is a context identifier and is generally a string matched with a type. In this way, users of the token can be sure to get the right type of context.
+
+```typescript
+import { UmbContextToken } from "@umbraco-cms/backoffice/context-api";
+
+type MyContext = {
+ foo: string;
+ bar: number;
+};
+
+const MY_CONTEXT = new UmbContextToken ("My.Context.Token");
+```
+
+### **Context Token with an API Alias**
+
+For additions to Contexts, we can use the API Aliases to identify the additional API. Using the same Context Alias for additional APIs will ensure that such API must be present with the first encounter of that Context Alias. Otherwise, a request will be rejected. In other words, if the addition is not part of the nearest matching Context, the request will be rejected.
+
+{% hint style="info" %}
+Using API Alias only provides value when two or more APIs should share the same Context. This is needed for Context Extensions that are provided along with other Contexts.
+{% endhint %}
+
+```typescript
+import { UmbContextToken } from "@umbraco-cms/backoffice/context-api";
+
+type MyAdditionalContext = {
+ additional: string;
+};
+
+const MY_ADDITIONAL_API_TOKEN = new UmbContextToken(
+ "My.ContextFrame.Alias",
+ "My.API.Alias"
+);
+```
+
+The Token declared above can be used to provide an additional Context API at the same Element as another Context API is provided at. Below is an example of how the two APIs are made available.
+
+```typescript
+const contextElement = new UmbLitElement();
+contextElement.provideContext(
+ MY_API_TOKEN,
+ new MyAPiFromSomewhereNotPartOfThisExample()
+);
+contextElement.provideContext(
+ MY_ADDITIONAL_API_TOKEN,
+ new MyAdditionalAPiFromSomewhereNotPartOfThisExample()
+);
+
+const consumerElement = new UmbLitElement();
+contextElement.appendChild(consumerElement);
+consumerElement.consumeContext(MY_API_TOKEN, (context) => {
+ console.log("I've got the default api", context);
+});
+consumerElement.consumeContext(MY_ADDITIONAL_API_TOKEN, (context) => {
+ console.log("I've got the additional api", context);
+});
+```
+
+This is no different than using two different Context Aliases. But it has an important effect on what happens if one of them is not provided. This is demonstrated in the example below:
+
+```typescript
+const upperContextElement = new UmbLitElement();
+
+const contextElement = new UmbLitElement();
+upperContextElement.appendChild(contextElement);
+contextElement.provideContext(
+ MY_API_TOKEN,
+ new MyAPiFromSomewhereNotPartOfThisExample()
+);
+
+const consumerElement = new UmbLitElement();
+contextElement.appendChild(consumerElement);
+consumerElement.consumeContext(MY_API_TOKEN, (context) => {
+ console.log("I've got the default api", context);
+});
+consumerElement.consumeContext(MY_ADDITIONAL_API_TOKEN, (context) => {
+ // This will never happen
+ console.log("I've got the additional api", context);
+});
+```
+
+The consumption of the Additional API will never happen as the token uses the same Context Alias as `MY_API_TOKEN`. This means that any request containing this Context Alias will be stopped at the first API it encounters. To ensure addition to a specific context, do it locally at the nearest API that uses the same Context Alias.
+
+### **Context Token with a Type Discriminator**
+
+{% hint style="info" %}
+This is only relevant if you are going to make multiple context API for the same context. Discriminator only gives value for consumption of Context APIs that have a varying interface. The backoffice uses this for the different types of Workspace Contexts.
+{% endhint %}
+
+In some cases, it is needed to have different APIs for the same context. For example, the [Workspace Contexts](../../extending-overview/extension-types/workspaces/workspace-context.md).
+
+If someone wants the workspace name, they might not care about the specific API of the Workspace Context. These implementations can use a standard Context Token with a type of generic Workspace Context.
+
+The features related to Publishing in the **Document Workspace Context** do not require a new Context. However, we should not accidentally retrieve the workspace context of a parent workspace when in a Workspace. Therefore, we need to provide a workspace context in each workspace, and the one we retrieve is the one we will be using. Since Publishing is not part of the generic Workspace Context, check if the context is a Document Workspace Context and recast it accordingly.
+
+To avoid each implementation taking care of this, Context Tokens can be extended with a **Type Discriminator**. This will discard the given API if it does not meet the necessary requirements. When it is the desired type, the API will be converted to the appropriate type.
+
+This example shows how to create a discriminator Context Token that will discard the API if it is not a Publishable Context:
+
+**Context Token Example:**
+
+```typescript
+import { UmbContextToken } from "@umbraco-cms/backoffice/context-api";
+
+
+interface MyBaseContext {
+ foo: string;
+ bar: number;
+}
+
+interface MyPublishableContext extends MyBaseContext {
+ publish();
+}
+
+const MY_PUBLISHABLE_CONTEXT = new UmbContextToken<
+
+ MyContext,
+ MyPublishableContext
+>("My.Context.Token", (context): context is MyPublishableContext => {
+ return "publish" in context;
+});
+```
+
+**Implementation of Context Token Example:**
+
+```typescript
+const contextElement = new UmbLitElement();
+contextElement.provideContext(
+ MY_PUBLISHABLE_CONTEXT,
+ new MyPublishableContext()
+);
+
+const consumerElement = new UmbLitElement();
+contextElement.appendChild(contextElement);
+consumerElement.consumeContext(MY_PUBLISHABLE_CONTEXT, (context) => {
+
+ // context is of type 'MyPublishableContext'
+ console.log("I've got the context of the right type", context);
+});
+```
+
+This allows implementers to request a publishable context without needing to know the Type or how to identify the context.
+
+In detail, the Context API will search for the first API that matches the alias `My.Context.Token`, and not look further. If the API meets the type discriminator, it will be returned, otherwise the consumer will never reply.
+
+## Provide a Context API
+
+You can provide a Context API from an Umbraco Element or Umbraco Controller:
+
+```typescript
+this.provideContext('myContextAlias', new MyContextApi());
+```
+
+Or with a Controller using a 'host' reference to Controller Host (Umbraco Element/Controller):
+
+```typescript
+new UmbContextProviderController(host, 'myContextAlias', new MyContextApi());
+```
diff --git a/16/umbraco-cms/customizing/foundation/working-with-data/repositories.md b/16/umbraco-cms/customizing/foundation/working-with-data/repositories.md
new file mode 100644
index 00000000000..b094f93569e
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/working-with-data/repositories.md
@@ -0,0 +1,31 @@
+# Repositories
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A repository is the Backoffices entry point to request data and get notified about updates. Each domain should register their own repository in the Backoffice.
+
+### Register a Repository
+
+```typescript
+import { umbExtensionRegistry } from '@umbraco-cms/backoffice/extension-registry';
+import { MyRepository } from './MyRepository';
+
+const repositoryManifest = {
+ type: 'repository',
+ alias: 'My.Repository',
+ name: 'My Repository',
+ api: MyRepository,
+};
+```
+
+With a repository we can have different data sources depending on the state of the app. The data sources can come from places like a server, an offline database, a store, or a Signal-R connection. That means that the consumer will not have to be concerned how to access the data, add or remove items from a collection, etc. This means we get a loose connection between the consumer and the data-storing procedures hiding all complex implementation.
+
+### Data flow with a repository
+
+
Data flow
+
+A repository has to be instanced in the context where it is used. It should take a host element as part of the constructor. This ensures that any contexts consumed in the repository, like notifications or modals, are rendered in the correct DOM context.
+
+A repository can be called directly from an element, but will often be instantiated in a context, like the Workspace Context.
diff --git a/16/umbraco-cms/customizing/foundation/working-with-data/states.md b/16/umbraco-cms/customizing/foundation/working-with-data/states.md
new file mode 100644
index 00000000000..9e20508b951
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/working-with-data/states.md
@@ -0,0 +1,79 @@
+---
+description: Make reactivity with Umbraco States
+---
+
+# States
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Umbraco States enables you to create [Observables](states.md#observables) based on a State. The Observables can then be observed, and when a change to the State occurs, all observers of Observables will be triggered.
+
+## State types
+
+Umbraco comes with a State type for the most common types of data:
+
+* Array State
+* Boolean State
+* Class State
+* Number State
+* Object State
+* String State
+
+## Observables
+
+### Observe a state via Umbraco Element or Umbraco Controller
+
+The Umbraco Element or Controllers comes with the ability to observe an Observable.
+
+While observing all changes will result in the callback being executed.
+
+The example below creates a State and then turns the whole state into an Observable, which then can be observed.
+
+
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
+
+...
+
+this.#selectionState = UmbArrayState<string>(['item1', 'item2']);
+this.selection = this.#selectionState.asObservable();
+
+this.observe(
+ this.selection,
+ (selection) => {
+ // This call will be executed initially and on each change of the state
+ }
+);
+
+
+### Change the value of a state
+
+The value of a state can be changed via the `setValue` method. This replaces the current data with new data.
+
+The following example shows how to change the value of the state to hold `item2` and `item3`. As the example extends the example from above, it means that `item1` is no longer part of the value of this state.
+
+
+
+**Observe part of a state**
+
+With the `asObservablePart` method, you can set up an Observable that provides a transformed outcome, based on the State.
+
+```typescript
+this.selectionLength = this.#selectionState.asObservablePart(data => data.length);
+
+this.observe(
+ this.selectionLength, (length) => {
+ // This call will be executed, initially and on each change of the specific value that this observer provides.
+ // This means that this will only be executed when the length changed. Not if the value was replaced with a new value value with the exact same length.
+ console.log("Length of selection is now ", length)
+ }
+);
+```
+
+In the above example, the `asObservablePart` mapping function will be executed every time there is a change to the State. If the result of the method is different than before it will trigger an update to its observers.
diff --git a/16/umbraco-cms/customizing/foundation/working-with-data/store.md b/16/umbraco-cms/customizing/foundation/working-with-data/store.md
new file mode 100644
index 00000000000..94cf0a21246
--- /dev/null
+++ b/16/umbraco-cms/customizing/foundation/working-with-data/store.md
@@ -0,0 +1,150 @@
+---
+description: >-
+ A store holds data throughout the session. It is used to create reactivity
+ across different parts.
+---
+
+# Store
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## Store
+
+A store is the link between a Resource and a Repository. A store is mainly taken from a Context API. In other words, we have to Consume the Context (Store) to get the Store.
+
+Generally, a Store will hold one or more [State Objects](states.md), with each Subject made available for Observation via Observables.
+
+### A Basic Store
+
+```typescript
+class MyProductStore {
+ #products = new UmbArrayState(>[], (product) => product.id);
+
+ public readonly products = this.#products.asObservable();
+
+ protected host: UmbControllerHostElement;
+ constructor(host: UmbControllerHostElement) {
+ this.host = host;
+
+ // The Store provides it self as a Context-API.
+ new UmbContextProviderController(_host, 'MyStoreContextAlias', this);
+ }
+}
+```
+
+In this example, we created an ArrayState, A State which is specific to Arrays. This holds the data for one or more Observables to convey to outsiders.
+
+This example shows how to use the store:
+
+```typescript
+class MyImplementation extends UmbLitElement {
+ private _myProductStore?: MyProductStore;
+
+ constructor() {
+ super();
+
+ // Notice the consume callback is triggered initially and every time the Context is changed.
+ this.consume('MyStoreContextAlias', (context) => {
+ this._myProductStore = context;
+
+ this._observeAllProducts();
+ });
+ }
+
+ private _observeAllProducts() {
+ if (!this._myProductStore) return;
+
+ // Notice this callback will be triggered initially and each time the products change:
+ this.observe(this._myProductStore.products, (products) => {
+ console.log('The data of all products is:', products);
+ });
+ }
+}
+```
+
+#### A bit more meaningful Store
+
+Here we added a method that returns an Observable that is specific to the requested product.
+
+```typescript
+class MyProductStore {
+
+ ...
+
+ getByKey(id: string) {
+
+ // Request data via a Resource to then take part of this state when received.
+ tryExecuteAndNotify(this.host, ProductResource.getByKey({id})).then(({ data }) => {
+ if (data) {
+ this.#products.append(data.items);
+ }
+ });
+
+ // Return a Observable part, to listen for this specific product and the future changes of it.
+ return this.#data.asObservablePart((documents) =>
+ documents.find((document) => document.id === id)
+ );
+ }
+}
+```
+
+An example implementation using this method:
+
+```typescript
+class MyImplementation extends UmbLitElement {
+ private _myProductStore?: MyProductStore;
+
+ constructor() {
+ super();
+
+ // Notice the consume callback is triggered initially and every time the Context is changed.
+ this.consume('MyStoreContextAlias', (context) => {
+ this._myProductStore = context;
+
+ this._observeASpecificProduct();
+ });
+ }
+
+ private _observeASpecificProduct() {
+ if (!this._myProductStore) return;
+
+ // Notice this callback will be triggered initially and each time the specific product change:
+ this.observe(this._myProductStore.getByKey('1234'), (product) => {
+ console.log('The data of product `1234`` is:', product);
+ });
+ }
+}
+```
+
+**Create many Observables**
+
+A Store must hold different Observables, some exceptionally general and others highly specific, all in perspective of the types of observers we aim to accommodate.
+
+This example gives some inspiration to how fine-grained this can become:
+
+```typescript
+class MyProductStore {
+ #products = new UmbArrayState(>[]);
+
+ public readonly products = this.#products.asObservable();
+ public readonly amountOfProducts = this.#products.asObservablePart((products) => products.length);
+ public readonly topTenRatedProducts = this.#products.asObservablePart((products) => products.sort((a, b) => b.rating - a.rating).slice(0, 10));
+
+ ...
+}
+```
+
+An observer of an Observable will only be triggered if the specific part of that data has changed. With this we can make a high-performance application, only triggering the parts that need to update when data is changed.
+
+**Ensure unique data**
+
+For incoming data to replace existing data, we need to clarify what makes an entry of the array unique. In the examples of this guide, each product has an `id`. We have clarified this to the State by giving it the little method `(product) => product.id` as part of its creation:
+
+```typescript
+class MyProductStore {
+ #products = new UmbArrayState(>[], (product) => product.id);
+ ...
+}
+```
diff --git a/16/umbraco-cms/customizing/overview.md b/16/umbraco-cms/customizing/overview.md
new file mode 100644
index 00000000000..30d2c4c936d
--- /dev/null
+++ b/16/umbraco-cms/customizing/overview.md
@@ -0,0 +1,32 @@
+---
+description: >-
+ Get an overview of the different options for extending and customizing the
+ Umbraco CMS backoffice.
+---
+
+# Extend and customize the editing experience
+
+The backoffice is one of the main forces of Umbraco CMS. It is where you build the foundations for the website and where your content editors will work with the content.
+
+{% hint style="info" %}
+Are you looking to **extend and customize the Umbraco CMS**?
+
+Resources are available in the [Extending](../extending/build-on-umbraco-functionality.md) section for when you are looking to extend Umbraco functionality beyond the backoffice.
+{% endhint %}
+
+In this section, you will find all the resources you need to build an intuitive and fluid editor experience for your content editors.
+
+
Dashboards
The dashboard is where all the main functionality of the backoffice will be.
+
+{% content-ref url="foundation/" %}
+[foundation](foundation/)
+{% endcontent-ref %}
+
+{% content-ref url="extending-overview/extension-types/" %}
+[extension-types](extending-overview/extension-types/)
+{% endcontent-ref %}
+
+***
+
+{% include "../.gitbook/includes/umbraco-extending-the-backoffice-training-course.md" %}
+
diff --git a/16/umbraco-cms/customizing/project-bellissima.md b/16/umbraco-cms/customizing/project-bellissima.md
new file mode 100644
index 00000000000..a819247ddd2
--- /dev/null
+++ b/16/umbraco-cms/customizing/project-bellissima.md
@@ -0,0 +1,15 @@
+---
+description: >-
+ Learn more about project Bellissima that transformed the Umbraco Backoffice
+ using modern methods and technology.
+---
+
+# Project Bellissima
+
+"Bellissima", the code name for the frontend code of the backoffice, is a re-creation of the backoffice of Umbraco. While replacing the deprecated angular code with [Lit](https://lit.dev/) and [TypeScript](https://www.typescriptlang.org/), you can customize and extend everything in the backoffice.
+
+
An overview of all the customizable sections and elements in the Umbraco CMS backoffice.
+
+Each block is an extension point that can be extended, customized, replaced, or removed.
+
+You are not limited to the mentioned frameworks. You can use any other framework or library of your choice.
diff --git a/16/umbraco-cms/customizing/property-editors/README.md b/16/umbraco-cms/customizing/property-editors/README.md
new file mode 100644
index 00000000000..03463d2d372
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/README.md
@@ -0,0 +1,40 @@
+---
+description: Guide on how to work with and create Property Editors in Umbraco
+---
+
+# Property Editors
+
+{% hint style="info" %}
+[This tutorial](../../tutorials/creating-a-property-editor/) contains step-by-step instructions for building a custom Property editor.
+{% endhint %}
+
+{% hint style="warning" %}
+The Property Editor articles are a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+This section describes how to work with and create Property Editors. A property editor is the editor used to insert content into Umbraco. [See here for definition](../../fundamentals/backoffice/property-editors/)
+
+## [Property Editors Composition](composition/)
+
+A property editor is an editor used to insert content into Umbraco. A Property Editor is composed of two extensions: Property Editor Schema and Property Editor UI.
+
+## [Package Manifest](../umbraco-package.md)
+
+Reference for the package.manifest JSON file format to register one or more property editors for Umbraco.
+
+## [Property Value Converters](property-value-converters.md)
+
+Convert the stored property data value to a useful object returned by the Published Content APIs.
+
+## [Property Actions](property-actions.md)
+
+Use Property Actions to add additional functionaility to your custom property editors.
+
+## [Tracking References](tracking.md)
+
+Learn how to extend Property editors to track entity references inside the property editor.
+
+## More information
+
+* [Built in Property Editors](../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/)
+* [Creating a property editor](../../tutorials/creating-a-property-editor/)
diff --git a/16/umbraco-cms/customizing/property-editors/composition/README.md b/16/umbraco-cms/customizing/property-editors/composition/README.md
new file mode 100644
index 00000000000..f0298a26a69
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/composition/README.md
@@ -0,0 +1,24 @@
+---
+description: This section describes how to work with and create Property Editors.
+---
+
+# Property Editors Composition
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A property editor is an editor used to insert content into Umbraco. A Property Editor is composed of two extensions. To form a full Property Editor you will need a:
+
+* [Property Editor Schema](property-editor-schema.md)
+* [Property Editor UI](property-editor-ui.md)
+
+A Property Editor UI is utilizing a Property Editor Schema, and you can have multiple Property Editor UIs for one Schema. This means you can find a Schema that solves your needs. You only need to build a Property Editor UI.
+
+* Each Property Editor can have multiple Property Editor UIs.
+* Both a Property Editor Schema and Property Editor UI can define the Settings used for their configuration.
+
+### Configuration
+
+* Data Type Settings for a Property Editor or Property Editor UI is defined in the manifests.
+* They both use the same format for their settings.
diff --git a/16/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md b/16/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md
new file mode 100644
index 00000000000..2b0d2728eda
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md
@@ -0,0 +1,25 @@
+---
+description: The Server side part of a Property Editor
+---
+
+# Property Editor Schema
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Property Editor Schema is server code, written in C#. This handles the storage of a Property Editor and defines _Server Side Validation_ and _Property Value Converters_.
+
+### Property Editor Schema
+
+The Property Editor Schema settings are used for configuration that the server needs to know about.
+
+**Manifest**
+
+```json
+{
+ "type": "propertyEditorSchema",
+ "name": "Text Box",
+ "alias": "Umbraco.TextBox",
+};
+```
diff --git a/16/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md b/16/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md
new file mode 100644
index 00000000000..b0b3c5c6624
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md
@@ -0,0 +1,143 @@
+---
+description: Presenting the Editing Experience of a Property Editor
+---
+
+# Property Editor UI
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Property Editor UI is the UI that is used to edit the data in the backoffice.
+
+The Property Editor UI is a pure front-end extension. This determines how the data of a Property Editor is presented and manipulated. The Extension points to a Web Component.
+
+### Property Editor UI
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "type": "propertyEditorUi",
+ "alias": "Umb.PropertyEditorUi.TextBox",
+ "name": "Text Box Property Editor UI",
+ "element": "/App_Plugins/my-text-box/dist/my-text-box.js",
+ "elementName": "my-text-box",
+ "meta": {
+ "label": "My Text Box",
+ "propertyEditorSchemaAlias": "Umbraco.TextBox",
+ "icon": "icon-autofill",
+ "group": "common"
+ }
+}
+```
+{% endcode %}
+
+The Property Editor UI cannot be used for Content Types if no Property Editor Schema is specified in the manifest. However, it can still be utilized to manipulate JSON. A case of that could be a Settings property for another Property Editor UI or Schema.
+
+### Settings
+
+The Property Editor UI settings are used for configuration related to rendering the UI in the backoffice. This is the same for Property Editor Schemas:
+
+{% hint style="info" %}
+The Property Editor UI inherits the Settings of its Property Editor Schema.
+{% endhint %}
+
+**Manifest**
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "type": "propertyEditorUi",
+ "alias": "My.PropertyEditorUI.TextArea",
+ //... more
+ "meta": {
+ //... more
+ "settings": {
+ "properties": [
+ {
+ "alias": "rows",
+ "label": "Number of rows",
+ "description": "If empty - 10 rows would be set as the default value",
+ "propertyEditorUiAlias": "Umb.PropertyEditorUi.Integer",
+ },
+ ],
+ "defaultData": [
+ {
+ "alias": "rows",
+ "value": 10,
+ },
+ ],
+ },
+ },
+};
+```
+{% endcode %}
+
+## The Property Editor UI Element
+
+Implement the `UmbPropertyEditorUiElement` interface, to secure your Element live up to the requirements of this.
+
+```typescript
+interface UmbPropertyEditorUiElement extends HTMLElement {
+ name?: string;
+ value?: unknown;
+ config?: UmbPropertyEditorConfigCollection;
+ mandatory?: boolean;
+ mandatoryMessage?: string;
+ destroy?: () => void;
+}
+```
+
+{% hint style="info" %}
+The `UmbPropertyEditorUiElement` interface ensures that your Element has the necessary properties and methods to be used as a Property Editor UI Element.
+
+See the [UI API documentation](https://apidocs.umbraco.com/v15/ui-api/interfaces/packages_core_property-editor.UmbPropertyEditorUiElement.html) for more information.
+{% endhint %}
+
+**Example with LitElement**
+
+{% code title="my-text-box.ts" lineNumbers="true" %}
+```typescript
+import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
+import { css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import type {
+ UmbPropertyEditorConfigCollection,
+ UmbPropertyEditorUiElement,
+} from '@umbraco-cms/backoffice/property-editor';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+
+@customElement('umb-property-editor-ui-text-box')
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ @property()
+ value?: string;
+
+ @property({ attribute: false })
+ config?: UmbPropertyEditorConfigCollection;
+
+ #onInput(e: InputEvent) {
+ this.value = (e.target as HTMLInputElement).value;
+ this.dispatchEvent(new UmbChangeEvent());
+ }
+
+ override render() {
+ return html``;
+ }
+
+ static override readonly styles = [
+ UmbTextStyles,
+ css`
+ uui-input {
+ width: 100%;
+ }
+ `,
+ ];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-property-editor-ui-text-box': UmbPropertyEditorUITextBoxElement;
+ }
+}
+```
+{% endcode %}
diff --git a/16/umbraco-cms/customizing/property-editors/full-examples-value-converters.md b/16/umbraco-cms/customizing/property-editors/full-examples-value-converters.md
new file mode 100644
index 00000000000..a094928f6a1
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/full-examples-value-converters.md
@@ -0,0 +1,55 @@
+# Content Picker Value Converter Example
+
+{% include "../../.gitbook/includes/obsolete-warning-snapshot-publishedcache.md" %}
+
+{% code title="ContentPickerPropertyConverter.cs" %}
+
+```csharp
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Models.PublishedContent;
+using Umbraco.Cms.Core.PropertyEditors;
+using Umbraco.Cms.Core.PublishedCache;
+
+namespace UmbracoDocs.Samples;
+
+public class ContentPickerPropertyConverter : IPropertyValueConverter
+{
+ private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+
+ // Injecting the PublishedSnapshotAccessor for fetching content
+ public ContentPickerPropertyConverter(IPublishedSnapshotAccessor publishedSnapshotAccessor)
+ => _publishedSnapshotAccessor = publishedSnapshotAccessor;
+
+ public bool IsConverter(IPublishedPropertyType propertyType)
+ => propertyType.EditorAlias.Equals("Umbraco.ContentPicker");
+
+ public bool? IsValue(object? value, PropertyValueLevel level)
+ {
+ return level switch
+ {
+ PropertyValueLevel.Source => value is string stringValue && string.IsNullOrWhiteSpace(stringValue) is false,
+ _ => throw new NotSupportedException($"Invalid level: {level}.")
+ };
+ }
+
+ public Type GetPropertyValueType(IPublishedPropertyType propertyType)
+ => typeof(IPublishedContent);
+
+ public PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
+ => PropertyCacheLevel.Elements;
+
+ public object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview)
+ // parse the source string to a GuidUdi intermediate value
+ => source is string stringValue && UdiParser.TryParse(stringValue, out GuidUdi? guidUdi)
+ ? guidUdi
+ : null;
+
+ public object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview)
+ // inter is expected to be a GuidUdi at this point (see ConvertSourceToIntermediate)
+ => inter is GuidUdi guidUdi
+ ? _publishedSnapshotAccessor.GetRequiredPublishedSnapshot().Content?.GetById(guidUdi.Guid)
+ : null;
+}
+```
+
+{% endcode %}
diff --git a/16/umbraco-cms/customizing/property-editors/images/JSON-schema.png b/16/umbraco-cms/customizing/property-editors/images/JSON-schema.png
new file mode 100644
index 00000000000..70003504b6b
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/JSON-schema.png differ
diff --git a/16/umbraco-cms/customizing/property-editors/images/data-types-references.png b/16/umbraco-cms/customizing/property-editors/images/data-types-references.png
new file mode 100644
index 00000000000..d09a0db0f02
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/data-types-references.png differ
diff --git a/16/umbraco-cms/customizing/property-editors/images/document-references (1).png b/16/umbraco-cms/customizing/property-editors/images/document-references (1).png
new file mode 100644
index 00000000000..504116f0e2a
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/document-references (1).png differ
diff --git a/16/umbraco-cms/customizing/property-editors/images/document-references.png b/16/umbraco-cms/customizing/property-editors/images/document-references.png
new file mode 100644
index 00000000000..504116f0e2a
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/document-references.png differ
diff --git a/16/umbraco-cms/customizing/property-editors/images/example-of-property-actions (1).jpg b/16/umbraco-cms/customizing/property-editors/images/example-of-property-actions (1).jpg
new file mode 100644
index 00000000000..2e94865f559
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/example-of-property-actions (1).jpg differ
diff --git a/16/umbraco-cms/customizing/property-editors/images/example-of-property-actions.jpg b/16/umbraco-cms/customizing/property-editors/images/example-of-property-actions.jpg
new file mode 100644
index 00000000000..2e94865f559
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/example-of-property-actions.jpg differ
diff --git a/16/umbraco-cms/customizing/property-editors/images/media-references.png b/16/umbraco-cms/customizing/property-editors/images/media-references.png
new file mode 100644
index 00000000000..504116f0e2a
Binary files /dev/null and b/16/umbraco-cms/customizing/property-editors/images/media-references.png differ
diff --git a/16/umbraco-cms/customizing/property-editors/integrate-property-editors.md b/16/umbraco-cms/customizing/property-editors/integrate-property-editors.md
new file mode 100644
index 00000000000..30640fa5cda
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/integrate-property-editors.md
@@ -0,0 +1,42 @@
+# Integrate Property Editors
+
+Property Editors can be used and implemented anywhere in the Umbraco Backoffice.
+
+## Property & Property Dataset Components
+
+The simplest way to integrate one or more Property Editors is done using two Components: the Property Dataset component and a Property component.
+
+The `umb-property` component renders a property using a Property Editor UI.
+
+The `umb-property-dataset` component provides the dataset for any properties within. It holds the data even if the actual property is not rendered. This makes it possible to hide properties in tabs or other ways.
+
+In the following example a dataset is implemented with two properties:
+
+```js
+
+
+
+
+```
+
+Notice how the values of the properties are handled by the dataset, leaving you with one component to integrate.
+
+[Read more about Property Dataset here](property-dataset.md)
diff --git a/16/umbraco-cms/customizing/property-editors/integrate-validation.md b/16/umbraco-cms/customizing/property-editors/integrate-validation.md
new file mode 100644
index 00000000000..2b960b020cb
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/integrate-validation.md
@@ -0,0 +1,88 @@
+---
+description: >-
+ Learn how to bind and use the validation system when working with Form
+ Controls and Umbraco CMS backoffice.
+---
+
+# Integrate Validation
+
+The Validation System provides abilities to validate different Form Controls. Such can be native or custom, like a Property Editor.
+
+It also allows for binding server validation to the Form Controls making the validation experience as synergetic as possible.
+
+## Validation Context
+
+Validation Context, the hub of the Validation, is the core of this system. Everything that holds opinions about the Validation, is a Validator and is connected to the Validation Context.
+
+You can ask the Validation Context to validate. This will evaluate all validators, and once all validator instances have been validated successfully, the Validation Context will be valid.
+
+## Validators
+
+We provide a few built-in Validators that handle most cases.
+
+### Form Control Validator
+
+This Validator binds a Form Control Element with the Validation Context. When the Form Control becomes Invalid, its Validation Message is appended to the Validation Context.
+
+Notice this one also comes as a Lit Directive called `umbBindToValidation`. This enables you to integrate an element with one line of code within a Lit Render method. See the following example for a demonstration:
+
+```typescript
+
+#validation = new UmbValidationContext(this);
+
+#validate = () => {
+ this.#validation.validate().then(() => {
+ console.log('Valid');
+ }, () => {
+ console.log('Invalid');
+ });
+}
+
+render() {
+ return html`
+
+
+
+ Validate
+ `;
+}
+```
+
+## Integrate Umb-Property Elements
+
+The `umb-property` element automatically binds to its nearest validation context.
+
+This is demonstrated in the example below:
+
+```typescript
+
+#validation = new UmbValidationContext(this);
+
+#validate = () => {
+ this.#validation.validate().then(() => {
+ console.log('Valid');
+ }, () => {
+ console.log('Invalid');
+ });
+}
+
+render() {
+ return html`
+
+
+ Validate
+ `;
+}
+```
+
+## Server Validation and more
+
+This documentation is not available at the moment. For the moment you can find more information in the [Backoffice repository](https://github.com/umbraco/Umbraco-CMS/tree/ced3db8542d390bb12082ca63ef71b790da220c5/src/Umbraco.Web.UI.Client/src/packages/core/validation).
diff --git a/16/umbraco-cms/customizing/property-editors/property-actions.md b/16/umbraco-cms/customizing/property-editors/property-actions.md
new file mode 100644
index 00000000000..e40d6b560b6
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/property-actions.md
@@ -0,0 +1,111 @@
+---
+description: Guide on how to implement Property Actions for Property Editors in Umbraco
+---
+
+# Property Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Property Actions are a built-in feature that provide a generic place for secondary functionality for property editors.
+
+Property Actions appear as a small button next to the label of the property, which expands to show the available actions. They are defined and implemented in the Property Editor, making it open as to what a Property Action is.
+
+## Data Structure of Property Actions
+
+Property Actions are an array of objects defining each action. An action is defined by the following properties:
+
+```js
+{
+ labelKey: 'clipboard_labelForRemoveAllEntries',
+ labelTokens: [],
+ icon: 'trash',
+ method: removeAllEntries,
+ isDisabled: true
+}
+```
+
+We use `labelKey` and `labelTokens` to retrieve a localized string that is displayed as the Actions label. [See localization for more info.](../../extending/language-files/)
+
+`isDisabled` is used to disable an Action, which change the visual appearance and prevents interaction. Use this option when an action wouldn't provide any change. In the example above, the action `remove all entries` would not have any impact if there is no entries.
+
+## Implementation
+
+The implementation of Property Actions varies depending on whether your Property Editor is implemented with a Controller or as a Component.
+
+### Controller Implementation
+
+When your Property Editor is implemented with a Controller, use the following approach for the Property Action:
+
+```js
+angular.module("umbraco").controller("My.MarkdownEditorController", function ($scope) {
+
+function myActionExecutionMethod() {
+ alert('My Custom Property Action Clicked');
+ // Disable the action so it can not be re-run
+ // You may have custom logic to enable or disable the action
+ // Based on number of items selected etc...
+ myAction.isDisabled = true;
+};
+
+var myAction = {
+ labelKey: 'general_labelForMyAction',
+ labelTokens: [],
+ icon: 'action',
+ method: myActionExecutionMethod,
+ isDisabled: false
+}
+
+var propertyActions = [
+ myAction
+];
+
+this.$onInit = function () {
+ if ($scope.umbProperty) {
+ $scope.umbProperty.setPropertyActions(propertyActions);
+ }
+};
+
+
+});
+```
+
+### Component Implementation
+
+Follow this guide if your Property Editor is implemented as a Component. The Component must be configured to retrieve an optional reference to `umbProperty`. The requirement must be optional because property-editors are implemented in scenarios where it's not presented.
+
+See the following example:
+
+```js
+angular.module('umbraco').component('myPropertyEditor', {
+ controller: MyController,
+ controllerAs: 'vm',
+ require: {
+ umbProperty: '?^umbProperty'
+ }
+ …
+});
+```
+
+See the following example for implementation of Property Actions in a Component, notice the difference is that we are parsing actions to `this.umbProperty.setPropertyActions(...)`.
+
+```js
+var myAction = {
+ labelKey: 'general_labelForMyAction',
+ labelTokens: [],
+ icon: 'action',
+ method: myActionExecutionMethod,
+ isDisabled: false
+}
+
+var propertyActions = [
+ myAction
+];
+
+this.$onInit = function () {
+ if (this.umbProperty) {
+ this.umbProperty.setPropertyActions(propertyActions);
+ }
+};
+```
diff --git a/16/umbraco-cms/customizing/property-editors/property-dataset.md b/16/umbraco-cms/customizing/property-editors/property-dataset.md
new file mode 100644
index 00000000000..c28a50ded44
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/property-dataset.md
@@ -0,0 +1,52 @@
+# Property Dataset
+
+A Property Dataset is a Context API that holds the data for a set of properties.
+
+It is required for the `umb-property` element to have a Property Dataset provided. It can be provided via JavaScript code or an Element as documented below.
+
+## Property dataset component
+
+The `umb-property-dataset` component provides a Property Dataset Context for any properties within. This provides a way to implement such purely via Elements.
+
+In the following example a dataset is implemented by using the `umb-property-dataset` component together with with two `umb-property` components:
+
+```xml
+
+
+
+
+```
+
+## Consume values
+
+Since a Property Dataset is a Context any descending code can consume it and utilize the values.
+
+Such a case could be a Workspace View that wants to display the value of a specific property.
+
+The following example shows how to consume the Property Dataset and observe the value of a property with the alias of `my-property-alias`.
+
+```typescript
+this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (datasetContext) => {
+ this.observe(await datasetContext?.propertyValueByAlias('my-property-alias'), (value) => {
+ console.log('the value of `my-property-alias` is', value)
+ });
+});
+```
diff --git a/16/umbraco-cms/customizing/property-editors/property-value-converters.md b/16/umbraco-cms/customizing/property-editors/property-value-converters.md
new file mode 100644
index 00000000000..268afd7b7b0
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/property-value-converters.md
@@ -0,0 +1,206 @@
+---
+description: "A guide to creating a custom property value converter in Umbraco"
+---
+
+
+# Property Value Converters
+
+A Property Value Converter converts a property editor's database-stored value to another type. The converted value can be accessed from MVC Razor or any other Published Content API.
+
+Published property values have four "Values":
+
+- **Source** - The raw data stored in the database, this is generally a `String`
+- **Intermediate** - An object of a type that is appropriate to the property, for example a nodeId should be an `Int` or a collection of nodeIds would be an integer array, `Int[]`
+- **Object** - The object to be used when accessing the property using a Published Content API, for example UmbracoHelper's `GetPropertyValue` method
+
+## Registering PropertyValueConverters
+
+PropertyValueConverters are automatically registered when implementing the interface. Any given PropertyEditor can only utilize a single PropertyValueConverter.
+
+If you are implementing a PropertyValueConverter for a PropertyEditor that doesn't already have one, creating the PropertyValueConverter will automatically enable it. No further actions are needed.
+
+If you aim to override an existing PropertyValueConverter, possibly from Umbraco or a package, additional steps are necessary. Deregister the existing one to prevent conflicts in this scenario.
+
+```csharp
+using System.Linq;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+
+public class MyComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ //If the type is accessible (not internal) you can deregister it by the type:
+ builder.PropertyValueConverters().Remove();
+
+ //If the type is not accessible you will need to locate the instance and then remove it:
+ var contentPickerValueConverter = builder.PropertyValueConverters().GetTypes().FirstOrDefault(x => x.Name == "ContentPickerValueConverter");
+ if (contentPickerValueConverter != null)
+ {
+ builder.PropertyValueConverters().Remove(contentPickerValueConverter);
+ }
+ }
+}
+```
+
+The built-in PropertyValueConverters included with Umbraco, are currently marked as internal. This means you will not be able to remove them by type since the type isn't accessible outside of the namespace. In order to remove such PropertyValueConverters, you will need to look up the instance by name and then deregister it by the instance. This could be the case for other PropertyValueConverters included by packages as well, depending on the implementation details.
+
+## Implementing the Interface
+
+Implement `IPropertyValueConverter` from the `Umbraco.Cms.Core.PropertyEditors` namespace on your class
+
+```csharp
+public class ContentPickerValueConverter : IPropertyValueConverter
+```
+
+## Methods - Information
+
+### IsConverter(IPublishedPropertyType propertyType)
+
+This method is called for each PublishedPropertyType (Document Type Property) at application startup. By returning `True` your value converter will be registered for that property type and your conversion methods will be executed whenever that value is requested.
+
+Example: Checking if the IPublishedPropertyType EditorAlias property is equal to the alias of the core content editor.
+This check is a string comparison but we recommend creating a constant for it to avoid spelling errors:
+
+```csharp
+public bool IsConverter(IPublishedPropertyType propertyType)
+{
+ return propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.ContentPicker);
+}
+```
+
+### IsValue(object value, PropertyValueLevel level)
+
+This method is called to determine if the passed-in value is a value, and is of the level specified. There's a basic implementation of this in `PropertyValueConverterBase`.
+
+### GetPropertyValueType(IPublishedPropertyType propertyType)
+
+This is where you can specify the type returned by this Converter. This type will be used by ModelsBuilder to return data from properties using this Converter in the proper type.
+
+Example: Content Picker data is being converted to `IPublishedContent`.
+
+```csharp
+public Type GetPropertyValueType(IPublishedPropertyType propertyType)
+{
+ return typeof(IPublishedContent);
+}
+```
+
+### PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
+
+Here you specify which level the property value is cached at.
+
+A property value can be cached at the following levels:
+
+#### `PropertyCacheLevel.Unknown`
+
+Do not use this cache level unless you know exactly what you're doing. We recommend using the `PropertyCacheLevel.Element` level.
+
+#### `PropertyCacheLevel.Element`
+
+The property value will be cached until its _element_ is modified. The element is what holds (or owns) the property. For example:
+
+- For properties used at the page level, the element is the entire page.
+- For properties contained within Block List items, the element is the individual Block List item.
+
+This is the most commonly used cache level and should be your default, unless you have specific reasons to do otherwise.
+
+#### `PropertyCacheLevel.Elements`
+
+The property value will be cached until _any_ element (see above) is changed. This means that any change to any page will clear the property value cache.
+
+This is particularly useful for property values that contain references to other content or elements. For example, this cache level is utilized by the Content Picker to clear its property values from the cache upon content updates.
+
+#### `PropertyCacheLevel.Snapshot`
+
+{% hint style="warning" %}
+`PropertyCacheLevel.Snapshot` is obsolete in Umbraco 15 and will be removed in a future version.
+{% endhint %}
+
+The property value will only be cached for the duration of the current _snapshot_.
+
+A snapshot represents a point in time. For example, a snapshot is created for every content request from the frontend. When accessing a property in a snapshot using this cache level, it gets converted, cached throughout the snapshot, and later cleared.
+
+For all intents and purposes, think of this cache level as "per request". If your property value should _only_ be cached per request, this is the cache level you should use. Use it with caution, as the added property conversions incur a performance penalty.
+
+#### `PropertyCacheLevel.None`
+
+The property value will _never_ be cached. Every time a property value is accessed (even within the same snapshot) property conversion is performed explicitly.
+
+Use this cache level with extreme caution, as it incurs a massive performance penalty.
+
+```csharp
+public PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
+{
+ return PropertyCacheLevel.Elements;
+}
+```
+
+## Methods - Conversion
+
+There are a few different levels of conversion which can occur.
+
+### ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview)
+
+This method should convert the raw data value into an appropriate type. For example, a node identifier stored as a `String` should be converted to an `Int` or `Udi`.
+
+Include a `using Umbraco.Extensions;` to be able to use the `TryConvertTo` extension method.
+
+```csharp
+public object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview)
+{
+ if (source == null) return null;
+
+ var attemptConvertInt = source.TryConvertTo();
+ if (attemptConvertInt.Success)
+ return attemptConvertInt.Result;
+
+ var attemptConvertUdi = source.TryConvertTo();
+ if (attemptConvertUdi.Success)
+ return attemptConvertUdi.Result;
+
+ return null;
+}
+```
+
+### ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
+
+This method converts the Intermediate to an Object. The returned value is used by the `GetPropertyValue` method of `IPublishedContent`.
+
+{% include "../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+The below example converts the nodeId (converted to `Int` or `Udi` by _ConvertSourceToIntermediate_) into an 'IPublishedContent' object.
+
+```csharp
+public object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
+{
+ if (inter == null)
+ return null;
+
+ if ((propertyType.Alias != null && PropertiesToExclude.Contains(propertyType.Alias.ToLower(CultureInfo.InvariantCulture))) == false)
+ {
+ IPublishedContent content;
+ if (inter is int id)
+ {
+ content = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(id);
+ if (content != null)
+ return content;
+ }
+ else
+ {
+ var udi = inter as GuidUdi;
+ if (udi == null)
+ return null;
+ content = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(udi.Guid);
+ if (content != null && content.ContentType.ItemType == PublishedItemType.Content)
+ return content;
+ }
+ }
+
+ return inter;
+}
+```
+
+## Sample
+
+[Content Picker to `IPublishedContent` using `IPropertyValueConverter` interface](full-examples-value-converters.md)
diff --git a/16/umbraco-cms/customizing/property-editors/tracking.md b/16/umbraco-cms/customizing/property-editors/tracking.md
new file mode 100644
index 00000000000..a476528d812
--- /dev/null
+++ b/16/umbraco-cms/customizing/property-editors/tracking.md
@@ -0,0 +1,95 @@
+---
+description: >-
+ Guide on how to implement tracking entity references for Property Editors in
+ Umbraco
+---
+
+# Tracking References
+
+Property editors can be extended further to track entity references that may be selected or referenced inside the property editor. For example in the core of the CMS we have added this to numerous property editors.
+
+A good example of this is the Media Picker. The CMS stores a reference to the selected media item, enabling the identification of content nodes that use that particular media item. This avoids it being accidentally deleted if it is being used.
+
+When a content node is saved it will save the entity references as relations.
+
+## Viewing References
+
+### For Media Items
+
+1. Go to the **Media** section.
+2. Select a media item and click the **Info** tab.
+
+
+
+### For Content Nodes
+
+1. Go to the **Settings** section.
+2. Under the **Relations** from the **Advanced** section, select **Related Document** relations.
+
+
+
+### For Data Types
+
+1. Go to the **Settings** section.
+2. Expand the **Data Types** folder.
+3. Select the **Data Type** you wish to view the references.
+4. Navigate to the **Info** tab.
+
+
+
+## Example
+
+The following example shows how to implement tracking for the inbuilt CMS property editor **Content Picker**. It will always add a specific media reference, regardless of what value is picked in the content picker. In your own implementations, you will need to parse the value stored from the property editor you are implementing. You will also need to find any references to picked items in order to track their references.
+
+{% code title="TrackingExample.cs" %}
+```csharp
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Models.Editors;
+using Umbraco.Cms.Core.PropertyEditors;
+
+namespace UmbracoDocs.Samples;
+
+public class TrackingExample : IDataValueReferenceFactory, IDataValueReference
+{
+ public IDataValueReference GetDataValueReference() => this;
+
+ // Which Data Editor (Data Type) does this apply to - in this example it is the built in content picker of Umbraco
+ public bool IsForEditor(IDataEditor? dataEditor)
+ => dataEditor?.Alias.InvariantEquals(Constants.PropertyEditors.Aliases.ContentPicker) is true;
+
+ public IEnumerable GetReferences(object? value)
+ {
+ // Value contains the raw data that is being saved for a property editor
+ // You can then analyse this data be it a complex JSON structure or something more trivial
+ // To add the chosen entities as references (as any UDI type including custom ones)
+
+ // A very simple example
+ // This will always ADD a specific media reference to the collection list
+ // When it's a ContentPicker datatype
+ var references = new List();
+ var udiType = UmbracoObjectTypes.Media.GetUdiType();
+ var udi = Udi.Create(udiType, Guid.Parse("fbbaa38d-bd93-48b9-b1d5-724c46b6693e"));
+ var entityRef = new UmbracoEntityReference(udi);
+ references.Add(entityRef);
+ return references;
+ }
+}
+```
+{% endcode %}
+
+You'll need a Composer to enable the tracking example:
+
+{% code title="TrackingExampleComposer.cs" %}
+```csharp
+using Umbraco.Cms.Core.Composing;
+
+namespace UmbracoDocs.Samples;
+
+public class TrackingExampleComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ => builder.DataValueReferenceFactories().Append();
+}
+```
+{% endcode %}
diff --git a/16/umbraco-cms/customizing/searchable-trees.md b/16/umbraco-cms/customizing/searchable-trees.md
new file mode 100644
index 00000000000..b569a0ef57f
--- /dev/null
+++ b/16/umbraco-cms/customizing/searchable-trees.md
@@ -0,0 +1,165 @@
+# Searchable Trees (ISearchableTree)
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+When you type a search term into the Umbraco backoffice search field, you'll see search results from all the Section Trees that your user account has permission to access:
+
+.png>)
+
+The results are grouped by 'Section Tree' like Content, Media, Document Types. Each 'Tree' has its own associated search mechanism that receives the search term and looks for matches in the tree that is responsible for searching.
+
+You can create your own search mechanisms for your own custom sections or replace the default search implementation for a particular section tree.
+
+## Custom Tree Search
+
+To create a search for your own custom tree you need to create a C# class that implements the interface `Umbraco.Cms.Core.Trees.ISearchableTree`.
+
+### ISearchableTree
+
+```csharp
+using System.Collections.Generic;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.Models.ContentEditing;
+
+namespace My.Website;
+
+public interface ISearchableTree : IDiscoverable
+{
+ ///
+ /// The alias of the tree that the belongs to
+ ///
+ string TreeAlias { get; }
+
+ ///
+ /// Searches for results based on the entity type
+ ///
+ /// The search term used for finding matching results.
+ /// The number of records to return for a page of results.
+ /// The 0-based index for retrieving a page of search results.
+ /// Populated with the total number of results matching the provided search term.
+ ///
+ /// The starting point for the search, generally a node ID, but for members this is a member type alias.
+ ///
+ ///
+ Task SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null);
+}
+```
+
+Your implementation needs to return an IEnumerable of `SearchResultEntity` items:
+
+```csharp
+public class SearchResultEntity : EntityBasic
+{
+ public SearchResultEntity() {
+ ///
+ /// The score of the search result
+ ///
+ [DataMember(Name = "score")]
+ public float Score { get; set; }
+ };
+
+}
+```
+
+A `SearchResultEntity` consists of a Score (a Float value) identifying its relevance to the search term, and the set of `EntityBasic` properties that all Umbraco objects share: eg Name, Id, Udi, Icon, Trashed, Key, ParentId, Path, Alias, AdditionalData.
+
+#### Example implementation of ISearchableTree
+
+If we have a custom section Tree with the alias 'favouriteThingsAlias' (see the [custom tree example](extending-overview/extension-types/tree.md)) then we could implement searchability by creating the following C# class in our site:
+
+```csharp
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Models.ContentEditing;
+using Umbraco.Cms.Core.Trees;
+
+namespace Umbraco.Docs.Samples.Web.Trees;
+
+public class FavouriteThingsSearchableTree : ISearchableTree
+{
+ public string TreeAlias => "favouriteThingsAlias";
+
+ public async Task SearchAsync(string query, int pageSize, long pageIndex, string searchFrom = null)
+ {
+ // your custom search implementation starts here
+ Dictionary favouriteThings = new Dictionary();
+ favouriteThings.Add(1, "Raindrops on Roses");
+ favouriteThings.Add(2, "Whiskers on Kittens");
+ favouriteThings.Add(3, "Skys full of Stars");
+ favouriteThings.Add(4, "Warm Woolen Mittens");
+ favouriteThings.Add(5, "Cream coloured Unicorns");
+ favouriteThings.Add(6, "Schnitzel with Noodles");
+
+ var searchResults = new List();
+
+ var matchingItems = favouriteThings.Where(f => f.Value.StartsWith(query, true, System.Globalization.CultureInfo.CurrentCulture));
+ foreach (var matchingItem in matchingItems)
+ {
+ // Making up the Id/Udi for this example! - these would normally be different for each search result.
+ searchResults.Add(new SearchResultEntity()
+ {
+ Id = 12345,
+ Alias = "favouriteThingItem",
+ Icon = "icon-favorite",
+ Key = new Guid("325746a0-ec1e-44e8-8f7b-6e7c4aab36d1"),
+ Name = matchingItem.Value,
+ ParentId = -1,
+ Path = "-1,12345",
+ Score = 1.0F,
+ Trashed = false,
+ Udi = Udi.Create("document", new Guid("325746a0-ec1e-44e8-8f7b-6e7c4aab36d1"))
+ });
+ }
+ // Set number of search results found
+ var totalFound = matchingItems.Count();
+ // Return your results
+ return new EntitySearchResults(searchResults, totalFound);
+ }
+}
+```
+
+That's all we need, after an application pool recycle, if we now search in the backoffice we'll see matches from our custom 'Favourite Things' tree:
+
+.png>)
+
+Umbraco automatically finds any implementation of `ISearchableTree` in your site and automatically configures it to be used for the custom section mentioned in the TreeAlias property. Be careful not to accidentally have two `ISearchableTree` implementations trying to search the 'same' TreeAlias, it's _one_ `ISearchableTree` per TreeAlias.
+
+## Replacing an existing Section Tree Search
+
+Perhaps you want to change the logic for searching an existing section of the site, (why? - well you might have a 'company name' property on a MemberType in the Member section, and you want searches for that company name to filter the members who work there, the default implementation will only search on Member Name).
+
+Or perhaps you want to replace Examine search in the backoffice with an external Search Service, e.g. Azure Search. In a cloud-hosted implementation you don't need to build the Examine indexes on each new server as your cloud hosting scales out.
+
+### Example
+
+First create your replacement custom `ISearchableTree` implementation, using the same approach as above, but specifying the TreeAlias of the Tree you aim to replace, e.g. 'Member'.
+
+```csharp
+public string TreeAlias => "member";
+```
+
+To avoid your custom implementation clashing with the default `ISearchableTree` for a Tree, you need to remove its `ISearchableTree` implementation from the collection of SearchableTrees using an `IComposer` when Umbraco starts up:
+
+```csharp
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Web.BackOffice.Trees;
+
+namespace Umbraco.Docs.Samples.Web.Trees;
+
+public class RemoveCoreMemberSearchableTreeComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ // Remove core MemberTreeController
+ builder.SearchableTrees().Exclude();
+ }
+}
+```
+
+This would then allow your custom implementation of `ISearchableTree` with TreeAlias 'member' to be used when searching the Member Section Tree.
diff --git a/16/umbraco-cms/customizing/section-trees.md b/16/umbraco-cms/customizing/section-trees.md
new file mode 100644
index 00000000000..344f1035db2
--- /dev/null
+++ b/16/umbraco-cms/customizing/section-trees.md
@@ -0,0 +1,29 @@
+---
+description: An explanation on sections and trees in Umbraco
+---
+
+# Sections & Trees
+
+{% hint style="warning" %}
+The Section & Trees articles are a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Umbraco backoffice consists of sections (sometimes referred to as applications) which contain Trees.
+
+Each section is identified by its name in the top navigation ribbon of the Umbraco Backoffice.
+
+For example, when you load the backoffice, you'll see that the 'Content' section contains one tree: the content tree. Meanwhile, the 'Settings' section contains a number of trees such as Stylesheets, Document Types, Media Types, etc...
+
+You can create your own sections and trees to extend Umbraco.
+
+## [Sections](extending-overview/extension-types/sections/section.md)
+
+Describes Umbraco Sections, configuration, and APIs.
+
+## [Trees](extending-overview/extension-types/tree.md)
+
+Describes Umbraco Trees, configuration, APIs, and events.
+
+## [Searchable Trees (ISearchableTree)](searchable-trees.md)
+
+Explains how to customize the backoffice search of a Section Tree.
diff --git a/16/umbraco-cms/customizing/ui-library.md b/16/umbraco-cms/customizing/ui-library.md
new file mode 100644
index 00000000000..ad0d3f57824
--- /dev/null
+++ b/16/umbraco-cms/customizing/ui-library.md
@@ -0,0 +1,51 @@
+---
+description: Find out more about Umbraco UI Library, UI API and Storybook.
+---
+
+# UI Library
+
+## UI Library and UI API
+
+With the UI Library, you get a collection of visual building blocks that consists of pieces to build any UI in Umbraco. Each component is a building block updating its display according to the data passed to it.
+
+{% hint style="info" %}
+**Are you looking for the AngularJS documentation?**
+
+With Umbraco 14 the Umbraco backoffice has been rebuilt using Web Components and TypeScript. This means that AngularJS is no longer being used in Umbraco CMS, hence the removal of the corresponding documentation.
+{% endhint %}
+
+With the UI API, you get a set of collections related to modules export, interfaces, and hierarchy. This includes code examples and much more that you can use to extend the backoffice.
+
+
+
+## UI Library Storybook
+
+The Umbraco UI Library is a set of web components that can be used to build Umbraco User Interfaces. The UI Library separates the user interface from Umbraco’s business logic and creates a unified user experience. This is done with coherent styling and naming, across all the Umbraco platforms and projects including the ones developed by you.
+
+[Storybook](https://uui.umbraco.com/) is an application that gathers all the components together of the UI Library. It holds the documentation for the components and showcases different use case scenarios. You can explore all the components through stories reflecting their use cases.
+
+Each story has interactive controls that allow you to change the state of the component in real time. Every publicly available property is editable in Storybook, so you can test out custom configurations and use cases.
+
+You can also modify the custom properties in the stylesheet to see how the component will look. Every story has a code example that you can copy and paste into your project. This will allow you to implement the components in your own packages and extensions.
+
+### Getting Started with the UI Library
+
+The [Storybook](https://uui.umbraco.com/) is the starting point for working with the Umbraco UI Library. The Storybook contains two tabs:
+
+1. Canvas - The Canvas tab allows to use the interactive controls.
+
+
+2. Documentation - Here, you can find code examples for all the stories and use them in your markup. You can look it up by tag name or head to the project repository, where, in the packages folder, you will find all the component packages with all the necessary scripts and examples in the readme files.
+
+
+
+### Import UI Library Components
+
+You can also work with the components on a code level. If you want to do so here is how you import it:
+
+```typescript
+import { UUIButtonElement } from '@umbraco-cms/backoffice/external/uui';
+```
+
+This requires that your Package has the `@umbraco-cms/backoffice` dependency.
diff --git a/16/umbraco-cms/customizing/umbraco-package.md b/16/umbraco-cms/customizing/umbraco-package.md
new file mode 100644
index 00000000000..e48638e5615
--- /dev/null
+++ b/16/umbraco-cms/customizing/umbraco-package.md
@@ -0,0 +1,251 @@
+---
+description: An extension begins with a Umbraco Package
+---
+
+# Umbraco Package
+
+A Package is declared via an Umbraco Package JSON file. This describes the Package and declares one or more UI Extensions. The Package declaration is a JSON file that is stored in the `App_Plugins/{YourPackageName}` folder. The file is named `umbraco-package.json`.
+
+## Sample
+
+Here is a sample package. It should be stored in a folder in `App_Plugins/{YourPackageName}`, with the name `umbraco-package.json`. In this example, the package name is `SirTrevor` and is a text box property Data Type.
+
+{% hint style="info" %}
+Before Umbraco 14, a package was declared in a `package.manifest` file instead of `umbraco-package.json`. The old format is no longer supported, but you can migrate the contents to the new format.
+{% endhint %}
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "id": "My.Nuget.Package",
+ "name": "Sir Trevor",
+ "version": "1.0.0-beta",
+ "extensions": [
+ {
+ "type": "propertyEditorUi",
+ "alias": "Sir.Trevor",
+ "name": "Sir Trevor Property Editor UI",
+ "element": "/App_Plugins/SirTrevor/SirTrevor.js",
+ "meta": {
+ "label": "Sir Trevor",
+ "propertyEditorSchemaAlias": "Umbraco.TextBox",
+ "icon": "icon-code",
+ "group": "Pickers"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+## Root fields
+
+The `umbraco-package` accepts these fields:
+
+```json
+{
+ "id": "",
+ "name": "",
+ "version": "",
+ "allowTelemetry": true,
+ "allowPublicAccess": false,
+ "importmap": {
+ "imports": {
+ "": ""
+ },
+ "scopes": {
+ "": ""
+ }
+ },
+ "extensions": []
+}
+```
+
+### Id
+
+The unique identifier for your package. This is used to identify your package and should be unique to your package. If you are creating a package that is distributed via NuGet, you should use the NuGet package ID as the ID for your package.
+
+### Name
+
+Allows you to specify a friendly name for your package that will be used for telemetry. If no name is specified the name of the folder will be used instead.
+
+### Version
+
+The version of your package, if this is not specified there will be no version-specific information for your package. This is used for telemetry and to help users understand what version of your package they are using. It is also used for package migrations. The version should follow the [Semantic Versioning](https://semver.org/) format.
+
+### Allow Telemetry
+
+With this field, you can control the telemetry of this package, this will provide Umbraco with the knowledge of how many installations use this package.
+
+The default is `true`.
+
+Also known as: `allowPackageTelemetry`
+
+### Allow Public Access
+
+This field is used to allow public access to the package. If set to `true`, the package will be available for anonymous usage, for example on the login screen. If set to `false`, the package will only be available to logged-in users.
+
+The default is `false`.
+
+### Importmap
+
+The `importmap` field is an object that contains two properties: `imports` and `scopes`. This is used to define the import map for the package. The `imports` property is an object that contains the import map for the package. The `scopes` property is an object that contains the scopes for the package.
+
+**Example**
+
+This example shows how to define an import map for a module exported by a package:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "importmap": {
+ "imports": {
+ "mypackage/services": "/App_Plugins/MyPackage/services/index.js",
+ }
+ }
+}
+```
+{% endcode %}
+
+The `imports` object contains the import map for the package. The key is the specifier for the module that is being imported, and the value is the URL of the module.
+
+This allows developers to consume modules that are exported by a package without having to know the exact path to the module:
+
+{% code title="index.js" %}
+```javascript
+import { MyService } from 'mypackage/services';
+```
+{% endcode %}
+
+Umbraco supports the current specification of the property as outlined on MDN Web Documentation: [importmap](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap).
+
+### Extensions
+
+The `extensions` field is an array of Extension Manifest objects. Each object describes a single client extension.
+
+Read more about these in the [Extension Manifests article](extending-overview/extension-registry/extension-manifest.md).
+
+These are the current types of UI Extensions:
+
+| Type | Description |
+| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| authProvider | An authentication provider for [external login](../reference/security/external-login-providers.md). |
+| appEntryPoint | An app entry point is a JavaScript module that is executed when any app is loaded (Login, Installer, Upgrader, and Backoffice). It will never be destroyed. Read more about [Entry Points](extending-overview/extension-types/app-entry-point.md). |
+| backofficeEntryPoint | A backoffice entry point is a JavaScript module that is executed when the backoffice is loaded. It will be destroyed when the backoffice is closed or logged out. Read more about [Entry Points](extending-overview/extension-types/backoffice-entry-point.md). |
+| blockEditorCustomView | A custom view for a block in the block editor. |
+| bundle | A bundle is a collection of other manifests that can be loaded together. You would use this in lieu of a `backofficeEntryPoint` if all you needed was to load extensions through JavaScript. |
+| condition | A condition that can be used to control the visibility of other UI Extensions. Read more about [Conditions](extending-overview/extension-types/condition.md). |
+| currentUserAction | A current user action is a button that can be added to the current user view. |
+| dashboard | A dashboard is a view that can be added to any section. It is displayed in the dashboard view with tabs. Read more about [Dashboards](extending-overview/extension-types/dashboard.md). |
+| dashboardCollection | A dashboard collection is a view that can be added to a collection. |
+| dynamicRootOrigin | A dynamic root origin is a dynamic root origin that can be added to the Dynamic Root selector. |
+| dynamicRootQueryStep | A dynamic root query step is a query step that can be added to the Dynamic Root selector. |
+| entityAction | An entity action is a button that can be added to any entity, like a document, media, member, etc. It will be shown in the entity actions menu and in the entity actions menu. |
+| entityBulkAction | An entity bulk action is a button that can be added to the bulk actions menu, which is shown when multiple entities are selected in a collection view. |
+| entryPoint | (Deprecated) Old name for `backofficeEntryPoint`. |
+| globalContext | A global context is a context instance that is available to all components in the Backoffice. It is used to share state between components and to provide a way to communicate between components. Read more about [Global Context](extending-overview/extension-types/global-context.md). |
+| granularUserPermissions | A granular user permission is a permission that can be added to a user. It is used to control access to specific parts of the Backoffice. |
+| headerApp | A header app is a component that can be added to the header such as a button or a link. Read more about [Header Apps](extending-overview/extension-types/header-apps.md). |
+| healthCheck | A health check is a check that can be added to the health check dashboard. Read more about the backend side of [Health Checks](../reference/configuration/healthchecks.md). |
+| icons | An icon is a set of icons that can be added to the icon picker. Read more in the [Icons article](extending-overview/extension-types/icons.md). |
+| localization | A localization is a set of translations that can be added to the localization service. Read more about [Localization](foundation/localization.md) in the UI. |
+| menu | A menu is a component that can be added to the menu bar. Read more about [Menus](extending-overview/extension-types/menu.md). |
+| menuItem | A menu item is a component that can be added to a menu. |
+| mfaLoginProvider | This type of login provider is the UI component of [Two-Factor Authentication](../reference/security/two-factor-authentication.md) used to enable/disable the provider. |
+| modal | A modal dialog. Read more about [Modals](extending-overview/extension-types/modals/). |
+| monacoMarkdownEditorAction | A Monaco Markdown Editor action is a button that can be added to the toolbar of the [Markdown Property Editor](../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/markdown-editor.md). |
+| packageView | A package view is an optional view that can be shown in the "Packages" section of the Backoffice. The user can navigate to this view to see more information about the package and to manage it. |
+| previewAppProvider | A preview app provider is a provider that can be used to provide a preview app for the Save and Preview action on a document. |
+| propertyAction | A property action is a button that can be added to the property actions menu. |
+| propertyEditorSchema | A property editor schema is a model that describes a Data Editor and its properties from the backend to the UI. It is used by Property Editor UIs. Read more about [Property Editors](property-editors/). |
+| propertyEditorUi | A property editor UI is a UI component that can be added to content types. It is used to render the UI of a Data Editor. Read more about [Property Editors](property-editors/). |
+| searchProvider | A search provider is a provider that can be used to provide search results for the search bar in the Backoffice. |
+| searchResultItem | A search result item is a component that can be added to the search results. |
+| theme | A theme is a set of styles that can be added to the Backoffice. The user can select their preferred theme in the current user modal. |
+| tinyMcePlugin | A TinyMCE plugin is a plugin that can be added to the TinyMCE editor. Read more about [TinyMCE Plugins](../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/plugins.md). |
+| treeItem | A tree item that can be added to the tree. |
+| tree | A tree that can be added to a section. |
+| ufmComponent | This type of component is a formatter that can be added to the [Umbraco Flavoured Markdown](../reference/umbraco-flavored-markdown.md), which is used in property descriptions and advanced labels. |
+| userProfileApp | A user profile app is a component that can be added to the current user view. |
+
+**Collections**
+
+| Type | Description |
+| ---------------- | -------------------------------------------------------------------------- |
+| collection | A collection to show a list of entities (documents, media, members, etc.). |
+| collectionAction | A collection action is a button that can be added to a collection view. |
+| collectionView | A collection view is a view that can be added to a collection. |
+
+**Stores and repositories**
+
+| Type | Description |
+| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| repository | A repository is a class that can be used to interact with a data source. It is used either by context classes or elements directly to interact with the data source. It typically holds a `store` instance. Read more about [Repositories](foundation/working-with-data/repositories.md). |
+| store | A store is a context instance that is available to repositories. It is used by repositories to store data. Read more about [Stores](foundation/working-with-data/store.md). |
+| itemStore | An item store is a store that can be used to store items. It is used by repositories to store items. |
+| treeStore | A tree store is a store that can be used to store tree data. It is used by tree repositories to store tree data. |
+
+**Sections**
+
+| Type | Description |
+| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| section | A section is a section that can be added to the navigation bar of the Backoffice like the "Content" or "Media" sections that are built-in. Read more about [Sections](extending-overview/extension-types/sections/section.md). |
+| sectionRoute | A section route is a route that can be added to a section. It is used to define the URL of the view that is displayed in the main content area of the Backoffice. |
+| sectionSidebarApp | A section sidebar app that can be added to the section sidebar. Read more about [Section Sidebar Apps](extending-overview/extension-types/sections/section-sidebar.md). |
+| sectionView | A section view is a view that can be added to a section. It is displayed in the main content area of the Backoffice. More than one view can be added to a section, and the user can switch between them. In that case, the views are displayed as tabs. Read more about [Section Views](extending-overview/extension-types/sections/section-view.md). |
+
+**Workspaces**
+
+| Type | Description |
+| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| workspace | A workspace is a component that can be added to an entity type. This is the editor you see, when you edit an entity. Read more about [Workspaces](workspaces.md). |
+| workspaceActionMenuItem | A workspace action menu item is a button that can be added to the workspace action menu. |
+| workspaceAction | A workspace action is a button that can be added to the workspace such as the "Save" button. Read more about [Workspace Actions](extending-overview/extension-types/workspaces/workspace-editor-actions.md). |
+| workspaceContext | A workspace context is a context instance that is available to all components in the workspace. It is used to share state between components and to provide a way to communicate between components. Read more about [Workspace Context](extending-overview/extension-types/workspaces/workspace-context.md). |
+| workspaceFooterApp | A workspace footer app is a component that can be added to the workspace footer. |
+| workspaceView | A workspace view is a view that can be added to a workspace. It is displayed in the main content area of the workspace. More than one view can be added to a workspace, and the user can switch between them. In that case, the views are displayed as tabs. Read more about [Workspace Views](extending-overview/extension-types/workspaces/workspace-views.md). |
+
+Read more about [Extension Types](extending-overview/extension-types/README.md) in the Backoffice to get a better understanding of the different types of extensions.
+
+## Package Manifest IntelliSense
+
+Make your IDE be aware about the opportunities of the `umbraco-package.json` by adding a JSON schema. This gives your code editor abilities to autocomplete and knowledge about the format. This helps to avoid mistakes or errors when editing the `umbraco-package.json` file.
+
+### Adding inline schema
+
+Editors like Visual Studio can use the `$schema` notation in your file.
+
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": ""
+}
+```
+
+Hover over any of the properties to see the description of the property. You can also use the `Ctrl + Space` (Windows/Linux) or `CMD + Space` (macOS) shortcut to see the available properties.
+
+## Load Package Manifest files
+
+Umbraco scans the `App_Plugins` folder for `umbraco-package.json` files **two levels deep**. When found, the packages are loaded into the system.
+
+You may need to restart the application, if you add a new file or modify an existing manifest:
+
+If the runtime mode is `Production`, the manifests are cached for 30 days or until the application is restarted to improve performance. In other runtime modes, the cache is cleared every 10 seconds.
+
+{% hint style="info" %}
+You can implement the interface [IPackageManifestReader](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Infrastructure.Manifest.IPackageManifestReader.html) to provide your own package manifest reader. This can be useful if you want to load package manifests from a different location or source.
+{% endhint %}
+
+## Razor Class Library
+
+Umbraco also supports [Razor Class Library (RCL)](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-8.0\&tabs=visual-studio#create-an-rcl-with-static-assets) projects that contain static web assets. The `umbraco-package.json` file can be placed in the `wwwroot` folder of the RCL project. The package will be loaded when the RCL is referenced by the main project. You must map the web path to `App_Plugins` in your `.csproj` file:
+
+{% code title="MyProject.Assets.csproj" %}
+```xml
+
+ App_Plugins/{YourPackageName}
+
+```
+{% endcode %}
+
+Read more about getting set up for Backoffice development in the [Customize Backoffice](overview.md) section.
diff --git a/16/umbraco-cms/customizing/workspaces.md b/16/umbraco-cms/customizing/workspaces.md
new file mode 100644
index 00000000000..9606400ec88
--- /dev/null
+++ b/16/umbraco-cms/customizing/workspaces.md
@@ -0,0 +1,24 @@
+# Workspaces
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A Workspace is the editor for a specific entity type. It can either be a view of data or a complex editor with multiple views.
+
+* A workspace is based on an entity type (for example content, media, member, etc.) and a unique string (ex: key).
+* Most workspaces hold a draft state of an entity. It is a copy of the entity data that can be modified at runtime and sent to the server to be saved.
+* A workspace can be a single view or consist of multiple views.
+* A workspace should host a workspace context, with which anything within can communicate.
+
+
Workspace
+
+```ts
+interface UmbWorkspaceElement {}
+```
+
+## [Workspace Context](extending-overview/extension-types/workspaces/workspace-context.md)
+
+## [Workspace Views](extending-overview/extension-types/workspaces/workspace-views.md)
+
+## [Workspace Actions](extending-overview/extension-types/workspaces/workspace-editor-actions.md)
diff --git a/16/umbraco-cms/extending/backoffice-search.md b/16/umbraco-cms/extending/backoffice-search.md
new file mode 100644
index 00000000000..ff396b6f9e5
--- /dev/null
+++ b/16/umbraco-cms/extending/backoffice-search.md
@@ -0,0 +1,103 @@
+---
+description: A guide to customization of Backoffice Search
+---
+
+# Backoffice Search
+
+The search facility of the Umbraco Backoffice allows the searching 'across sections' of different types of Umbraco entities, for example Content, Media, Members. However 'by default' only a small subset of standard fields are searched:
+
+| Node Type | Propagated Fields |
+| ------------ | ---------------------- |
+| All Nodes | Id, _NodeId_ and _Key_ |
+| Media Nodes | UmbracoFileFieldName |
+| Member Nodes | email, loginName |
+
+An Umbraco implementation might have additional custom properties that it would be useful to include in a Backoffice Search. For example: an 'Organisation Name' property on a Member Type, or a 'Product Code' field for a 'Product' content item.
+
+## Adding custom properties to backoffice search
+
+To add custom properties, it is required to register a custom implementation of `IUmbracoTreeSearcherFields`. We recommend to override the existing `UmbracoTreeSearcherFields`.
+
+Your custom implementation needs to be registered in the container. For example in the `Program.cs` file or in a composer, as an alternative.
+
+```csharp
+builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .Build();
+
+builder.Services.AddUnique();
+```
+
+or
+
+```csharp
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Infrastructure.Examine;
+using Umbraco.Extensions;
+
+namespace Umbraco.Docs.Samples.Web.BackofficeSearch;
+
+public class BackofficeSearchComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.Services.AddUnique();
+ }
+}
+```
+
+{% hint style="warning" %}
+The below example is using `ILocalizationService` which is currently obselete and will be removed in v15. Use `ILanguageService` instead.
+{% endhint %}
+
+```csharp
+using System.Collections.Generic;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Infrastructure.Examine;
+using Umbraco.Cms.Infrastructure.Search;
+
+namespace Umbraco.Docs.Samples.Web.BackofficeSearch;
+
+public class CustomUmbracoTreeSearcherFields : UmbracoTreeSearcherFields, IUmbracoTreeSearcherFields
+{
+ public CustomUmbracoTreeSearcherFields(ILocalizationService localizationService) : base(localizationService)
+ {
+ }
+
+ //Adding custom field to search in all nodes
+ public new IEnumerable GetBackOfficeFields()
+ {
+ return new List(base.GetBackOfficeFields()) { "nodeType" };
+ }
+
+ //Adding custom field to search in document types
+ public new IEnumerable GetBackOfficeDocumentFields()
+ {
+ return new List(base.GetBackOfficeDocumentFields()) { "nodeType" };
+ }
+
+ //Adding custom field to search in media
+ public new IEnumerable GetBackOfficeMediaFields()
+ {
+ return new List(base.GetBackOfficeMediaFields()) { "nodeType" };
+ }
+
+ //Adding custom field to search in members
+ public new IEnumerable GetBackOfficeMembersFields()
+ {
+ return new List(base.GetBackOfficeMembersFields()) { "nodeType" };
+ }
+}
+```
+
+{% hint style="warning" %}
+You cannot use this to search on integer types in the index, as an example `parentID` does not work.
+{% endhint %}
+
+## More advanced extensions
+
+For further extensibility of the Umbraco Backoffice search implementation check [ISearchableTree](../customizing/searchable-trees.md)
diff --git a/16/umbraco-cms/extending/build-on-umbraco-functionality.md b/16/umbraco-cms/extending/build-on-umbraco-functionality.md
new file mode 100644
index 00000000000..a32a1bc6c98
--- /dev/null
+++ b/16/umbraco-cms/extending/build-on-umbraco-functionality.md
@@ -0,0 +1,38 @@
+---
+description: >-
+ Learn more about how to extend and build in the features and functionalities
+ with the Umbraco CMS.
+---
+
+# Build on Umbraco functionality
+
+One of the biggest strengths of the Umbraco CMS is its flexibility. It is possible to extend and customize all aspects of the product, tailoring it to fit perfectly to any project.
+
+{% hint style="info" %}
+Are you looking to **customize and build extensions for the Umbraco backoffice?**
+
+All articles related to customizing and extending the Umbraco backoffice have been moved to the [Customize the Backoffice](../customizing/overview.md) section.
+{% endhint %}
+
+In this section, you can find resources to build and extend Umbraco CMS functionality.
+
+
Backoffice Search
Learn how to customize the built-in search functionality in the backoffice.
+
+## Other ways to extend the Umbraco CMS backoffice
+
+* [Embedded Media Providers](embedded-media-providers.md)
+* [Language files and localization](language-files/)
+
+## Also in this section
+
+{% content-ref url="database.md" %}
+[database.md](database.md)
+{% endcontent-ref %}
+
+{% content-ref url="key-vault.md" %}
+[key-vault.md](key-vault.md)
+{% endcontent-ref %}
+
+{% content-ref url="filesystemproviders/" %}
+[filesystemproviders](filesystemproviders/)
+{% endcontent-ref %}
diff --git a/16/umbraco-cms/extending/creating-custom-seed-key-provider.md b/16/umbraco-cms/extending/creating-custom-seed-key-provider.md
new file mode 100644
index 00000000000..64fbd4ea869
--- /dev/null
+++ b/16/umbraco-cms/extending/creating-custom-seed-key-provider.md
@@ -0,0 +1,115 @@
+---
+description: A guide to creating a custom seed key provider for Umbraco
+---
+
+# Creating a Custom Seed Key Provider
+
+Umbraco uses a lazy loaded cache, which means that content is loaded into the cache on an as-needed basis. However, you may need specific content to always be in the cache. To achieve this you can implement your own custom seed key providers.
+
+There are two types of seed key providers: `IDocumentSeedKeyProvider` for documents and `IMediaSeedKeyProvider` for media. As these interfaces are identical only `IDocumentSeedKeyProvider` is demonstrated in this article.
+
+{% hint style="warning" %}
+Seed keys are cached and calculated once. Any documents created after the site has started will not be included in the seed keys until after a server restart.
+{% endhint %}
+
+## Implementation
+
+This example implements a `IDocumentSeedKeyProvider` which seeds all the children of a node, in this case blog posts.
+
+1. Create a new class called `BlogSeedKeyProvider` that implements `IDocumentSeedKeyProvider`.
+
+```csharp
+using Umbraco.Cms.Infrastructure.HybridCache;
+
+namespace MySite.SeedKeyProviders;
+
+public class BlogSeedKeyProvider : IDocumentSeedKeyProvider
+{
+ public ISet GetSeedKeys()
+ {
+ }
+}
+```
+
+Next we'll inject the `IDocumentNavigationQueryService` in order to get the children of the blog node.
+
+```csharp
+using Umbraco.Cms.Core.Services.Navigation;
+using Umbraco.Cms.Infrastructure.HybridCache;
+
+namespace MySite.SeedKeyProviders;
+
+public class BlogSeedKeyProvider : IDocumentSeedKeyProvider
+{
+ private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
+
+ public BlogSeedKeyProvider(IDocumentNavigationQueryService documentNavigationQueryService)
+ => _documentNavigationQueryService = documentNavigationQueryService;
+
+{...}
+```
+
+3. Parse a hardcoded string to a GUID.
+4. Use the `IDocumentNavigationQueryService` to get the children of the blog node.
+5. Return their keys as a `HashSet`.
+
+```csharp
+public ISet GetSeedKeys()
+{
+ var blogRoot = Guid.Parse("a5fdb22d-b7f2-4a59-8c4e-46ed86bde56c");
+
+ if (_documentNavigationQueryService.TryGetChildrenKeys(blogRoot, out IEnumerable blogPostKeys))
+ {
+ return new HashSet(blogPostKeys);
+ }
+
+ return new HashSet();
+}
+```
+Since this returns it as a set, and all the sets get unioned, we do not have to worry about duplicates.
+
+The final class looks like this:
+
+```csharp
+using Umbraco.Cms.Core.Services.Navigation;
+using Umbraco.Cms.Infrastructure.HybridCache;
+
+namespace MySite.SeedKeyProviders;
+
+public class BlogSeedKeyProvider : IDocumentSeedKeyProvider
+{
+ private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
+
+ public BlogSeedKeyProvider(IDocumentNavigationQueryService documentNavigationQueryService)
+ => _documentNavigationQueryService = documentNavigationQueryService;
+
+ public ISet GetSeedKeys()
+ {
+ var blogRoot = Guid.Parse("a5fdb22d-b7f2-4a59-8c4e-46ed86bde56c");
+
+ if (_documentNavigationQueryService.TryGetChildrenKeys(blogRoot, out IEnumerable blogPostKeys))
+ {
+ return new HashSet(blogPostKeys);
+ }
+
+ return new HashSet();
+ }
+}
+```
+
+### Registering the Seed Key Provider
+
+Now that the `BlogSeedKeyProvider` is implemented, it must be registered in the `Startup` class.
+
+```csharp
+using MySite.SeedKeyProviders;
+using Umbraco.Cms.Infrastructure.DependencyInjection;
+using Umbraco.Cms.Infrastructure.HybridCache;
+
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddSingleton();
+{...}
+```
+
+All blogpost will now be seeded into the cache on startup, and will always be present in the cache.
diff --git a/16/umbraco-cms/extending/customize-backoffice/development-flow/images/vite-project-cli.jpg b/16/umbraco-cms/extending/customize-backoffice/development-flow/images/vite-project-cli.jpg
new file mode 100644
index 00000000000..2258c172c82
Binary files /dev/null and b/16/umbraco-cms/extending/customize-backoffice/development-flow/images/vite-project-cli.jpg differ
diff --git a/16/umbraco-cms/extending/database.md b/16/umbraco-cms/extending/database.md
new file mode 100644
index 00000000000..423150c9bd5
--- /dev/null
+++ b/16/umbraco-cms/extending/database.md
@@ -0,0 +1,288 @@
+---
+description: A guide to creating a custom Database table in Umbraco
+---
+
+# Creating a Custom Database Table
+
+Umbraco ships with [NPoco](https://github.com/schotime/NPoco), which enables mapping the results of database queries to Common Language Runtime (CLR) objects. NPoco allows custom database tables to be added to your site to store additional data that should not be stored as normal content nodes.
+
+The end result looks like this:
+
+ (1) (1).png>)
+
+## Using a Composer and Component
+
+The following code sample shows how this is done using a composer and component.
+
+When migrating from version 8 there are a few changes to be aware of. The first change is that namespace updates are dependencies that need to be passed to the `Upgrader.Execute()` method. Another is a change to the access modifier of the `Migrate()` method.
+
+```csharp
+using Microsoft.Extensions.Logging;
+using NPoco;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.Migrations;
+using Umbraco.Cms.Core.Scoping;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Infrastructure.Migrations;
+using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
+using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;
+
+namespace MyNamespace;
+
+public class BlogCommentsComposer : ComponentComposer
+{
+}
+
+public class BlogCommentsComponent : IComponent
+{
+ private readonly ICoreScopeProvider _coreScopeProvider;
+ private readonly IMigrationPlanExecutor _migrationPlanExecutor;
+ private readonly IKeyValueService _keyValueService;
+ private readonly IRuntimeState _runtimeState;
+
+ public BlogCommentsComponent(
+ ICoreScopeProvider coreScopeProvider,
+ IMigrationPlanExecutor migrationPlanExecutor,
+ IKeyValueService keyValueService,
+ IRuntimeState runtimeState)
+ {
+ _coreScopeProvider = coreScopeProvider;
+ _migrationPlanExecutor = migrationPlanExecutor;
+ _keyValueService = keyValueService;
+ _runtimeState = runtimeState;
+ }
+
+ public void Initialize()
+ {
+ if (_runtimeState.Level < RuntimeLevel.Run)
+ {
+ return;
+ }
+
+ // Create a migration plan for a specific project/feature
+ // We can then track that latest migration state/step for this project/feature
+ var migrationPlan = new MigrationPlan("BlogComments");
+
+ // This is the steps we need to take
+ // Each step in the migration adds a unique value
+ migrationPlan.From(string.Empty)
+ .To("blogcomments-db");
+
+ // Go and upgrade our site (Will check if it needs to do the work or not)
+ // Based on the current/latest step
+ var upgrader = new Upgrader(migrationPlan);
+ upgrader.Execute(_migrationPlanExecutor, _coreScopeProvider, _keyValueService);
+ }
+
+ public void Terminate()
+ {
+ }
+}
+
+public class AddCommentsTable : MigrationBase
+{
+ public AddCommentsTable(IMigrationContext context) : base(context)
+ {
+ }
+ protected override void Migrate()
+ {
+ Logger.LogDebug("Running migration {MigrationStep}", "AddCommentsTable");
+
+ // Lots of methods available in the MigrationBase class - discover with this.
+ if (TableExists("BlogComments") == false)
+ {
+ Create.Table().Do();
+ }
+ else
+ {
+ Logger.LogDebug("The database table {DbTable} already exists, skipping", "BlogComments");
+ }
+ }
+
+ [TableName("BlogComments")]
+ [PrimaryKey("Id", AutoIncrement = true)]
+ [ExplicitColumns]
+ public class BlogCommentSchema
+ {
+ [PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 1)]
+ [Column("Id")]
+ public int Id { get; set; }
+
+ [Column("BlogPostUmbracoId")]
+ public int BlogPostUmbracoId { get; set; }
+
+ [Column("Name")]
+ public required string Name { get; set; }
+
+ [Column("Email")]
+ public required string Email { get; set; }
+
+ [Column("Website")]
+ public required string Website { get; set; }
+
+ [Column("Message")]
+ [SpecialDbType(SpecialDbTypes.NVARCHARMAX)]
+ public string Message { get; set; }
+ }
+}
+```
+
+## Using a Notification Handler
+
+If building a new solution, you can adopt a new pattern. With this pattern you create and run a similar migration but trigger it in response to a [notification handler](../fundamentals/code/subscribing-to-notifications.md).
+
+The code for this approach is as follows:
+
+```csharp
+using Microsoft.Extensions.Logging;
+using NPoco;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Migrations;
+using Umbraco.Cms.Core.Notifications;
+using Umbraco.Cms.Core.Scoping;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Infrastructure.Migrations;
+using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
+using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;
+
+namespace MyNamespace;
+
+public class RunBlogCommentsMigration : INotificationHandler
+{
+ private readonly IMigrationPlanExecutor _migrationPlanExecutor;
+ private readonly ICoreScopeProvider _coreScopeProvider;
+ private readonly IKeyValueService _keyValueService;
+ private readonly IRuntimeState _runtimeState;
+
+ public RunBlogCommentsMigration(
+ ICoreScopeProvider coreScopeProvider,
+ IMigrationPlanExecutor migrationPlanExecutor,
+ IKeyValueService keyValueService,
+ IRuntimeState runtimeState)
+ {
+ _migrationPlanExecutor = migrationPlanExecutor;
+ _coreScopeProvider = coreScopeProvider;
+ _keyValueService = keyValueService;
+ _runtimeState = runtimeState;
+ }
+
+ public void Handle(UmbracoApplicationStartingNotification notification)
+ {
+ if (_runtimeState.Level < RuntimeLevel.Run)
+ {
+ return;
+ }
+
+ // Create a migration plan for a specific project/feature
+ // We can then track that latest migration state/step for this project/feature
+ var migrationPlan = new MigrationPlan("BlogComments");
+
+ // This is the steps we need to take
+ // Each step in the migration adds a unique value
+ migrationPlan.From(string.Empty)
+ .To("blogcomments-db");
+
+ // Go and upgrade our site (Will check if it needs to do the work or not)
+ // Based on the current/latest step
+ var upgrader = new Upgrader(migrationPlan);
+ upgrader.Execute(
+ _migrationPlanExecutor,
+ _coreScopeProvider,
+ _keyValueService);
+ }
+}
+
+// Migration and schema defined as in the previous code sample.
+```
+
+The notification handler can be registered in a composer:
+
+```csharp
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Core.Notifications;
+
+namespace TableMigrationTest;
+
+public class BlogCommentsComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.AddNotificationHandler();
+ }
+}
+```
+
+## Which to use?
+
+In short, it's up to you. If you are migrating from version 8 and want the quickest route to getting running with the latest version, then using a component makes sense.
+
+You will be using the notification pattern elsewhere. This could be when responding to Umbraco events that run many times in the lifetime of the application, like when content is saved. And so you may also prefer to align with that pattern for start-up events.
+
+It is also worth noting that components offer both `Initialize` and `Terminate` methods. With these you will need to handle two notifications to do the same with the notification handler approach (`UmbracoApplicationStartingNotification` and `UmbracoApplicationStoppingNotification`). A single handler class can be used for both notifications though.
+
+## Schema Class and Migrations
+
+**Important!** The `BlogCommentSchema` class nested inside the migration is purely used as a database schema representation class. It should not be used as a Data Transfer Object (DTO) to access the table data. Equally, you shouldn't use your DTO classes to define the schema used by your migration. Instead, you should create a duplicate snapshot for the purpose of creating or working with your database tables in the current migration. The name of the class is not important as you will be overriding it using the TableName attribute. You should choose a name that makes it clear that this class is purely for defining the schema in this migration.
+
+Whilst this adds a level of duplication, it is important that migrations and the code/classes within a migration remain immutable. If the DTO was to be used for both, it could cause unexpected behaviour. Should you later modify your DTO used in your application but you have previous migrations expecting the DTO to be in its unmodified state.
+
+Once a snapshot has been created, and once your code has been deployed, the snapshot should never be changed directly. Instead, you should use further migrations to alter the database table into the state you require. This ensures that migrations can be run in sequence and that each migration can expect the database to be in a known state before executing.
+
+When adding further migrations and if you need to reuse the schema class, it is a good idea to duplicate this in those particular migrations. You want the migrations to be immutable. Having separate classes in separate namespaces, reduces the risk of modifying a schema class from your initial migration.
+
+## Data stored in Custom Database Tables
+
+When storing data in custom database tables, this is by default not manageable by Umbraco at all. This can be great for many purposes such as storing massive amounts of data that you do not need to edit from the backoffice. Decoupling part of your data from being managed by Umbraco as content can be a way of achieving better performance for your site. It will no longer take up space in indexes and caches, and the Umbraco database.
+
+This also means that if you do need to edit or display this data, you need to implement the underlying functionality to support this. The same if the case if you need this data to be transferred or kept synchronized between multiple sites or environments. Data stored in custom tables are not supported by default by add-ons such as Umbraco Deploy and will not be deployable by default.
+
+Figuring out how to manage data across multiple environments can be different between individual sites and there is not one solution that fits all. Some sites may have automated database synchronization set up to ensure specific tables in multiple databases are always kept in sync. Other sites may be better off with scripts moving data around manually on demand.
+
+## Working with data in Custom Database Tables
+
+To create, read, update or delete data from your custom database tables, you can use the `IScopeProvider` to get access to the database operations.
+
+The following example creates a `Controller` that uses `[Route]` annotations to create API endpoints for fetching and inserting blog comments.
+
+{% hint style="info" %}
+This example does not use the aforementioned `BlogCommentSchema` class but rather a separate (yet duplicate) class that is not part of the example. Also, be aware that things like error handling and data validation have been omitted for brevity.
+{% endhint %}
+
+```csharp
+using Microsoft.AspNetCore.Mvc;
+using System.Collections.Generic;
+using Umbraco.Cms.Infrastructure.Scoping;
+
+namespace MyNamespace;
+
+[ApiController]
+[Route("/umbraco/api/blogcomments")]
+public class BlogCommentsApiController : Controller
+{
+ private readonly IScopeProvider _scopeProvider;
+ public BlogCommentsApiController(IScopeProvider scopeProvider)
+ {
+ _scopeProvider = scopeProvider;
+ }
+
+ [HttpGet("getcomments")]
+ public IEnumerable GetComments(int umbracoNodeId)
+ {
+ using var scope = _scopeProvider.CreateScope();
+ var queryResults = scope.Database.Fetch("SELECT * FROM BlogComments WHERE BlogPostUmbracoId = @0", umbracoNodeId);
+ scope.Complete();
+ return queryResults;
+ }
+
+ [HttpPost("insertcomment")]
+ public void InsertComment(BlogComment comment)
+ {
+ using var scope = _scopeProvider.CreateScope();
+ scope.Database.Insert(comment);
+ scope.Complete();
+ }
+}
+```
diff --git a/16/umbraco-cms/extending/embedded-media-providers.md b/16/umbraco-cms/extending/embedded-media-providers.md
new file mode 100644
index 00000000000..01978f63075
--- /dev/null
+++ b/16/umbraco-cms/extending/embedded-media-providers.md
@@ -0,0 +1,187 @@
+---
+description: A guide to creating a custom embed providers in Umbraco
+---
+
+# Embedded Media Providers
+
+The Rich Text Editor in Umbraco has an 'Embed' button, that when pressed, slides open a panel. This panel enables editors to paste the URL of a third-party media resource to embed in content.
+
+
+
+For example, a YouTube Video:
+
+
+
+The task of an `EmbedProvider` is to accept the pasted URL and write out the appropriate markup for the third-party provider associated with the URL.
+
+## Embed Provider Configuration
+
+Embed Providers are registered with the `EmbedProvidersCollection` during Composition when Umbraco boots.
+
+The list of available default Embed Providers in an Umbraco install is as follows:
+
+* YouTube
+* YouTube Shorts
+* Twitter (removed with version 14.2)
+* X (available from version 14.2)
+* Vimeo
+* Dailymotion
+* Flickr
+* SlideShare
+* Kickstarter
+* Getty Images
+* Ted
+* SoundCloud
+* Issuu
+* Hulu
+* Giphy
+
+You can see the details of these, and any recent editions in the C# developer reference for [Umbraco.Core.Media.EmbedProviders](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Media.EmbedProviders.html).
+
+## Configuring a new provider
+
+Create a new provider by creating a C# class that implements the `IEmbedProvider` interface. Umbraco provides a convenient `OEmbedProviderBase` class as a starting point. You can read more about this class in the [Api documentation](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Media.EmbedProviders.OEmbedProviderBase.html?q=OEmbedProviderBase).
+
+### Adding a new OEmbed Provider Example
+
+Let's allow our editors to embed artwork from the popular DeviantArt website - the world's largest online social community for artists and art enthusiasts. We can see they have information on using OEmbed: [https://www.deviantart.com/developers/oembed](https://www.deviantart.com/developers/oembed). The format of their OEmbed implementation returns a JSON format, from a URL `https://backend.deviantart.com/oembed?url=[urltoembed]`. We'll need to use the `OEmbedProviderBase` and the `base.GetJsonResponse` method. We can see 'links' to media shared on DeviantArt are in the format: `https://fav.me/[uniquemediaidentifier]`. We'll need a regex to match any URLs pasted into the embed panel that start with _fav.me_, achieved by setting the `UrlSchemeRegex` property.
+
+The Provider would look like this:
+
+{% code title="DeviantArtEmbedProvider.cs" lineNumbers="true" %}
+```csharp
+using Umbraco.Cms.Core.Media.EmbedProviders;
+using Umbraco.Cms.Core.Serialization;
+
+namespace MyNamespace;
+
+public class DeviantArtEmbedProvider : OEmbedProviderBase
+{
+ public DeviantArtEmbedProvider(IJsonSerializer jsonSerializer)
+ : base(jsonSerializer)
+ {
+ }
+
+ public override string ApiEndpoint => "https://backend.deviantart.com/oembed?url=";
+
+ public override string[] UrlSchemeRegex => new[]
+ {
+ @"fav\.me/*",
+ @"\w+\.deviantart.com\/\w+\/art\/*",
+ @"\w+\.deviantart.com\/art\/*",
+ @"sta\.sh/*",
+ @"\w+\.deviantart.com\/\w+#\/d*"
+ };
+
+ public override Dictionary RequestParams => new();
+
+ public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
+ }
+
+ public override async Task GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ OEmbedResponseWithStringDimensions? oembed = await base.GetJsonResponseAsync(requestUrl, cancellationToken);
+
+ return oembed?.GetHtml();
+ }
+}
+```
+{% endcode %}
+
+#### Register the provider with the `EmbedProvidersCollection`
+
+Create a new C# class that implements `IComposer` and append your new provider to the `EmbedProvidersCollection`:
+
+{% code title="RegisterEmbedProvidersComposer.cs" lineNumbers="true" %}
+```csharp
+using Umbraco.Cms.Core.Composing;
+
+namespace MyNamespace;
+
+public class RegisterEmbedProvidersComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ => builder.EmbedProviders().Append();
+}
+```
+{% endcode %}
+
+The new provider should be available for editors to use:
+
+
+
+Notice there isn't any implementation written here. The regex maps the incoming URL to the provider. The base methods handle the complication of requesting from the third-party API and turning the response into HTML.
+
+## Custom Embed Providers
+
+If your third-party media provider lacks OEmbed support or requires custom HTML due to content quirks, implement `GetMarkup()` without using base helper methods.
+
+### Custom Embed Provider Example
+
+Azure Media Services [(https://azure.microsoft.com/en-gb/services/media-services/)](https://azure.microsoft.com/en-gb/services/media-services/) provides 'broadcast-quality' video streaming services. You can embed the Azure Media Player into your site to play a video using an IFrame.
+
+You can create a custom `EmbedProvider` to embed an IFrame video player in your content. This can be done by taking the Media asset URL and writing out the required markup.
+
+{% code title="AzureVideoEmbedProvider.cs" lineNumbers="true" %}
+```csharp
+using System.Net;
+using Umbraco.Cms.Core.Media.EmbedProviders;
+using Umbraco.Cms.Core.Serialization;
+
+namespace MyNamespace;
+
+public class AzureVideoEmbedProvider : OEmbedProviderBase
+{
+ public AzureVideoEmbedProvider(IJsonSerializer jsonSerializer)
+ : base(jsonSerializer)
+ {
+ }
+
+ // no ApiEndpoint!
+ public override string ApiEndpoint => string.Empty;
+
+ public override string[] UrlSchemeRegex => new[]
+ {
+ @"windows\.net/*"
+ };
+
+ public override Dictionary RequestParams => new();
+
+ public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ // format of markup
+ string videoFormat = "";
+
+ // pass in encoded Url, with and height, and turn off autoplay...
+ var videoPlayerMarkup = string.Format(videoFormat, WebUtility.UrlEncode(url) + "&autoplay=false", maxWidth, maxHeight);
+
+ return videoPlayerMarkup;
+ }
+}
+```
+{% endcode %}
+
+Here the markup to embed has been manually constructed based upon the iframe video player, no request to an Api endpoint is made...
+
+#### Register the Azure Embed Provider with the `EmbedProvidersCollection`
+
+Create a new C# class that implements `IComposer` and add append your new provider to the `EmbedProvidersCollection`:
+
+{% code title="RegisterEmbedProvidersComposer.cs" lineNumbers="true" %}
+```csharp
+using Umbraco.Cms.Core.Composing;
+
+namespace MyNamespace;
+
+public class RegisterEmbedProvidersComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ => builder.EmbedProviders().Append();
+}
+```
+{% endcode %}
+
+Now editors can embed Azure Media video Urls in the format: `//amssamples.streaming.mediaservices.windows.net/3b970ae0-39d5-44bd-b3a3-3136143d6435/AzureMediaServicesPromo.ism/manifest`.
diff --git a/16/umbraco-cms/extending/filesystemproviders/README.md b/16/umbraco-cms/extending/filesystemproviders/README.md
new file mode 100644
index 00000000000..18b491480c0
--- /dev/null
+++ b/16/umbraco-cms/extending/filesystemproviders/README.md
@@ -0,0 +1,220 @@
+---
+description: A guide to creating custom file systems in Umbraco
+---
+
+# Custom File Systems (IFileSystem)
+
+## Media Filesystem
+
+{% hint style="info" %}
+Before considering a custom media file system, be sure to first read about the configuration options for `UmbracoMediaPath` and `UmbracoMediaPhysicalRootPath` in the [configuration reference docs](../../reference/configuration/globalsettings.md). These configurations may save you from creating your own media file system entirely.
+{% endhint %}
+
+By default, Umbraco uses an instance of `PhysicalFileSystem` to handle the storage location of the media archive (wwwroot/media).
+
+This can be configured by composition:
+
+```csharp
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Core.Hosting;
+using Umbraco.Cms.Core.IO;
+using Umbraco.Cms.Infrastructure.DependencyInjection;
+
+namespace UmbracoExamples.Composition;
+
+public class SetMediaFileSystemComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.SetMediaFileSystem((factory) =>
+ {
+ IHostingEnvironment hostingEnvironment = factory.GetRequiredService();
+ var folderLocation = "~/CustomMediaFolder";
+ var rootPath = hostingEnvironment.MapPathWebRoot(folderLocation);
+ var rootUrl = hostingEnvironment.ToAbsolute(folderLocation);
+
+ return new PhysicalFileSystem(
+ factory.GetRequiredService(),
+ hostingEnvironment,
+ factory.GetRequiredService>(),
+ rootPath,
+ rootUrl);
+ });
+ }
+}
+```
+
+When creating a `PhysicalFileSystem` it takes some dependencies like `IIOHelper`, but the last two parameters are what we're interested in.
+
+The `rootPath` is where your media will be stored on the disk. Since netcore by default stores files in the `wwwroot`, we must put our desired folder somewhere within `wwwroot` to ensure that we use `hostingEnvironment.MapPathWebRoot(~/CustomMediaFolder)`. The `~` will be mapped to your `wwwroot` folder, so the final `rootPath` will be `your/project/path/wwwroot/CustomMediaFolder`. The `~` is therefore important.
+
+The `rootUrl` is the base URL that your media files will be served from. In this case, your image URL could look something like `mysite.com/CustomMediaFolder/MyAwesomePicture.png`. Again the `~` is important.
+
+In the code sample above, the `rootUrl` must map to the the same physical location as `rootPath`, which again must be placed under `wwwroot`. If you want to store the media files outside of `wwwroot` there is an extra step involved; you need to instruct netcore to include static files from a different physical location.
+
+The `rootUrl` is the base URL that your media files will be served from. In this case, your image URL could look something like `mysite.com/CustomMediaFolder/MyAwesomePicture.png`. Again the `~` is important. With the code sample above, the `rootUrl` must map to the same physical location as `rootPath`, otherwise, you will get 404's for your images.
+
+If you want to store the media files outside of `wwwroot` there is an extra step involved; you need to instruct netcore to include static files from a different physical location.
+
+In the `Program.cs` file, register a new static file location like so:
+
+```csharp
+...
+WebApplication app = builder.Build();
+
+app.UseStaticFiles(new StaticFileOptions
+ {
+ FileProvider = new PhysicalFileProvider(Path.Combine("C:", "storage", "umbracoMedia")),
+ RequestPath = "/CustomPath"
+ });
+```
+
+The PhysicalFileProvider takes a single parameter, the **`RootPath`**. This is the rooted filesystem path using directory separator chars and not ending with a directory separator, eg: `c:\storage\umbracoMedia` or `\\server\path`. The safest way to achieve this is using `Path.Combine`.
+
+You also have to specify the **`RequestPath`**. This is the relative URL where the media will be served using URL separator chars and not ending with a separator, eg: `/CustomPath` or `/Media`.
+
+Now you can use your newly registered static file location as if it was `wwwroot`. Notice how you no longer need to use `hostingEnvironment.MapPathWebRoot(folderLocation)`, since you're no longer trying to map the location to somewhere within `wwwroot`, but instead use your newly registered static file location.
+
+```csharp
+public void Compose(IUmbracoBuilder builder)
+{
+ builder.SetMediaFileSystem((factory) =>
+ {
+ IHostingEnvironment hostingEnvironment = factory.GetRequiredService();
+ var rootPath = Path.Combine("C:", "storage", "umbracoMedia");
+ var rootUrl = hostingEnvironment.ToAbsolute("/CustomPath");
+
+ return new PhysicalFileSystem(
+ factory.GetRequiredService(),
+ hostingEnvironment,
+ factory.GetRequiredService>(),
+ rootPath,
+ rootUrl);
+ });
+}
+```
+
+This is almost the same as when registering a location within the `wwwroot` folder. The only difference is that `rootPath` is now set to the path we gave the `PhysicalFileProvider` and the `rootUrl` is the same as we set as the `RequestPath` in the `StaticFileOption`.
+
+Our media is now stored in `C:\storage\umbracoMedia`, and is served from the base URL `/CustomPath`, so an image URL will look something like `mysite.com/CustomPath/MyAwesomePicture.png`.
+
+### Creating a custom file system
+
+You can replace `PhysicalFileSystem` with a custom file system implementation - eg. if you want your media files stored on Amazon S3 or elsewhere outside your site.
+
+To achieve this, you must first create your own file system by implementing the interfaces `IFileSystem` and `IFileProviderFactory` (the interfaces that are implemented by `PhysicalFileSystem`).
+
+You then replace the media filesystem by composition using `IUmbracoBuilder.SetMediaFileSystem(...)` (as is demonstrated in the paragraphs above), but instead of returning a `PhysicalFileSystem`, you return your own file system implementation.
+
+For inspiration on building a custom file system, have a look at the [Azure Blob Storage file system implementation](https://github.com/umbraco/Umbraco.StorageProviders#umbracostorageprovidersazureblob).
+
+### Accessing the media file system from code
+
+{% hint style="warning" %}
+`UmbracoAuthorizedApiController` has been removed from Umbraco 14. Use`ManagementApiControllerBase` class instead.
+
+Read the [Creating a Backoffice API article](../../tutorials/creating-a-backoffice-api/README.md) for a comprehensive guide to writing APIs for the Management API.
+{% endhint %}
+
+Since the default media file system can be swapped with custom implementations, you should never access the implementation directly. Umbraco uses a manager class called `MediaFileManager`. You can get a reference to this manager class via dependency injection in the constructor for your custom class or controller:
+
+```csharp
+public class ImagesController : UmbracoAuthorizedApiController
+{
+ private readonly MediaFileManager _mediaFileManager;
+
+ public ImagesController(MediaFileManager mediaFileManager)
+ {
+ _mediaFileManager = mediaFileManager;
+ }
+
+{...}
+```
+
+You can then access the configured file system provider through `_mediaFileManager.FileSystem`, which is the same way Umbraco will access the file system provider.
+
+## MediaPath Scheme
+
+The MediaPath Scheme defines the current set of rules that decide the format of the Media Path when it is saved into the media archive wherever it is located.
+
+By default the MediaPath scheme used by Umbraco is the `UniqueMediaPathScheme` this generates a unique 'folder' to place the uploaded image in eg.
+
+`/media/dozdrg2f/mylovelyimage.jpg`
+
+`/media` is defined by the PhysicalFileSystem and 'dozdrg2f' is generated by the `UniqueMediaPathScheme`.
+
+You can create your own logic for the path by implementing `IMediaPathScheme` and setting it during composition with:
+
+```csharp
+builder.Services.AddUnique();
+```
+
+## Other IFileSystems
+
+Umbraco also registers instances of `PhysicalFileSystem` for the following parts of Umbraco that persist to 'files':
+
+* `PartialViewsFileSystem`
+* `StylesheetsFileSystem`
+* `ScriptsFileSystem`
+* `MvcViewsFileSystem`
+
+These are accessible via dependency injection.
+
+`IFileSystem`, `MediaFileManager`, and `FileSystems` are located in the `Umbraco.Cms.Core.IO` namespace.
+
+### Stylesheet Filesystem
+
+Like with the media file system it is also possible to replace the stylesheet filesystem with your own implementation of `IFileSystem` in a composer. It's important to note here that, unlike media file system, you cannot replace the filesystem with a `PhysicalFileSystem` using a different root path or root URL, this will not work, and will cause issues since the root path is coupled to the virtual path, given by the frontend, e.g. `/css/MyBeautifulStyle.css`.
+
+When replacing the stylesheet filesystem, you don't need to register it, since it's only available through Filesystems, what you need to do instead is configure the `FileSystems` to use your implementation for the `StylesheetsFileSystem`.
+
+The IUmbracoBuilder has an extension method for configuring the `FileSystems`, you need to invoke this method with an action that accepts an `IServiceProvider` and the `FileSystems` you will configure, configuring the `FileSystems` can look like this:
+
+```csharp
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.Configuration.Models;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Core.Hosting;
+using Umbraco.Cms.Core.IO;
+using Umbraco.Cms.Infrastructure.DependencyInjection;
+
+namespace UmbracoExamples.Composition;
+
+public class FileSystemComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.ConfigureFileSystems((factory, systems) =>
+ {
+ IIOHelper ioHelper = factory.GetRequiredService();
+ IHostingEnvironment hostingEnvironment = factory.GetRequiredService();
+ ILogger logger = factory.GetRequiredService>();
+ GlobalSettings settings = factory.GetRequiredService>().Value;
+
+ var path = settings.UmbracoCssPath;
+ var rootPath = hostingEnvironment.MapPathWebRoot(path);
+ var rootUrl = hostingEnvironment.ToAbsolute(path);
+ var fileSystem = new YourFileSystemImplementaion(ioHelper, hostingEnvironment, logger, rootPath, rootUrl);
+
+ systems.SetStylesheetFilesystem(fileSystem);
+ });
+ }
+}
+
+```
+
+Where `YourFileSystemImplementation` is a class that implements `IFileSystem`. This should always be done in a composer, since we do not recommend trying to change filesystems on the fly.
+
+After the `SetStylesheetFileSystem` method has run, `FileSystems.StylesheetsFileSystem` will return the instance that was created in the `ConfigureFileSystems` extension method.
+
+## Custom providers
+
+There is an Azure Blob Storage provider:
+
+* [Azure Blob Storage](azure-blob-storage.md)
diff --git a/16/umbraco-cms/extending/filesystemproviders/azure-blob-storage.md b/16/umbraco-cms/extending/filesystemproviders/azure-blob-storage.md
new file mode 100644
index 00000000000..b73e5367f11
--- /dev/null
+++ b/16/umbraco-cms/extending/filesystemproviders/azure-blob-storage.md
@@ -0,0 +1,98 @@
+---
+description: Setup your site to use Azure Blob storage for media and ImageSharp cache
+---
+
+# Using Azure Blob Storage for Media and ImageSharp Cache
+
+There are some scenarios where you may want or need to consider leveraging Azure Blob Storage. An example would be for media in Umbraco sites with substantial media libraries.
+
+Having your site's media in Azure Blob Storage can help your deployments complete more quickly. This has the potential to positively affect site performance, as the ImageSharp cache is moved to Azure Blob Storage.
+
+The setup consists of adding a package to your site, setting the correct configuration, and adding the services and middleware. Before you begin you’ll need to create an Azure Storage Account and a container for your media and ImageSharp cache. In this example, we assume your container name is "mysitestorage" and has already been created.
+
+See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-portal) for a quickstart guide on how to create a blob storage container.
+
+## Installing the package
+
+Before you begin, you need to install the `Umbraco.StorageProviders.AzureBlob` and the `Umbraco.StorageProviders.AzureBlob.ImageSharp` NuGet packages. There are two approaches to installing the packages:
+
+1. Use your favorite Integrated Development Environment (IDE) and open up the NuGet Package Manager to search and install the packages
+2. Use the command line to install the packages
+
+### Installing through command line
+
+Navigate to your project folder, which is the folder that contains your `.csproj` file. Now use the following `dotnet add package` commands to install the packages:
+
+```cmd
+dotnet add package Umbraco.StorageProviders.AzureBlob
+dotnet add package Umbraco.StorageProviders.AzureBlob.ImageSharp
+```
+
+The correct packages will have been installed in your project.
+
+## Configuring Blob storage
+
+The next step is to configure your blob storage. There are multiple approaches for this, but in this document, we're going to do it through `appsettings.json`. For more configuration options, see the [readme](https://github.com/umbraco/Umbraco.StorageProviders#umbracostorageproviders) on the GitHub repository.
+
+Open up your `appsettings.json` file and add the connection string and container name under `Umbraco:Storage:AzureBlob:Media`. Your Umbraco section of appsettings will look something like this:
+
+```json
+ "Umbraco": {
+ "Storage": {
+ "AzureBlob": {
+ "Media": {
+ "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=;AccountKey=;EndpointSuffix=core.windows.net",
+ "ContainerName": "mysitestorage"
+ }
+ }
+ },
+ "CMS": {
+ "Hosting": {
+ "Debug": false
+ },
+ {...}
+ }
+ }
+```
+
+In this example, the container name is `mysitestorage`.
+
+{% hint style="info" %}
+You can get your connection string from your Azure Portal under "Access Keys".
+{% endhint %}
+
+## Setting the services and middleware
+
+You are almost there. The last step is to set up the required services and middleware. This can be done using extension methods.
+
+Invoke the `.AddAzureBlobMediaFileSystem()` and the `.AddAzureBlobImageSharpCache()` extension methods using the `CreateUmbracoBuilder()` builder chain in the `Program.cs` file like shown below.
+
+```csharp
+builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .AddAzureBlobMediaFileSystem() // This configures the required services for Media
+ .AddAzureBlobImageSharpCache() // This configures the required services for the Image Sharp cache
+ .Build();
+```
+
+Learn more about invoking and registering extension methods in the [Dependency Injection](../../reference/using-ioc.md) article.
+
+{% hint style="info" %}
+**Upgrading from Umbraco 9/10**:
+
+As of [version 11.0.0](https://github.com/umbraco/Umbraco.StorageProviders/releases/tag/release-11.0.0) of `Umbraco.StorageProviders`, the ImageSharp dependency has been separated into its own package.
+
+Therefore, if you're planning on upgrading your site from Umbraco 9/10 to 11+, don't forget to install and setup the new `Umbraco.StorageProviders.AzureBlob.ImageSharp` package. This will ensure that your ImageSharp cache continues to be stored in your blob storage container.
+
+{% endhint %}
+
+Now when you launch your site again, the blob storage will be used to store media items as well as the ImageSharp cache. Do note though that the `/media` and `/cache` folders do not get created until a piece of media is uploaded.
+
+## Existing Media files
+
+Any media files you already have on your site will not automatically be added to the blob storage container. You will need to copy the contents on the `/wwwroot/media` folder and upload them to a new folder called `/media` in your blob storage container. Once you've done that, you can safely delete the `wwwroot/media` folder locally, as it is no longer needed.
+
+Any new media files you upload to the site will automatically be added to the Blob Storage.
diff --git a/16/umbraco-cms/extending/filesystemproviders/images/config-from-backoffice.png b/16/umbraco-cms/extending/filesystemproviders/images/config-from-backoffice.png
new file mode 100644
index 00000000000..a28c4f9bb7e
Binary files /dev/null and b/16/umbraco-cms/extending/filesystemproviders/images/config-from-backoffice.png differ
diff --git a/16/umbraco-cms/extending/health-check/README.md b/16/umbraco-cms/extending/health-check/README.md
new file mode 100644
index 00000000000..366d89f3f90
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/README.md
@@ -0,0 +1,314 @@
+---
+description: "Health Checks are used to determine the state of your Umbraco project. Learn more about each of them in this section."
+---
+
+# Health Check
+
+The Settings section of the Umbraco backoffice holds a dashboard named "Health Check". It is a handy list of checks to see if your Umbraco installation is configured according to best practices. It's possible to add your custom-built health checks.
+
+For inspiration when building your checks you can look at the checks we've [built into Umbraco](https://github.com/umbraco/Umbraco-CMS/tree/v10/dev/src/Umbraco.Core/HealthChecks/Checks), as well as our [guides](guides/). Some examples will follow in this document.
+
+## Built-in checks
+
+Umbraco comes with the following checks by default:
+
+* Category **Configuration**
+ * **Notification Email Settings (id: `3E2F7B14-4B41-452B-9A30-E67FBC8E1206`)** - checks that the "from" email address used for email notifications has been changed from its default value
+* Category **Data Integrity**
+ * **Database data integrity check (id: `73DD0C1C-E0CA-4C31-9564-1DCA509788AF`)** - checks for various data integrity issues in the Umbraco database
+* Category **Live Environment**
+ * **Debug Compilation Mode (id: `61214FF3-FC57-4B31-B5CF-1D095C977D6D`)** - should be set to `debug="false"` on your live site
+ * **Runtime Mode (id: `8E31E5C9-7A1D-4ACB-A3A8-6495F3EDB932`)** - should be set to `Production` on your live site
+* Category **Permissions**
+ * **Folder & File Permissions (id: `53DBA282-4A79-4B67-B958-B29EC40FCC23`)** - checks that the folders and files set with write permissions that are either required or recommended can be accessed
+* Category **Security**
+ * **Application URL Configuration (id: `6708CA45-E96E-40B8-A40A-0607C1CA7F28`)** - checks if the Umbraco application URL is configured for your site.
+ * **Click-Jacking Protection (id: `ED0D7E40-971E-4BE8-AB6D-8CC5D0A6A5B0`)** - checks to see if a header or meta-tag is in place to indicate whether the site can be hosted in an IFRAME. Normally this is best set to deny permission for this to be done, to prevent what is known as [click-jacking](https://www.owasp.org/index.php/Clickjacking) attacks
+ * **Content/MIME Sniffing Protection (id: `1CF27DB3-EFC0-41D7-A1BB-EA912064E071`)** - checks that your site contains a header used to protect against Multipurpose Internet Mail Extensions (MIME) sniffing vulnerabilities
+ * **Cookie hijacking and protocol downgrade attacks Protection (HSTS) (id: `E2048C48-21C5-4BE1-A80B-8062162DF124`)** - checks if your HTTPS site contains the Strict-Transport-Security Header (HSTS). If not - adds with a default of 18 weeks
+ * **Cross-site scripting Protection (id: `F4D2B02E-28C5-4999-8463-05759FA15C3A`)** - checks for the presence of the X-XSS-Protection-header
+ * **Excessive Headers (id: `92ABBAA2-0586-4089-8AE2-9A843439D577`)** - checks to ensure that various headers that can provide details about the technology used to build and host the website have been removed
+ * **HTTPS Configuration (id: `EB66BB3B-1BCD-4314-9531-9DA2C1D6D9A7`)** - to determine if the current site is running on a secure connection
+ * **UseHttps check** - when the site is running on HTTPS, `Umbraco.Cms.Core.Configuration.Models.GlobalSettings.UseHttps` needs to be enabled to secure the backoffice. The setting can be found under `Umbraco:CMS:Global` in the `appsettings.json` file
+* Category **Services**
+ * **SMTP Settings (id: `1B5D221B-CE99-4193-97CB-5F3261EC73DF`)** - checks that an Simple Mail Tranfer Protocol (SMTP) server is configured and is accepting requests for sending emails
+
+Each check returns a message indicating whether or not the issue in question has been found on the website installation. This could be an error that should be fixed, or a warning you should be aware of.
+
+Some of them can also be rectified via the dashboard, by clicking the **Fix** button and in some cases providing some required information. These changes usually involve writing to configuration files that will often trigger a restart of the website.
+
+## Configuring and scheduling checks
+
+As well as viewing the results of health checks via the Settings section dashboard, you can set up the checks to be run on a schedule and be notified of the results by email. It's also possible to disable certain checks if they aren't applicable in your environment.
+
+For more information, see the [Reference > Configuration > Health checks](../../reference/configuration/healthchecks.md) article.
+
+## Custom checks
+
+You can build your own health checks. There are two types of health checks you can build: **configuration checks** and **general checks**.
+
+Each health check is a class that needs to have a `HealthCheck` attribute. This attribute has a few things you need to fill in:
+
+* GUID - a unique ID that you've generated for this specific check
+* Name - give it a short name so people know what the check is for
+* Description - describes what the check does in detail
+* Group - this is the category for the check if you use an existing group name (like "Configuration") the check will be added in that category, otherwise a new category will appear in the dashboard
+
+### Configuration checks
+
+These are small checks that take an [IConfiguration](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.iconfiguration?view=dotnet-plat-ext-6.0) key and confirm that the value that's expected is there. If the value is not correct, there will be a link to a guide on how to set this value correct.
+
+* A configuration check needs to inherit from `Umbraco.Cms.Core.HealthChecks.Checks.AbstractSettingsCheck`
+* A configuration check needs the `HealthCheck` attribute as noted at the start of this document
+* `ReadMoreLink` is a link to an external guide that will help you to troubleshoot any problems
+* `ValueComparisonType` can either be `ValueComparisonType.ShouldEqual` or `ValueComparisonType.ShouldNotEqual`
+* `ItemPath` is the IConfiguration key path leading to the configuration value that you want to verify
+* `Values` is a list of values that are available for this configuration item - in this example it can be `RemoteOnly` or `On`, they're both acceptable for a live site.
+ * For checks using the `ShouldEqual` comparison method, make sure to set one of these values to `IsRecommended = true`.
+ * Where `ShouldNotEqual` is used the fix will require the user to provide the correct setting
+* `CurrentValue` is the current value from the configuration setting
+* `CheckSuccessMessage` and `CheckErrorMessage` are the messages returned to the user
+ * It is highly recommended to use the `LocalizedTextService` so these can be localized. You can add the text in `~/Config/Lang/en-US.user.xml` (or whatever language you like)
+
+### General checks
+
+This can be anything you can think of, the results and the rectify action are completely under your control.
+
+* A general check needs to inherit from `Umbraco.Cms.Core.HealthChecks.HealthCheck`
+* A general check needs the `HealthCheck` attribute as noted at the start of this document
+* All checks run when the dashboard is loaded, this means that the `GetStatus()` method gets executed
+ * You can return multiple status checks from `GetStatus()`
+* A status check returns a `HealthCheckStatus`
+ * If a `HealthCheckStatus` has a `HealthCheckAction` defined then the "Fix" button will perform that action once clicked
+ * Sometimes, the button to fix something should not be called "Fix", change the `Name` property of a `HealthCheckAction` to provide a better name
+ * `HealthCheckAction` has a `Description` property so that you can provide information on what clicking the "Rectify" button will do (or provide links to documentation, for example)
+ * `HealthCheckStatus` has a few result levels:
+ * `StatusResultType.Success`
+ * `StatusResultType.Error`
+ * `StatusResultType.Warning`
+ * `StatusResultType.Info`
+ * A `HealthCheckAction` needs to provide an alias for an action that can be picked up in the `ExecuteAction` method
+* It is highly recommended to use the `LocalizedTextService` so text can be localized. You can add the text in `~/Config/Lang/en-US.user.xml` (or whatever language you like)
+
+An example check:
+
+```csharp
+using Umbraco.Cms.Core.Extensions;
+using Umbraco.Cms.Core.HealthChecks;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Web.HealthCheck.Checks.SEO;
+
+[HealthCheck("3A482719-3D90-4BC1-B9F8-910CD9CF5B32", "Robots.txt",
+ Description = "Create a robots.txt file to block access to system folders.",
+ Group = "SEO")]
+public class HealthCheckNotifier : Cms.Core.HealthChecks.HealthCheck
+{
+ private readonly IHostEnvironment _hostEnvironment;
+ private readonly ILogger _logger;
+ private readonly ILocalizedTextService _textService;
+
+ public HealthCheckNotifier(ILocalizedTextService textService, IHostEnvironment hostEnvironment,
+ ILogger logger)
+ {
+ _textService = textService;
+ _hostEnvironment = hostEnvironment;
+ _logger = logger;
+ }
+
+ public override Task> GetStatus() =>
+ Task.FromResult((IEnumerable)new[] { CheckForRobotsTxtFile() });
+
+ public override HealthCheckStatus ExecuteAction(HealthCheckAction action)
+ {
+ switch (action.Alias)
+ {
+ case "addDefaultRobotsTxtFile":
+ return AddDefaultRobotsTxtFile();
+ default:
+ throw new InvalidOperationException("Action not supported");
+ }
+ }
+
+ private HealthCheckStatus CheckForRobotsTxtFile()
+ {
+ var success = File.Exists(_hostEnvironment.MapPathContentRoot("~/robots.txt"));
+ var message = success
+ ? _textService.Localize("healthcheck", "seoRobotsCheckSuccess")
+ : _textService.Localize("healthcheck", "seoRobotsCheckFailed");
+
+ var actions = new List();
+
+ if (success == false)
+ {
+ actions.Add(new HealthCheckAction("addDefaultRobotsTxtFile", Id)
+ // Override the "Rectify" button name and describe what this action will do
+ {
+ Name = _textService.Localize("healthcheck", "seoRobotsRectifyButtonName"),
+ Description = _textService.Localize("healthcheck", "seoRobotsRectifyDescription")
+ });
+ }
+
+ return
+ new HealthCheckStatus(message)
+ {
+ ResultType = success ? StatusResultType.Success : StatusResultType.Error,
+ Actions = actions
+ };
+ }
+
+ private HealthCheckStatus AddDefaultRobotsTxtFile()
+ {
+ var success = false;
+ var message = string.Empty;
+ const string content = @"# robots.txt for Umbraco
+User-agent: *
+Disallow: /umbraco/";
+
+ try
+ {
+ File.WriteAllText(_hostEnvironment.MapPathContentRoot("~/robots.txt"), content);
+ success = true;
+ }
+ catch (Exception exception)
+ {
+ _logger.LogError(exception, "Could not write robots.txt to the root of the site");
+ }
+
+ return
+ new HealthCheckStatus(message)
+ {
+ ResultType = success ? StatusResultType.Success : StatusResultType.Error,
+ Actions = new List()
+ };
+ }
+}
+```
+
+## Custom health check notifications
+
+Health check notifications can be scheduled to run periodically and notify you of the results. Included with Umbraco is a notification method to deliver the results via email. In a similar manner to how it's possible to create your health checks, you can also create custom notification methods to send the message summarising the status of the health checks via other means. Again, for further details on implementing this please refer to the [existing notification methods within the core code base](https://github.com/umbraco/Umbraco-CMS/tree/v10/dev/src/Umbraco.Core/HealthChecks/NotificationMethods).
+
+Each notification method needs to implement the core interface `IHealthCheckNotificationMethod` and, for ease of creation, can inherit from the base class `NotificationMethodBase`, which itself implements the `IHealthCheckNotificationMethod` interface. The class must also be decorated with an instance of the `HealthCheckNotificationMethod` attribute. There's one method to implement - `SendAsync(HealthCheckResults results)` - which is responsible for taking the results of the health checks and sending them via the mechanism of your choice.
+
+The following example shows how the core method for sending notification via email is implemented:
+
+```csharp
+using Microsoft.Extensions.Options;
+using Umbraco.Cms.Core.Configuration.Models;
+using Umbraco.Cms.Core.Mail;
+using Umbraco.Cms.Core.Models.Email;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Core.HealthChecks.NotificationMethods;
+
+[HealthCheckNotificationMethod("email")]
+public class EmailNotificationMethod : NotificationMethodBase
+{
+ private readonly ILocalizedTextService? _textService;
+ private readonly IHostEnvironment? _hostEnvironment;
+ private readonly IEmailSender? _emailSender;
+ private readonly IMarkdownToHtmlConverter? _markdownToHtmlConverter;
+ private ContentSettings? _contentSettings;
+
+ public EmailNotificationMethod(
+ ILocalizedTextService textService,
+ IHostEnvironment hostEnvironment,
+ IEmailSender emailSender,
+ IOptionsMonitor healthChecksSettings,
+ IOptionsMonitor contentSettings,
+ IMarkdownToHtmlConverter markdownToHtmlConverter)
+ : base(healthChecksSettings)
+ {
+ var recipientEmail = Settings?["RecipientEmail"];
+ if (string.IsNullOrWhiteSpace(recipientEmail))
+ {
+ Enabled = false;
+ return;
+ }
+
+ RecipientEmail = recipientEmail;
+
+ _textService = textService ?? throw new ArgumentNullException(nameof(textService));
+ _hostEnvironment = hostEnvironment;
+ _emailSender = emailSender;
+ _markdownToHtmlConverter = markdownToHtmlConverter;
+ _contentSettings = contentSettings.CurrentValue ?? throw new ArgumentNullException(nameof(contentSettings));
+
+ contentSettings.OnChange(x => _contentSettings = x);
+ }
+
+ public string? RecipientEmail { get; }
+
+ public override async Task SendAsync(HealthCheckResults results)
+ {
+ if (ShouldSend(results) == false)
+ {
+ return;
+ }
+
+ if (string.IsNullOrEmpty(RecipientEmail))
+ {
+ return;
+ }
+
+ var message = _textService?.Localize("healthcheck", "scheduledHealthCheckEmailBody", new[]
+ {
+ DateTime.Now.ToShortDateString(),
+ DateTime.Now.ToShortTimeString(),
+ _markdownToHtmlConverter?.ToHtml(results, Verbosity)
+ });
+
+ // Include the Umbraco Application URL host in the message subject so that
+ // you can identify the site that these results are for.
+ var host = _hostEnvironment?.ContentRootPath?.ToString();
+
+ var subject = _textService?.Localize("healthcheck", "scheduledHealthCheckEmailSubject", new[] { host });
+
+
+ var mailMessage = CreateMailMessage(subject, message);
+ Task? task = _emailSender?.SendAsync(mailMessage, Constants.Web.EmailTypes.HealthCheck);
+ if (task is not null)
+ {
+ await task;
+ }
+ }
+
+ private EmailMessage CreateMailMessage(string? subject, string? message)
+ {
+ var to = _contentSettings?.Notifications.Email;
+
+ if (string.IsNullOrWhiteSpace(subject))
+ subject = "Umbraco Health Check Status";
+
+ var isBodyHtml = message.IsNullOrWhiteSpace() == false && message!.Contains("<") && message.Contains("");
+ return new EmailMessage(to, RecipientEmail, subject, message, isBodyHtml);
+ }
+}
+```
+
+If a custom configuration is required for a custom notification method, the following extract can be merged in the `appsettings.json` file, which will enable the email notification method to be configured:
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "HealthChecks": {
+ "Notification": {
+ "Enabled": true,
+ "NotificationMethods": {
+ "email": {
+ "Enabled": true,
+ "Settings": {
+ "RecipientEmail" : "alerts@mywebsite.tld"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+If you want to get the notifications by email, Simple Mail Tranfer Protocol (SMTP) settings should also be configured in the same JSON file.
diff --git a/16/umbraco-cms/extending/health-check/guides/README.md b/16/umbraco-cms/extending/health-check/guides/README.md
new file mode 100644
index 00000000000..7576b9ec411
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/README.md
@@ -0,0 +1,2 @@
+# Health Check Guides
+
diff --git a/16/umbraco-cms/extending/health-check/guides/clickjackingprotection.md b/16/umbraco-cms/extending/health-check/guides/clickjackingprotection.md
new file mode 100644
index 00000000000..6b45d358638
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/clickjackingprotection.md
@@ -0,0 +1,35 @@
+---
+description: Learn how to protect your Umbraco site from clickjacking attacks using X-Frame-Options and security headers.
+---
+
+# Health check: Click-Jacking Protection
+
+_Checks if your site is allowed to be IFRAMEd by another site and thus would be susceptible to click-jacking._
+
+## How to fix this health check
+
+This health check can be fixed by adding a header before the response is started.
+
+Preferable you use a security library like [NWebSec](https://docs.nwebsec.com/).
+
+### Adding Click-Jacking Protection using NWebSec
+
+If you take a NuGet dependency on [NWebsec.AspNetCore.Middleware/](https://www.nuget.org/packages/NWebsec.AspNetCore.Middleware/), you can use third extension methods on `IApplicationBuilder`.
+
+```csharp
+...
+WebApplication app = builder.Build();
+app.UseXfo(options => options.SameOrigin());
+```
+
+### Adding Click-Jacking Protection using manual middleware
+
+Avoid third-party library dependency by using custom middleware added to the request pipeline.
+
+```csharp
+app.Use(async (context, next) =>
+{
+ context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
+ await next();
+});
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/contentsecuritypolicy.md b/16/umbraco-cms/extending/health-check/guides/contentsecuritypolicy.md
new file mode 100644
index 00000000000..055d41d1292
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/contentsecuritypolicy.md
@@ -0,0 +1,54 @@
+---
+description: Implement a Content Security Policy (CSP) to protect your Umbraco site from XSS and data injection.
+---
+
+# Content Security Policy (CSP)
+
+_This check verifies if your site has a Content Security Policy (CSP) header to defend against Cross-Site Scripting (XSS) and data injection attacks._
+
+## How to fix this health check
+This health check can be fixed by adding a header before the response is started.
+
+Preferable you use a security library like [NWebSec](https://docs.nwebsec.com/).
+
+### Adding a Content Security Policy (CSP) using NWebSec
+
+If you take a NuGet dependency on [NWebsec.AspNetCore.Middleware/](https://www.nuget.org/packages/NWebsec.AspNetCore.Middleware/), you can use third extension methods on `IApplicationBuilder`.
+
+```csharp
+...
+WebApplication app = builder.Build();
+app.UseCsp(options => options
+ .ImageSources(s => s
+ .Self()
+ .CustomSources(
+ "our.umbraco.com data:",
+ "dashboard.umbraco.com"))
+ .DefaultSources(s => s
+ .Self()
+ .CustomSources(
+ "our.umbraco.com",
+ "marketplace.umbraco.com"))
+ .ScriptSources(s => s
+ .Self())
+ .StyleSources(s => s
+ .Self())
+ .FontSources(s => s
+ .Self())
+ .ConnectSources(s => s
+ .Self())
+ .FrameSources(s => s
+ .Self()));
+```
+
+### Adding a Content Security Policy (CSP) using manual middleware
+
+Avoid third-party library dependencies by using custom middleware added to the request pipeline as shown below.
+
+```csharp
+app.Use(async (context, next) =>
+{
+ context.Response.Headers.Append("Content-Security-Policy", "img-src 'self' our.umbraco.com data: dashboard.umbraco.com; default-src 'self' our.umbraco.com marketplace.umbraco.com; script-src 'self'; style-src 'unsafe-inline' 'self'; font-src 'self'; connect-src 'self'; frame-src 'self'; ");
+ await next();
+});
+```
\ No newline at end of file
diff --git a/16/umbraco-cms/extending/health-check/guides/contentsniffingprotection.md b/16/umbraco-cms/extending/health-check/guides/contentsniffingprotection.md
new file mode 100644
index 00000000000..ae71f98a164
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/contentsniffingprotection.md
@@ -0,0 +1,68 @@
+---
+description: Protect your Umbraco site from MIME sniffing vulnerabilities using security headers like X-Content-Type-Options.
+---
+
+# Health check: Content/MIME Sniffing Protection
+
+_Checks that your site contains a header used to protect against Multipurpose Internet Mail Extensions (MIME) sniffing vulnerabilities._
+
+## How to fix this health check
+
+This health check can be fixed by adding a header before the response is started.
+
+Preferable you use a security library like [NWebSec](https://docs.nwebsec.com/).
+
+### Adding Content/MIME Sniffing Protection using NWebSec
+
+If you take a NuGet dependency on [NWebsec.AspNetCore.Middleware/](https://www.nuget.org/packages/NWebsec.AspNetCore.Middleware/), you can use third extension methods on `WebApplication`.
+
+```csharp
+...
+WebApplication app = builder.Build();
+
+app.UseXContentTypeOptions();
+...
+```
+
+### Adding Content/MIME Sniffing Protection using manual middleware
+
+If you do not like to have a dependency on third party libraries, you can add the following custom middleware to the request pipeline.
+
+First create the middleware class:
+
+```csharp
+namespace MySite.Middleware;
+
+public class NoSniffMiddleware : IMiddleware
+{
+ public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ {
+ context.Response.Headers.Append("X-Content-Type-Options", "nosniff");
+ await next(context);
+ }
+}
+```
+
+Next register it in `Program.cs`
+
+```csharp
+using MySite.Middleware;
+
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddSingleton();
+
+builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .Build();
+
+WebApplication app = builder.Build();
+
+app.UseMiddleware();
+
+await app.BootUmbracoAsync();
+...
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/crosssitescriptingprotection.md b/16/umbraco-cms/extending/health-check/guides/crosssitescriptingprotection.md
new file mode 100644
index 00000000000..691135931ab
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/crosssitescriptingprotection.md
@@ -0,0 +1,11 @@
+# Health check: Cross-site scripting Protection (X-XSS-Protection header)
+
+{% hint style="warning" %}
+This header is non-standard and should not be used. Instead, it is recommended to use a [Content Security Policy (CSP)](./contentsecuritypolicy.md) header.
+
+For more information about the X-XSS-Protection header, and why it should not be used, see [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection).
+{% endhint %}
+
+## How to fix this health check
+
+This health check can be fixed by ensuring no middleware adds the header.
diff --git a/16/umbraco-cms/extending/health-check/guides/debugcompilationmode.md b/16/umbraco-cms/extending/health-check/guides/debugcompilationmode.md
new file mode 100644
index 00000000000..8395c9e09da
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/debugcompilationmode.md
@@ -0,0 +1,43 @@
+---
+description: Disable debug compilation mode in Umbraco to boost performance by updating JSON configuration.
+---
+
+# Health check: Debug Compilation Mode
+
+_Leaving debug compilation mode enabled can severely slow down a website and take up more memory on the server._
+
+## How to fix this health check
+
+This health check can be fixed by providing configuration on the following path: `Umbraco:CMS:Hosting:Debug`.
+
+This configuration can be setup in a configuration source of your choice. This guide shows how to set it up in one of the JSON file sources.
+
+### Updating the JSON configuration
+
+The following JSON needs to be merged into one of your JSON sources. By default the following JSON sources are used: `appSettings.json` and `appSettings..json`, e.g. `appSettings.Development.json` or `appSettings.Production.json`.
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Hosting": {
+ "Debug":
+ }
+ }
+ }
+}
+```
+
+One example that can be used for production:
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Hosting": {
+ "Debug": false
+ }
+ }
+ }
+}
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/excessiveheaders.md b/16/umbraco-cms/extending/health-check/guides/excessiveheaders.md
new file mode 100644
index 00000000000..bbab463ba86
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/excessiveheaders.md
@@ -0,0 +1,46 @@
+# Health check: Excessive Headers
+
+_Checks to see if your site reveals information in its headers that gives away unnecessary details about the technology used to build and host it._
+
+## How to fix this health check
+
+This health check can be fixed by removing headers before the response is started.
+
+Be aware these headers are often added by the server and not by the application.
+
+Unless you publicly expose the Kestrel server ([not recommended by Microsoft](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.1&tabs=aspnetcore2x#when-to-use-kestrel-with-a-reverse-proxy)), you can't handle this directly in middleware.
+
+### Removing headers when hosted on IIS
+
+For IIS you will need to manipulate `web.config` (If you don't have `web.config` already in your project you will need to add it at the root). Ensure to remove the custom `X-Powered-By` and `Server` header as shown in the following example.
+
+{% hint style="info" %}
+The `removeServerHeader` attribute is added in IIS 10.0 and does not work in versions of Windows prior to Windows Server version 1709 or Windows 10 version 1709.
+{% endhint %}
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Removing headers when hosted on Kestrel
+
+By default Kestrel will only expose the `Server` header. To disable this, you have to configure Kestrel in `Program.cs`. You can use the `UseKestrel` extension method on `WebApplicationBuilder` like in the following example.
+
+```csharp
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
+
+builder.WebHost.UseKestrel(options => options.AddServerHeader = false);
+...
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/fixedapplicationurl.md b/16/umbraco-cms/extending/health-check/guides/fixedapplicationurl.md
new file mode 100644
index 00000000000..a8d9223a671
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/fixedapplicationurl.md
@@ -0,0 +1,42 @@
+# Health check: Fixed Application URL
+
+_Check to make sure a fixed application URL is specified. This URL is for example used when sending emails from backoffice.
+If this is not specified in configuration, Umbraco gets the application URL from last host used to request the application_
+
+
+## How to fix this health check
+
+This health check can be fixed by providing configuration on the following path: `Umbraco:CMS:WebRouting:UmbracoApplicationUrl`.
+
+This configuration can be setup in a configuration source of your choice. This guide shows how to set it up in one of the JSON file sources.
+
+### Updating the JSON configuration
+
+The following JSON needs to be merged into one of your JSON sources. By default the following JSON sources are used: `appSettings.json` and `appSettings..json`, e.g. `appSettings.Development.json` or `appSettings.Production.json`.
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "WebRouting": {
+ "UmbracoApplicationUrl": "string"
+ }
+ }
+ }
+}
+```
+
+One example that can be used in production
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "WebRouting": {
+ "UmbracoApplicationUrl": "https://www.my-custom-domain.com/"
+ }
+ }
+ }
+}
+```
+{% hint style="info" %} If the site is hosted on Umbraco Cloud, changing the above configuration will have no effect. The site will always use the URL set in the`umbraco-cloud.json` file, which can not be changed. {% endhint %}
diff --git a/16/umbraco-cms/extending/health-check/guides/folderandfilepermissions.md b/16/umbraco-cms/extending/health-check/guides/folderandfilepermissions.md
new file mode 100644
index 00000000000..95dd3ded7e0
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/folderandfilepermissions.md
@@ -0,0 +1,25 @@
+# Folder & File Permissions
+
+_Checks that the web server folder and file permissions are set correctly for Umbraco to run._
+
+## How to fix this health check
+
+This health check can be fixed by ensuring that the process running Umbraco also has write access to the listed folders and files.
+
+### Updating the file permissions on Windows
+
+Here's an example of how to adjust permissions for a folder. This process works the same way for files.
+
+First we see an example of an error from the health check
+
+
+
+To fix this, we find the specified folder, from the report and choose `Properties` and the `Security` tab.
+
+ 
+
+From here you can edit the permissions for a specific user or user group.
+
+{% hint style="info" %}
+For security reasons we recommend only giving write access to the required users or groups.
+{% endhint %}
diff --git a/16/umbraco-cms/extending/health-check/guides/httpsconfiguration.md b/16/umbraco-cms/extending/health-check/guides/httpsconfiguration.md
new file mode 100644
index 00000000000..e96bd7b1a83
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/httpsconfiguration.md
@@ -0,0 +1,43 @@
+# Health check: HTTPS Configuration
+
+_Checks if your site is configured to work over HTTPS and if the Umbraco related configuration for that is correct._
+
+## How to fix this health check
+
+This health check checks a couple of things.
+
+First of all, it ensures that your website is running on HTTPS using a valid certificate.
+
+Furthermore, it is used to specify the configuration on the following path: `Umbraco:CMS:Global:UseHttps`.
+
+This configuration can be setup in a configuration source of your choice. This guide shows how to set it up in one of the JSON file sources.
+
+### Updating the JSON configuration
+
+The following JSON needs to be merged into one of your JSON sources. By default the following JSON sources are used: `appSettings.json` and `appSettings..json`, e.g. `appSettings.Development.json` or `appSettings.Production.json`.
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Global": {
+ "UseHttps":
+ }
+ }
+ }
+}
+```
+
+One example that can be used:
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Global": {
+ "UseHttps": true
+ }
+ }
+ }
+}
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/images/failed_healthcheck_folder_permissions.png b/16/umbraco-cms/extending/health-check/guides/images/failed_healthcheck_folder_permissions.png
new file mode 100644
index 00000000000..6dc15b3c5af
Binary files /dev/null and b/16/umbraco-cms/extending/health-check/guides/images/failed_healthcheck_folder_permissions.png differ
diff --git a/16/umbraco-cms/extending/health-check/guides/images/folder_properties.png b/16/umbraco-cms/extending/health-check/guides/images/folder_properties.png
new file mode 100644
index 00000000000..871cf463060
Binary files /dev/null and b/16/umbraco-cms/extending/health-check/guides/images/folder_properties.png differ
diff --git a/16/umbraco-cms/extending/health-check/guides/images/folder_properties_security.png b/16/umbraco-cms/extending/health-check/guides/images/folder_properties_security.png
new file mode 100644
index 00000000000..79a3fc7122e
Binary files /dev/null and b/16/umbraco-cms/extending/health-check/guides/images/folder_properties_security.png differ
diff --git a/16/umbraco-cms/extending/health-check/guides/notificationemail.md b/16/umbraco-cms/extending/health-check/guides/notificationemail.md
new file mode 100644
index 00000000000..3ecbe7747fb
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/notificationemail.md
@@ -0,0 +1,43 @@
+# Health check: Notification Email Settings
+
+_If notifications are used, the 'from' email address should be specified and changed from the default value._
+
+## How to fix this health check
+
+This health check can be fixed by providing configuration on the following path: `Umbraco:CMS:Content:Notifications:Email`.
+
+This configuration can be setup in a configuration source of your choice. This guide shows how to set it up in one of the JSON file sources.
+
+### Updating the JSON configuration
+
+The following JSON needs to be merged into one of your JSON sources. By default the following JSON sources are used: `appSettings.json` and `appSettings..json`, e.g. `appSettings.Development.json` or `appSettings.Production.json`.
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Content": {
+ "Notifications": {
+ "Email": ""
+ }
+ }
+ }
+ }
+}
+```
+
+One example that can be used:
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Content": {
+ "Notifications": {
+ "Email": "no-reply@domain.com"
+ }
+ }
+ }
+ }
+}
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/smtp.md b/16/umbraco-cms/extending/health-check/guides/smtp.md
new file mode 100644
index 00000000000..8fce916f7b5
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/smtp.md
@@ -0,0 +1,52 @@
+# Health check: SMTP
+
+_Checks that valid settings for sending emails are in place._
+
+## How to fix this health check
+
+This health check can be fixed by providing configuration on the following path: `Umbraco:CMS:Global:Smtp`
+
+This configuration can be setup in a configuration source of your choice. This guide shows how to set it up in one of the JSON file sources.
+
+### Updating the JSON configuration
+
+The following JSON needs to be merged into one of your JSON sources. By default the following JSON sources are used: `appSettings.json` and `appSettings..json`, e.g. `appSettings.Development.json` or `appSettings.Production.json`.
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Global": {
+ "Smtp": {
+ "From": "",
+ "Host": "",
+ "Port": ,
+ "PickupDirectoryLocation": "",
+ "Username": "",
+ "Password": "",
+ "DeliveryMethod": "",
+ "SecureSocketOptions": ""
+ }
+ }
+ }
+ }
+}
+```
+
+An example that can be used on localhost, is if you have a local Simple Mail Transfer Protocol (SMTP) server running during development. This could be a tool like [Smtp4dev](https://github.com/rnwood/smtp4dev).
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Global": {
+ "Smtp": {
+ "From": "my@email.com",
+ "Host": "localhost",
+ "Port": 25
+ }
+ }
+ }
+ }
+}
+```
diff --git a/16/umbraco-cms/extending/health-check/guides/stricttransportsecurityheader.md b/16/umbraco-cms/extending/health-check/guides/stricttransportsecurityheader.md
new file mode 100644
index 00000000000..72cea315e11
--- /dev/null
+++ b/16/umbraco-cms/extending/health-check/guides/stricttransportsecurityheader.md
@@ -0,0 +1,40 @@
+---
+description: "Learn about the health checks that check for cookie hijacking and protocol downgrade attacks protection."
+---
+
+# Strict-Transport-Security Header
+
+Checks if your site, when running with HTTPS, contains the Strict-Transport-Security Header (HSTS).
+
+## How to fix this health check
+
+This health check can be fixed by adding the `Strict-Transport-Security` header to responses. The header tells browsers that future requests should be made over HTTPS only.
+
+{% hint style="warning" %}
+Enabling HSTS on a domain will cause browsers to only use HTTPS (not HTTP) to communicate with your site. Only enable HSTS on domains that can, and should, use HTTPS exclusively.
+{% endhint %}
+
+### Using the UseHsts extension method
+
+ASP.NET Core implements HSTS with the `UseHsts` extension method.
+
+You can add `UseHsts` after the `env.IsDevelopment()` check-in `Program.cs`.
+
+```csharp
+if (builder.Environment.IsDevelopment())
+{
+ app.UseDeveloperExceptionPage();
+}
+else
+{
+ app.UseHsts();
+}
+ //...
+}
+```
+
+This example only enables HSTS if the app is not running in development mode. `UseHsts` isn't recommended in development because the HSTS settings are highly cacheable by browsers.
+
+It is possible to configure a timespan for the HSTS, preferably six months. This can be done by adding a new builder to the `Program.cs` file. Learn more in the [official Microsoft Documentation](https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-8.0&tabs=visual-studio%2Clinux-ubuntu#http-strict-transport-security-protocol-hsts).
+
+Full details of `UseHsts`, and additional configuration, can be found in the [ASP.NET Core documentation](https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-8.0&tabs=visual-studio%2Clinux-ubuntu#http-strict-transport-security-protocol-hsts).
diff --git a/16/umbraco-cms/extending/images/Canvas_tab (1).png b/16/umbraco-cms/extending/images/Canvas_tab (1).png
new file mode 100644
index 00000000000..1e6b0c0730a
Binary files /dev/null and b/16/umbraco-cms/extending/images/Canvas_tab (1).png differ
diff --git a/16/umbraco-cms/extending/images/Canvas_tab (2).png b/16/umbraco-cms/extending/images/Canvas_tab (2).png
new file mode 100644
index 00000000000..1e6b0c0730a
Binary files /dev/null and b/16/umbraco-cms/extending/images/Canvas_tab (2).png differ
diff --git a/16/umbraco-cms/extending/images/Canvas_tab.png b/16/umbraco-cms/extending/images/Canvas_tab.png
new file mode 100644
index 00000000000..1e6b0c0730a
Binary files /dev/null and b/16/umbraco-cms/extending/images/Canvas_tab.png differ
diff --git a/16/umbraco-cms/extending/images/Docs_tab (1).png b/16/umbraco-cms/extending/images/Docs_tab (1).png
new file mode 100644
index 00000000000..ac21325f172
Binary files /dev/null and b/16/umbraco-cms/extending/images/Docs_tab (1).png differ
diff --git a/16/umbraco-cms/extending/images/Docs_tab (2).png b/16/umbraco-cms/extending/images/Docs_tab (2).png
new file mode 100644
index 00000000000..ac21325f172
Binary files /dev/null and b/16/umbraco-cms/extending/images/Docs_tab (2).png differ
diff --git a/16/umbraco-cms/extending/images/Docs_tab.png b/16/umbraco-cms/extending/images/Docs_tab.png
new file mode 100644
index 00000000000..ac21325f172
Binary files /dev/null and b/16/umbraco-cms/extending/images/Docs_tab.png differ
diff --git a/16/umbraco-cms/extending/images/Embed-Button.png b/16/umbraco-cms/extending/images/Embed-Button.png
new file mode 100644
index 00000000000..c52341893ad
Binary files /dev/null and b/16/umbraco-cms/extending/images/Embed-Button.png differ
diff --git a/16/umbraco-cms/extending/images/Embed-YouTube.png b/16/umbraco-cms/extending/images/Embed-YouTube.png
new file mode 100644
index 00000000000..ae6456c438c
Binary files /dev/null and b/16/umbraco-cms/extending/images/Embed-YouTube.png differ
diff --git a/16/umbraco-cms/extending/images/content-app-1.png b/16/umbraco-cms/extending/images/content-app-1.png
new file mode 100644
index 00000000000..ffae7300253
Binary files /dev/null and b/16/umbraco-cms/extending/images/content-app-1.png differ
diff --git a/16/umbraco-cms/extending/images/content-app-2.png b/16/umbraco-cms/extending/images/content-app-2.png
new file mode 100644
index 00000000000..b3b479c6c3c
Binary files /dev/null and b/16/umbraco-cms/extending/images/content-app-2.png differ
diff --git a/16/umbraco-cms/extending/images/content-app-badge-v9.png b/16/umbraco-cms/extending/images/content-app-badge-v9.png
new file mode 100644
index 00000000000..7afd0e57dc3
Binary files /dev/null and b/16/umbraco-cms/extending/images/content-app-badge-v9.png differ
diff --git a/16/umbraco-cms/extending/images/content-app-badge.png b/16/umbraco-cms/extending/images/content-app-badge.png
new file mode 100644
index 00000000000..80d3b00631e
Binary files /dev/null and b/16/umbraco-cms/extending/images/content-app-badge.png differ
diff --git a/16/umbraco-cms/extending/images/content-apps-location.png b/16/umbraco-cms/extending/images/content-apps-location.png
new file mode 100644
index 00000000000..7192d228876
Binary files /dev/null and b/16/umbraco-cms/extending/images/content-apps-location.png differ
diff --git a/16/umbraco-cms/extending/images/content-dashboards.png b/16/umbraco-cms/extending/images/content-dashboards.png
new file mode 100644
index 00000000000..f2ef027c2e8
Binary files /dev/null and b/16/umbraco-cms/extending/images/content-dashboards.png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (1).png b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (1).png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (1).png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (2).png b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (2).png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (2).png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (3).png b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (3).png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1) (3).png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1).png b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1).png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (1).png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (2).png b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (2).png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1) (2).png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8 (1).png b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1).png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8 (1).png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific-v8.png b/16/umbraco-cms/extending/images/contentTypespecific-v8.png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific-v8.png differ
diff --git a/16/umbraco-cms/extending/images/contentTypespecific.png b/16/umbraco-cms/extending/images/contentTypespecific.png
new file mode 100644
index 00000000000..06cfabb8035
Binary files /dev/null and b/16/umbraco-cms/extending/images/contentTypespecific.png differ
diff --git a/16/umbraco-cms/extending/images/db-table (1).png b/16/umbraco-cms/extending/images/db-table (1).png
new file mode 100644
index 00000000000..f5bae665216
Binary files /dev/null and b/16/umbraco-cms/extending/images/db-table (1).png differ
diff --git a/16/umbraco-cms/extending/images/db-table (2).png b/16/umbraco-cms/extending/images/db-table (2).png
new file mode 100644
index 00000000000..f5bae665216
Binary files /dev/null and b/16/umbraco-cms/extending/images/db-table (2).png differ
diff --git a/16/umbraco-cms/extending/images/db-table.png b/16/umbraco-cms/extending/images/db-table.png
new file mode 100644
index 00000000000..f5bae665216
Binary files /dev/null and b/16/umbraco-cms/extending/images/db-table.png differ
diff --git a/16/umbraco-cms/extending/images/developer-dashboards.png b/16/umbraco-cms/extending/images/developer-dashboards.png
new file mode 100644
index 00000000000..1304c5c1805
Binary files /dev/null and b/16/umbraco-cms/extending/images/developer-dashboards.png differ
diff --git a/16/umbraco-cms/extending/images/deviantart-embedded-media.png b/16/umbraco-cms/extending/images/deviantart-embedded-media.png
new file mode 100644
index 00000000000..ca8a8902ac1
Binary files /dev/null and b/16/umbraco-cms/extending/images/deviantart-embedded-media.png differ
diff --git a/16/umbraco-cms/extending/images/element-v8.png b/16/umbraco-cms/extending/images/element-v8.png
new file mode 100644
index 00000000000..878ce70c25b
Binary files /dev/null and b/16/umbraco-cms/extending/images/element-v8.png differ
diff --git a/16/umbraco-cms/extending/images/element.png b/16/umbraco-cms/extending/images/element.png
new file mode 100644
index 00000000000..75bdeea01cc
Binary files /dev/null and b/16/umbraco-cms/extending/images/element.png differ
diff --git a/16/umbraco-cms/extending/images/getting-started-dashboard.jpg b/16/umbraco-cms/extending/images/getting-started-dashboard.jpg
new file mode 100644
index 00000000000..3af5f1808e3
Binary files /dev/null and b/16/umbraco-cms/extending/images/getting-started-dashboard.jpg differ
diff --git a/16/umbraco-cms/extending/images/image-position-v8.png b/16/umbraco-cms/extending/images/image-position-v8.png
new file mode 100644
index 00000000000..7a9995081f5
Binary files /dev/null and b/16/umbraco-cms/extending/images/image-position-v8.png differ
diff --git a/16/umbraco-cms/extending/images/image-position.png b/16/umbraco-cms/extending/images/image-position.png
new file mode 100644
index 00000000000..f6b86300305
Binary files /dev/null and b/16/umbraco-cms/extending/images/image-position.png differ
diff --git a/16/umbraco-cms/extending/images/introstep.png b/16/umbraco-cms/extending/images/introstep.png
new file mode 100644
index 00000000000..ca631766a82
Binary files /dev/null and b/16/umbraco-cms/extending/images/introstep.png differ
diff --git a/16/umbraco-cms/extending/images/step-event-element-v8.png b/16/umbraco-cms/extending/images/step-event-element-v8.png
new file mode 100644
index 00000000000..185991d1530
Binary files /dev/null and b/16/umbraco-cms/extending/images/step-event-element-v8.png differ
diff --git a/16/umbraco-cms/extending/images/step-event-element.png b/16/umbraco-cms/extending/images/step-event-element.png
new file mode 100644
index 00000000000..fb12fee4e39
Binary files /dev/null and b/16/umbraco-cms/extending/images/step-event-element.png differ
diff --git a/16/umbraco-cms/extending/images/stepcontent-v8.png b/16/umbraco-cms/extending/images/stepcontent-v8.png
new file mode 100644
index 00000000000..cf0776b57d0
Binary files /dev/null and b/16/umbraco-cms/extending/images/stepcontent-v8.png differ
diff --git a/16/umbraco-cms/extending/images/stepcontent.png b/16/umbraco-cms/extending/images/stepcontent.png
new file mode 100644
index 00000000000..adbe84d994a
Binary files /dev/null and b/16/umbraco-cms/extending/images/stepcontent.png differ
diff --git a/16/umbraco-cms/extending/images/steptitle-v8.png b/16/umbraco-cms/extending/images/steptitle-v8.png
new file mode 100644
index 00000000000..522e3008c1a
Binary files /dev/null and b/16/umbraco-cms/extending/images/steptitle-v8.png differ
diff --git a/16/umbraco-cms/extending/images/steptitle.png b/16/umbraco-cms/extending/images/steptitle.png
new file mode 100644
index 00000000000..c3ea636c953
Binary files /dev/null and b/16/umbraco-cms/extending/images/steptitle.png differ
diff --git a/16/umbraco-cms/extending/images/the-dashboard-package.png b/16/umbraco-cms/extending/images/the-dashboard-package.png
new file mode 100644
index 00000000000..e565eea3cf4
Binary files /dev/null and b/16/umbraco-cms/extending/images/the-dashboard-package.png differ
diff --git a/16/umbraco-cms/extending/images/tourallowdisable-v8.png b/16/umbraco-cms/extending/images/tourallowdisable-v8.png
new file mode 100644
index 00000000000..ba501f4fd87
Binary files /dev/null and b/16/umbraco-cms/extending/images/tourallowdisable-v8.png differ
diff --git a/16/umbraco-cms/extending/images/tourallowdisable.png b/16/umbraco-cms/extending/images/tourallowdisable.png
new file mode 100644
index 00000000000..7d24eae70e6
Binary files /dev/null and b/16/umbraco-cms/extending/images/tourallowdisable.png differ
diff --git a/16/umbraco-cms/extending/images/tourgroup-v8.png b/16/umbraco-cms/extending/images/tourgroup-v8.png
new file mode 100644
index 00000000000..b2a4a7efb38
Binary files /dev/null and b/16/umbraco-cms/extending/images/tourgroup-v8.png differ
diff --git a/16/umbraco-cms/extending/images/tourgroup.png b/16/umbraco-cms/extending/images/tourgroup.png
new file mode 100644
index 00000000000..2509c199dba
Binary files /dev/null and b/16/umbraco-cms/extending/images/tourgroup.png differ
diff --git a/16/umbraco-cms/extending/images/tourname-v8.png b/16/umbraco-cms/extending/images/tourname-v8.png
new file mode 100644
index 00000000000..e247687d244
Binary files /dev/null and b/16/umbraco-cms/extending/images/tourname-v8.png differ
diff --git a/16/umbraco-cms/extending/images/tourname.png b/16/umbraco-cms/extending/images/tourname.png
new file mode 100644
index 00000000000..91466067eb7
Binary files /dev/null and b/16/umbraco-cms/extending/images/tourname.png differ
diff --git a/16/umbraco-cms/extending/images/welcome-dashboard.jpg b/16/umbraco-cms/extending/images/welcome-dashboard.jpg
new file mode 100644
index 00000000000..60c31089586
Binary files /dev/null and b/16/umbraco-cms/extending/images/welcome-dashboard.jpg differ
diff --git a/16/umbraco-cms/extending/key-vault.md b/16/umbraco-cms/extending/key-vault.md
new file mode 100644
index 00000000000..d0e00cc0780
--- /dev/null
+++ b/16/umbraco-cms/extending/key-vault.md
@@ -0,0 +1,260 @@
+---
+description: A guide for configuring Azure Key Vault
+---
+
+# Configuring Azure Key Vault
+
+From a security perspective, storing your application secrets in Azure Key Vault is always a good solution. This could be a connection string or other keys.
+
+This article tells you how to configure your application so it is ready to use a Key Vault.
+
+Depending on your hosting situation there are a few approaches to incorporating Azure Key Vault into your application.
+
+1. [Install Key Vault via Nuget (for most Hosting scenarios)](key-vault.md#install-key-vault-via-nuget)
+2. [Use Key Vault references for Azure App Service (For Azure Web App Hosting)](key-vault.md#use-key-vault-references-for-azure-app-service)
+
+## Install Key Vault via Nuget
+
+Before you begin, you need to install the `Azure.Extensions.AspNetCore.Configuration.Secrets` and the `Azure.Identity` NuGet packages. There are two approaches to installing the packages:
+
+1. Use your favorite Integrated Development Environment (IDE) and open up the NuGet Package Manager to search and install the packages
+2. Use the command line to install the package
+
+### Installing through command line
+
+Navigate to your project folder, which is the folder that contains your `.csproj` file. Now use the following `dotnet add package` command to install the packages:
+
+```
+dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
+dotnet add package Azure.Identity
+```
+
+### Configuration
+
+{% hint style="info" %}
+You can find the database connection string under the `Umbraco:CMS:ConnectionStrings` section in the `appsettings.json` file. For more information, see the [Connection strings settings](../reference/configuration/connectionstringssettings.md) article.
+{% endhint %}
+
+The next step is to add the Azure Key Vault endpoint to the `appsettings.json` file (or create as an Environment Variable). You can add this endpoint in the root or anywhere in the `appsettings.json` as long as it is resolved in the `ConfigureAppConfiguration` method.
+
+```json
+{
+ "AzureKeyVaultEndpoint": "https://{your-key-vault-name}.vault.azure.net",
+}
+```
+
+After adding the endpoint in the appsettings, it's time to add configuration so that the KeyVault is used. One way to achieve this is to write an extension method for the `WebApplicationBuilder`:
+
+```csharp
+using System;
+using Azure.Identity;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Configuration;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Extensions;
+
+namespace My.Website;
+
+public static class WebApplicationBuilderExtensions
+{
+ public static WebApplicationBuilder ConfigureKeyVault(this WebApplicationBuilder builder)
+ {
+ var keyVaultEndpoint = builder.Configuration["AzureKeyVaultEndpoint"];
+ if (!string.IsNullOrWhiteSpace(keyVaultEndpoint) && Uri.TryCreate(keyVaultEndpoint, UriKind.Absolute, out var validUri))
+ {
+ builder.Configuration.AddAzureKeyVault(validUri, new DefaultAzureCredential());
+ }
+
+ return builder;
+ }
+}
+```
+
+After creating the extension method, it's possible to call it from the `Program.cs` class, like so:
+
+```csharp
+using Microsoft.AspNetCore.Builder;
+using My.Project;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Extensions;
+
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
+
+builder.ConfigureKeyVault();
+
+builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .Build();
+
+WebApplication app = builder.Build();
+
+await app.BootUmbracoAsync();
+
+app.UseUmbraco()
+ .WithMiddleware(u =>
+ {
+ u.UseBackOffice();
+ u.UseWebsite();
+ })
+ .WithEndpoints(u =>
+ {
+ u.UseBackOfficeEndpoints();
+ u.UseWebsiteEndpoints();
+ });
+
+await app.RunAsync();
+```
+
+### Authentication
+
+There are different ways to access the Azure Key Vault. It is important that the user you are logging in with has access to the Key Vault. You can assign roles using the Azure Portal.
+
+1. Navigate to your Key Vault.
+2. Select Access Control.
+3. Select Add -> Add role assignment.
+4. Select the preferred role.
+5. Search for the user.
+6. Click review + assign
+
+## Use Key Vault references for Azure App Service
+
+Azure Web Apps offers the ability to directly reference Key Vault secrets as App Settings. The benefit of this is you can securely store your secrets in Key Vault without any code changes required in your application.
+
+### Create a System Assigned Managed Identity
+
+To begin we first need to create a **Managed Identity** for the Azure Web App. This enables us to grant granular permissions to an identity representing the Web App.
+
+Head over to your Azure Web App and find **Identity** under **Settings**:
+
+
+
+Under **System assigned** change the Status from Off to **On**.
+
+
+
+A GUID will then be generated called **Object (principal) ID**. Take note of this ID as we will need it further on.
+
+### Update your Key Vault Access Policy
+
+{% hint style="info" %}
+Alternatively, you can use Role-Based Access Control on your Azure Key Vault.
+
+Learn more about the difference between the two approaches and how to migrate between them on the [Azure Documentation platform](https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-access-policy).
+{% endhint %}
+
+It is assumed you already have a Key Vault set up with a few Umbraco secrets inside. In your Key Vault head to **Access Policies**.
+
+
+
+At the top select **+ Create**. We are now going to add the **System Managed Identity** for the Web App to Key Vault.
+
+
+
+You will now be presented with different permissions to set for your Web App. You only need **Get** and **List** for **Secret Permissions** only. Click **Next** to continue:
+
+
+
+Enter the GUID you took note of earlier, into the **Search Box**. You will see your Web App listed.
+
+
+
+Click your Web App to Select and click Next and then Create:
+
+
+
+If you visit the **Access Policies** section again you should now see your web app in the list and its permissions:
+
+
+
+### Link our Key Vault Secret to an Azure Web App
+
+In your Azure Web App head to **Configuration** under **Settings**.
+
+
+
+Here we can add **App Settings** and **Connection Strings** to the environment.
+
+1. Let us start off with the **Umbraco Database Connection String**.
+
+Under Connection Strings, select **Advanced Edit**.
+
+
+
+Once you click on "**Advanced Edit"** a new window will open up. There you will need to paste in the following JSON Object inside the square brackets. Ensure you update `{keyvault-name}`, `{secret-name}` and `{version-id}`.
+
+```json
+{
+ "name": "umbracoDbDSN",
+ "value": "@Microsoft.KeyVault(SecretUri=https://{keyvault-name}.vault.azure.net/secrets/{secret-name}/{version-id}/)",
+ "type": "Custom",
+ "slotSetting": false
+}
+```
+
+{% hint style="info" %}
+You can obtain the Secret Uri by visiting the specific version of your secret and copying the Url:
+{% endhint %}
+
+
+
+The ID is optional but recommended as it enables you to control which version of the secret is used at your discretion. Leave it out if you always want the Web App to pull the latest version of the secret.
+
+Wait a moment and refresh the screen. You should see a Green tick. If you do not have a Green tick you need to review your Access Policies in the previous step.
+
+
+
+2. We will perform the same approach for our **App Settings**. We will be updating the following App Settings for Azure Blob Storage.
+
+```json
+"Umbraco": {
+ "Storage": {
+ "AzureBlob": {
+ "Media": {
+ "ConnectionString": "",
+ "ContainerName": ""
+ }
+ }
+ }
+```
+
+Due to the secrets being nested we need to use double underscore `__` to correctly reference the value on our Web App.
+
+On the Web App select **Advanced Edit** for Application Settings:
+
+
+
+When clicking on "Advanced Edit", a new window will open up. There you will need to paste in the following JSON Objects inside the square brackets. Ensure you update `{keyvault-name}`, `{secret-name}` and `{version-id}`.
+
+```json
+{
+ "name": "Umbraco__Storage__AzureBlob__Media__ConnectionString",
+ "value": "@Microsoft.KeyVault(SecretUri=https://{keyvault-name}.vault.azure.net/secrets/{secret-name}/{version-id}/)",
+ "slotSetting": false
+},
+{
+ "name": "Umbraco__Storage__AzureBlob__Media__ContainerName",
+ "value": "@Microsoft.KeyVault(SecretUri=https://{keyvault-name}.vault.azure.net/secrets/{secret-name}/{version-id}/)",
+ "slotSetting": false
+}
+```
+
+The ID is optional but recommended as it enables you to control which version of the secret is used at your discretion. Leave it out if you always want the Web App to pull the latest version of the secret.
+
+Wait a moment and refresh the screen. You should see Green ticks for both values. If you do not have a Green tick you need to review your Access Policies in the previous step.
+
+
+
+### Local Development
+
+1. [Sign in to Visual Studio using the credentials that can access the Key Vault.](https://docs.microsoft.com/en-us/visualstudio/ide/signing-in-to-visual-studio)
+2. [Use Azure CLI to store your preferred account into the credential cache.](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli)
+3. [An example of extending and referencing secrets in `appsettings.json` in your local development environment.](https://gist.github.com/tgreensill/26659111871fdc54d0ac20cc21e602e1)
+
+### Staging/Production
+
+1. [Managed identities for Azure resources](https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-6.0#use-managed-identities-for-azure-resources)
+2. [X.509 certificate for non-Azure-hosted apps](https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-6.0#use-application-id-and-x509-certificate-for-non-azure-hosted-apps)
+3. [Use Key Vault references for App Service and Azure Functions](https://learn.microsoft.com/en-us/azure/app-service/app-service-key-vault-references)
diff --git a/16/umbraco-cms/extending/language-files/README.md b/16/umbraco-cms/extending/language-files/README.md
new file mode 100644
index 00000000000..9770bcec6fa
--- /dev/null
+++ b/16/umbraco-cms/extending/language-files/README.md
@@ -0,0 +1,58 @@
+---
+description: >-
+ This article overviews how an Umbraco CMS website uses and manages
+ localization with language files.
+---
+
+# Language Files & Localization
+
+## Language Files & Localization
+
+Language files are used to localise the Umbraco backoffice, so Users can use Umbraco in their native language. This is particularly important for content editors who do not speak English.
+
+With language files, you can also:
+
+* Override existing (core) localizations.
+* Define localization for your own package.
+
+### [UI Localization](../../customizing/foundation/localization.md)
+
+Defines how to use the UI Umbraco Localization. This is the primary source of localization for the backoffice.
+
+### [.NET Localization](net-localization.md)
+
+Defines how to use the .NET Core Umbraco Localization. This is only relevant for localization that happens server-side - for example, for sending emails.
+
+{% hint style="info" %}
+You can use localization files for Document and Media Types as well. You can find more information about this in the [Document Type Localization](../../fundamentals/data/defining-content/document-type-localization.md) article.
+{% endhint %}
+
+## Supported Languages
+
+Current [languages](https://github.com/umbraco/Umbraco-CMS/tree/contrib/src/Umbraco.Core/EmbeddedResources/Lang) with their ISO codes that are included in new Umbraco installations are:
+
+* `bs-BS` - Bosnian (Bosnia and Herzegovina)
+* `cs-CZ` - Czech (Czech Republic)
+* `cy-GB` - Welsh (United Kingdom)
+* `da-DK` - Danish (Denmark)
+* `de-DE` - German (Germany)
+* `en` - **English (United Kingdom)** (fallback language)
+* `en-US` - English (United States)
+* `es-ES` - Spanish (Spain)
+* `fr-FR` - French (France)
+* `he-IL` - Hebrew (Israel)
+* `hr-HR` - Croatian (Croatia)
+* `it-IT` - Italian (Italy)
+* `ja-JP` - Japanese (Japan)
+* `ko-KR` - Korean (Korea)
+* `nb-NO` - Norwegian Bokmål (Norway)
+* `nl-NL` - Dutch (Netherlands)
+* `pl-PL` - Polish (Poland)
+* `pt-BR` - Portuguese (Brazil)
+* `ro-RO` - Romanian (Romania)
+* `ru-RU` - Russian (Russia)
+* `sv-SE` - Swedish (Sweden)
+* `tr-TR` - Turkish (Turkey)
+* `ua-UA` - Ukrainian (Ukraine)
+* `zh-CN` - Chinese (China)
+* `zh-TW` - Chinese (Taiwan)
diff --git a/16/umbraco-cms/extending/language-files/net-localization.md b/16/umbraco-cms/extending/language-files/net-localization.md
new file mode 100644
index 00000000000..d84a86072ac
--- /dev/null
+++ b/16/umbraco-cms/extending/language-files/net-localization.md
@@ -0,0 +1,116 @@
+---
+description: NET Umbraco Core Localization files.
+---
+
+# .NET Localization
+
+In this article, you will find information about the Core Localization files. You can also find information about where to find and use them, and how to keep them up-to-date.
+
+## Use cases
+
+.NET localization has limited use cases in Umbraco, as all backoffice localization is performed with [UI Localization](../../customizing/foundation/localization.md).
+
+In other words, .NET localization is only applied server-side with no accompanying UI - for example:
+
+* Sending emails.
+* User login error handling.
+* Health checks.
+
+## Where to find the core localization files
+
+The core Umbraco localization files are found at the following location within the [Umbraco source](https://github.com/umbraco/Umbraco-CMS/tree/contrib/src/Umbraco.Core/EmbeddedResources/Lang):
+
+```xml
+Umbraco-CMS/src/Umbraco.Core/EmbeddedResources/Lang/
+```
+
+These localization files are shipped with Umbraco and should not be modified.
+
+### User localization files
+
+If you want to override Umbraco Core .NET localization, create new files in the following location and format:
+
+```xml
+/config/lang/{language}.user.xml
+```
+
+{% hint style="info" %}
+The `/config/lang/` folders do not exist on a clean installation of the CMS. You will need to create them at the root of your project. In an Umbraco Cloud project this will need to be in the `src` project.
+{% endhint %}
+
+In order for these files to deploy when you do a `dotnet publish`, you need to add the following to your `.csproj` file:
+
+```xml
+
+
+
+```
+
+## Using the localizations
+
+`ILocalizedTextService` is used to localize strings, and is available through dependency injection. You can use the `Localize()` method available in the namespace `Umbraco.Extensions` to localize the string by `area` and `key`:
+
+```csharp
+using Umbraco.Cms.Core.Services;
+
+namespace UmbracoDocs.Samples;
+
+public class LocalizationSample
+{
+ private readonly ILocalizedTextService _localizedTextService;
+
+ public LocalizationSample(ILocalizedTextService localizedTextService)
+ => _localizedTextService = localizedTextService;
+
+ public string LocalizeMyText(string area, string key)
+ => _localizedTextService.Localize(area, key);
+}
+```
+
+## Help keep the language files up to date
+
+As Umbraco is a continually evolving product it is inevitable that new text is added regularly to the English language version of these files. This may mean that some of the above languages are no longer up to date.
+
+If a translation is missing, the key "**alias**" used will be shown within the user interface, as an example:
+
+```xml
+[assignDomain]
+```
+
+The language files are XML files with a straight-forward layout as seen below.
+
+```xml
+
+
+
+ The Umbraco community
+ https://community.umbraco.com
+
+
+ Culture and Hostnames
+ Audit Trail
+ ...
+
+ ...
+
+```
+
+In the above example of a missing translation for "**assignDomain**", locate this string in the en.xml file. Then copy the whole "**Key**" element into the relevant language file. Afterwards you can translate the text, as an example here is the Spanish version of the above snippet:
+
+```xml
+
+
+
+ The Umbraco community
+ https://community.umbraco.com
+
+
+ Administrar hostnames
+ Auditoría
+ ...
+
+ ...
+
+```
+
+If you modify core language files or introduce a new language, you can assist the community by sharing your updates. This can be done by [submitting a pull request](https://github.com/umbraco/Umbraco-CMS/blob/contrib/.github/CONTRIBUTING.md) so that your changes are merged into the core.
diff --git a/16/umbraco-cms/extending/packages/README.md b/16/umbraco-cms/extending/packages/README.md
new file mode 100644
index 00000000000..bb9c6ac7fff
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/README.md
@@ -0,0 +1,72 @@
+---
+description: "A package extends the functionality of Umbraco to provide additional functionality to editors, developers, site visitors, and all other types of users of Umbraco."
+---
+
+# Packages
+
+## What is a Package?
+
+A package extends Umbraco to provide additional functionality to editors, developers, site visitors, and all other types of users of Umbraco. It can impact one or more of these groups of people depending on the type of package.
+
+An Umbraco Package can be many things, but is generally characterized by:
+
+- Adding or extending functionality in the Umbraco CMS
+- Empowering people to do more and/or do things more efficiently
+- Engaging community members in collaboration and sharing
+- Solving real life problems
+- Inspiring people on what Umbraco can be made capable of
+
+### Categories of packages
+
+Packages provide a wide variety of functionality, and can often span multiple categories. In general, though, the functionality they provide fall into these main groups:
+
+- [Schema Extensions](#schema-extensions)
+- [Management Extensions](#management-extensions)
+- [Starter Kits](#starter-kits)
+- [Integration Extensions](#integration-extensions)
+
+#### Schema Extensions
+
+A package that can be categorized as a Schema Extension will extend the default Umbraco Schema. Schema in this sense refers to things like Data Types, Property Editors, Document Types and Media Types. By extending Umbraco with packages such as [Our.Umbraco.GMaps](https://marketplace.umbraco.com/package/our.umbraco.gmaps) editors are given greater capabilities when they are populating their content pages.
+
+#### Management Extensions
+
+A Management Extension package helps you manage your site, and provides information to the users. Management extensions typically contain custom sections or dashboards to facilitate site management. [Diplo God Mode](https://marketplace.umbraco.com/package/diplo.godmode) is an example of a comprehensive management extension package with additional tools and information.
+
+#### Starter Kits
+
+Starter kits are, as the name suggests, a package that helps you set up a starter version of whatever you want to build. Most starter kit packages are for starting a website, and include schema like Document Types and Templates as well as content nodes and media. There are also some specialized starter kits, for example for creating a blog. Umbraco HQ has released their [own starter kit](https://www.nuget.org/packages/Umbraco.TheStarterKit), that creates a small site with the most commonly used features.
+
+#### Workspace Views
+
+Workspace Views are almost like dashboards for content nodes that are intended to display node specific information. A good example of this is the [Preflight](https://marketplace.umbraco.com/package/preflight.umbraco) content app. It shows you readability scores for your written content, directly on each content node.
+
+#### Integration extensions
+
+This type of package can be a lot of things, and can include a number of the other package types. They are generally integrating a larger system into Umbraco. A good example could be an e-commerce package such as [Umbraco Commerce](https://docs.umbraco.com/umbraco-commerce), that includes an entire webshop module for Umbraco.
+
+## [Creating a Package](creating-a-package.md)
+
+This short tutorial will teach you how to create a package in the Umbraco backoffice. It will also give a quick overview of what a generated package will contain.
+
+## [Language file for packages](language-files-for-packages.md)
+
+Package authors who would like their UI to be multi-lingual can include their own set of language files as part of their package distribution.
+
+## [Listing a Package on the Umbraco Marketplace](listing-on-marketplace.md)
+
+Once you've created a package make it available on the Umbraco Marketplace to share it with the community.
+
+## [Packages on Umbraco Cloud](packages-on-umbraco-cloud.md)
+
+Things you should know if you are developing for Umbraco Cloud.
+
+## [Maintaining Packages](maintaining-packages.md)
+
+Some guidance on how to maintain your package after release.
+
+## [An Example Package Repository](example-package-repository.md)
+
+There are many ways to build and deploy your package to NuGet. You will likely have your own approach for organizing a solution and preferred tools for build and deployment.
+
+If you are looking for inspiration to follow form some tried and tested packages, read more here.
diff --git a/16/umbraco-cms/extending/packages/accessibility.md b/16/umbraco-cms/extending/packages/accessibility.md
new file mode 100644
index 00000000000..733e096667f
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/accessibility.md
@@ -0,0 +1,22 @@
+# Create accessible Umbraco packages
+
+Creating accessible packages extends on accessibility in an [Umbraco context](https://www.skrift.io/issues/accessibility-in-an-umbraco-context/).
+
+The Umbraco UI components have been built to be accessible and have accessibility tests built within them. Building the user interface (UI) using these [Umbraco UI components](https://uui.umbraco.com/) ensures that the package is as accessible as the Umbraco backoffice.
+
+In addition, any fixes and updates to the UI components will be pushed through to the packages when you rebuild them with the updates.
+
+## Testing
+
+Accessibility testing is more a specialist skillset than it is automated testing. The purpose of this document is to outline what can be done to help build accessible packages. It is not a complete list of accessibility tests that can be performed.
+
+- Build the components using the [Umbraco UI components](https://uui.umbraco.com/) as these have accessibility tests built within them.
+- Use the keyboard to tab through the elements on the page checking:
+ - Does the element tabbed to have a **focus state**?
+ - Does the **tab order** make sense?
+ - More on focus, tab orders, other common interactions and techniques for keyboard testing can be found at [WebAIM: Keyboard Accessibility](https://webaim.org/techniques/keyboard/)
+- Check the UI with a screen reader.
+ - [Non Visual Desktop Access (NVDA) is a free Windows screen reader](https://www.nvaccess.org/download/) and some guidelines on screen reader testing are available from [WebAIM: Web Accessibility In Mind](https://webaim.org/articles/screenreader_testing/)
+- Install an accessibility testing tool as a plugin into your browser to run automated tests:
+ - Tools like [axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd) are built to reduce the number of false positives in a test.
+- If the UI does not follow the Umbraco Style, then check the contrast with a tool like the [Web Content Accessibility Guidelines (WCAG) Contrast Checker](https://chrome.google.com/webstore/detail/wcag-color-contrast-check/plnahcmalebffmaghcpcmpaciebdhgdf). This will help ensure contrast.
diff --git a/16/umbraco-cms/extending/packages/creating-a-package.md b/16/umbraco-cms/extending/packages/creating-a-package.md
new file mode 100644
index 00000000000..c11745c70ac
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/creating-a-package.md
@@ -0,0 +1,336 @@
+---
+description: Tutorial to create a package in Umbraco
+---
+
+# Creating a Package
+
+This tutorial demonstrates how to create a package in Umbraco. The process described is based on creating a package from the dashboard in the [Creating a Custom Dashboard Tutorial](../../tutorials/creating-a-custom-dashboard/). The same approach can be applied to other packages as well.
+
+## Creating a Package Schema in the Backoffice
+
+To begin creating a package, start by setting up a package schema in the Umbraco backoffice:
+
+1. Navigate to the `Packages` section.
+2. Select `Created` in the top-right corner of the screen.
+3. Click the `Create package` button.
+
+
+
+On the `Create package` page, there are different fields that allow you to define the contents of the package based on backoffice items.
+
+4. Enter the Package Name at the top. For this tutorial, name the package `Custom Welcome Dashboard` matching the name used in the [Creating a Custom Dashboard Tutorial](../../tutorials/creating-a-custom-dashboard/).
+5. Fill in the required fields. For more information, see the [Package Content Section](#package-content-section).
+6. Click `Create` to generate the package schema.
+7. Click `Download` to download the package and inspect its contents.
+
+### Package Content section
+
+These fields determine which backoffice items will be included in the package. For this example, the following settings are used:
+
+| Property | Value | Note |
+| -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Content | _Empty_ | Here, you can include content. For example, if you want to create a starter kit. Not relevant for this package though. |
+| Media | _Empty_ | Here, you can include media. For example, if you want to add media to the starter kit. Not relevant for this package though. |
+| Document Types | _Empty_ | Similar to the Content picker above. If you include content, you will also need to pick all its dependencies in this and the next steps for them to be packaged together. |
+| Media Types | _Empty_ | Similar to the Media picker above. If you include media, you will also need to pick all its dependencies in this and the next steps for them to be packaged together. |
+| Languages | _Empty_ | See `Document Types` above. All text is hardcoded or within the lang folder in this package, so this is not needed. |
+| Dictionary | _Empty_ | See `Document Types` above |
+| Data Types | _Empty_ | See `Document Types` above |
+| Templates | _Empty_ | See `Document Types` above |
+| Stylesheets | _Empty_ | These will come from the **wwwroot/css** folder. If you have stylesheets you want to include from other locations (_like App_Plugins folder_) you can do so at a later step. |
+| Scripts | _Empty_ | These will come from the **wwwroot/scripts** folder. If you have scripts you want to include from other locations (_like App_Plugins folder_) you can do so at a later step. |
+| Partial Views | _Empty_ | See `Document Types` above |
+
+## Inspecting the Package ZIP
+
+If the package includes backoffice-specific items, the downloaded ZIP will contain the `package.xml` along with a folder for any media items included. The contents of the ZIP package might look like this:
+
+
+
+The `package.xml` file contains the metadata for the package, while additional files (if any) are referenced within the XML.
+
+Below is an example of the `package.xml` file:
+
+```xml
+
+
+
+
+ Custom Welcome Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+This XML file contains package metadata, and references where Umbraco should place the files upon installation.
+
+Since this example package does not include backoffice items, only the package name appears, with other tags left empty.
+
+## Creating a NuGet package
+
+NuGet packages are the preferred method for distributing Umbraco extensions. NuGet enables better practices for source control and deployment. This section outlines how to create a NuGet package for the custom dashboard that extends Umbraco’s functionality.
+
+NuGet is the standard package manager for .NET. More details on NuGet can be found in the [Microsoft Documentation](https://docs.microsoft.com/en-us/nuget/what-is-nuget).
+
+### Generate an Empty Package Using a Template
+
+1. Install the latest [.NET SDK](https://dotnet.microsoft.com/download).
+2. Run `dotnet new install Umbraco.Templates` to install the project templates.
+3. Run `dotnet new umbraco-extension -n CustomWelcomeDashboard` to create a new package project.
+
+{% hint style="info" %}
+If the post-installation script fails due to PowerShell restrictions, manually run `npm install` and `npm run build` in the `Client` folder.
+{% endhint %}
+
+This command will generate the following files:
+
+
+
+Apart from the project file, the generated structure includes key folders and files that are essential for building an Umbraco extension.
+
+- **Client** - where you can place any front-end assets, such as JavaScript, CSS, and Angular views, that will be used in the backoffice.
+- **Composers** - intended for C# composer classes, which are used to register dependencies and configure services in Umbraco.
+- **Controllers** - where you can add API controllers if your package requires custom endpoints.
+- **Constants.cs** - serves as a placeholder for any global constants your package may need.
+
+Unlike previous versions, the `umbraco-extension` template does not generate a `package.manifest` file or an `App_Plugins` folder by default. If your package includes client-side assets for the backoffice, you will need to manually create an `App_Plugins/{YourPackageName}` folder.
+
+Additionally, the `.csproj` file is configured to support NuGet packaging, allowing you to distribute your extension. If you plan to include custom C# logic, the files you place in the root folder will be compiled into the package DLL.
+
+### Transfer Files
+
+Since the `umbraco-extension` template does not generate an `App_Plugins` folder by default, you will need to manually create it.
+
+1. Create an `App_Plugins` folder in the downloaded package folder.
+2. Go to the `welcome-dashboard` folder created in the [Creating a Custom Dashboard Tutorial](../../tutorials/creating-a-custom-dashboard/README.md#setting-up-a-package).
+3. Transfer or copy the `welcome-dashboard` folder in the `App_Plugins` folder.
+
+
+
+### Specify Package Properties
+
+You can specify package metadata directly in the `csproj` file. Here, is an example of some package properties:
+
+```xml
+
+
+ . . .
+ CustomWelcomeDashboard
+ Custom welcome dashboard for Umbraco.
+ umbraco plugin package
+ 1.0.0
+ Your Name
+ https://umbraco.com
+ MIT
+
+ . . .
+
+```
+
+Alternatively, right-click the `csproj` file in Visual Studio > **Properties** > **Package** and add the required information:
+
+
+
+The properties that can be specified include:
+
+| Property | Value | Note |
+| ------------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Version | 1.0.0 | This is automatically set to 1.0.0 but can be changed as appropriate. |
+| Authors | Your name | Here you get to take credit for your awesome work! |
+| PackageProjectUrl | https://umbraco.com | This URL will be shown as the package's URL when others install it. It will likely be a GitHub repository, or similar. |
+| PackageLicenseExpression | MIT | The license is set to MIT. Please consider how you want your package licensed. If in doubt when deciding an open-source license there are [good resources available](https://choosealicense.com/licenses/). |
+
+### Pack the Package
+
+To create the actual NuGet package, use the `dotnet pack` command. You can either output the package to the default `bin` folder or specify a custom location.
+
+#### Default Output
+
+Run the command in the package directory to generate the package in the `bin` folder:
+
+```sh
+dotnet pack
+```
+
+
+
+#### Custom Output Location
+
+To specify a different output location, use the following command:
+
+```sh
+dotnet pack --output MyNugetPackages
+```
+
+
+
+It will pack the project in the current directory and place the resulting package into the `MyNugetPackages` folder.
+
+### Publish the Package
+
+To share the package with others, publish it to a public NuGet repository, such as [https://nuget.org](https://nuget.org).
+
+The official [NuGet Documentation](https://docs.microsoft.com/en-us/nuget/nuget-org/publish-a-package) provides a detailed guide on how to publish a package to NuGet.org.
+
+To release packages to only a limited audience, see the [Hosting your own NuGet feeds](https://docs.microsoft.com/en-us/nuget/hosting-packages/overview) documentation.
+
+For Umbraco-specific packages, refer to the [Listing Your Package](https://docs.umbraco.com/umbraco-dxp/marketplace/listing-your-package) guide to feature your package on the Umbraco Marketplace.
+
+## Installing a NuGet Package
+
+To install the NuGet package, you can use Visual Studio, Rider, or the CLI.
+
+In the CLI, create a new Umbraco project and add the package reference:
+
+```cs
+dotnet new umbraco -n CustomWelcomeDashboardProject
+cd CustomWelcomeDashboardProject
+dotnet add package CustomWelcomeDashboard.1.0.0
+dotnet run
+```
+
+You can check that the NuGet package was referenced in your solution and that the **App_Plugins** assets were restored successfully. The custom dashboard should now be available in the Umbraco backoffice.
+
+For testing the package locally without publishing, use the `-p` flag to create a project that depends on the package. So when you build the new project, it will copy the **App_Plugins** folder from the package project into the test project.
+
+```cs
+dotnet new umbraco -n CustomWelcomeDashboardProject -p CustomWelcomeDashboard
+```
+
+Go to the `CustomWelcomeDashboardProject` directory, build your Umbraco website using the `dotnet build` command, and then run the application.
+
+### Package Migration
+
+Umbraco supports automatic and custom package migrations to handle content updates when a package is installed.
+
+#### Automatic Package Migration
+
+For schema and content packages, inherit from the `AutomaticPackageMigrationPlan` and specify the package name that is displayed under the packages _Installed_ tab in the backoffice. You will also need to embed the schema file in the same namespace.
+
+```csharp
+using Umbraco.Cms.Infrastructure.Packaging;
+
+namespace CustomWelcomeDashboardProject.Migrations;
+
+public class PackageMigrationPlan : AutomaticPackageMigrationPlan
+{
+ public PackageMigrationPlan() : base("Custom Welcome Dashboard")
+ {
+ }
+}
+```
+
+
+
+{% hint style="info" %}
+Whenever the embedded package.xml file changes, the automatic package migration plan is executed again. This is due to the fact that the migration state is based on the file hash. Existing schema or content will not be overwritten in this process.
+{% endhint %}
+
+#### Custom Package Migration
+
+Instead of creating an automatic package migration plan, we will inherit from the `PackageMigrationPlan` and again specify the name of the package in the base constructor. Further on, we will define the plan using a unique GUID - in the example below we have a single migration called `MyCustomMigration`.
+
+```csharp
+using Umbraco.Cms.Core.Packaging;
+
+namespace CustomWelcomeDashboardProject.Migrations;
+
+public class CustomPackageMigrationPlan : PackageMigrationPlan
+{
+ public CustomPackageMigrationPlan() : base("Custom Welcome Dashboard")
+ {
+ }
+
+ protected override void DefinePlan()
+ {
+ To(new Guid("4FD681BE-E27E-4688-922B-29EDCDCB8A49"));
+ }
+}
+```
+
+The custom migrations can inherit from `PackageMigrationBase` where we can use helper methods to pick up the schema. But we can also use the regular `MigrationBase` class.
+
+```csharp
+using Microsoft.Extensions.Options;
+using Umbraco.Cms.Core.Configuration.Models;
+using Umbraco.Cms.Core.IO;
+using Umbraco.Cms.Core.PropertyEditors;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Strings;
+using Umbraco.Cms.Infrastructure.Migrations;
+using Umbraco.Cms.Infrastructure.Packaging;
+
+namespace CustomWelcomeDashboardProject.Migrations;
+
+public class CustomPackageMigration : PackageMigrationBase
+{
+ public CustomPackageMigration(
+ IPackagingService packagingService,
+ IMediaService mediaService,
+ MediaFileManager mediaFileManager,
+ MediaUrlGeneratorCollection mediaUrlGenerators,
+ IShortStringHelper shortStringHelper,
+ IContentTypeBaseServiceProvider contentTypeBaseServiceProvider,
+ IMigrationContext context,
+ IOptions packageMigrationsSettings)
+ : base(
+ packagingService,
+ mediaService,
+ mediaFileManager,
+ mediaUrlGenerators,
+ shortStringHelper,
+ contentTypeBaseServiceProvider,
+ context,
+ packageMigrationsSettings)
+ {
+ }
+
+ protected override void Migrate()
+ {
+ ImportPackage.FromEmbeddedResource().Do();
+ }
+}
+```
+
+Here we also added the ZIP file as an embedded resource to the package project.
+
+.png>)
+
+.png>)
+
+Whichever migration plan you choose to create, you will be able to see that your package has been installed after the migration is completed.
+
+
+
+When using a custom package migration plan, the current state is ignored by default. This causes it to execute all migrations again whenever this isn't the same as the final state of the plan (e.g. if you added a new migration). This is due to the `IgnoreCurrentState` being set to `true` in the `PackageMigrationPlan` base class. You can override this property and set it to `false` again to make it behave like regular migration plans and only run the migrations that have not yet been executed on the current environment.
+
+### Attended/Unattended migration execution
+
+After creating a migration plan, the content and schema will automatically be imported either during unattended package migration or from the Packages section in the backoffice.
+
+By default, all these package migrations are executed unattended during startup but the solution owners can disable this in the configuration. IntelliSense can help, as well as provide further information about the `PackageMigrationsUnattended` setting. Then in the Packages section, there will be an option to run the package migration for each package individually when the `PackageMigrationsUnattended` is set to `false`.
+
+```json
+ "Umbraco": {
+ "CMS": {
+ . . .
+ "Unattended": {
+ "PackageMigrationsUnattended": false
+ }
+ }
+ }
+```
+
+
+
+The configuration of package migrations can be different for each environment and makes it possible to have the migration executed unattended on the development environment, but leave them out or manually execute them on other environments. This is useful when you use a tool like Umbraco Deploy or USync as these will migrate the content.
diff --git a/16/umbraco-cms/extending/packages/example-package-repository.md b/16/umbraco-cms/extending/packages/example-package-repository.md
new file mode 100644
index 00000000000..2d861a71710
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/example-package-repository.md
@@ -0,0 +1,83 @@
+---
+meta.Title: An Example Package Repository
+description: >-
+ Suggestions for organizing and Umbraco package source code repository.
+---
+
+# An Example Package Repository
+
+There are many ways to build and deploy your package to NuGet. You will likely have your own approach for organizing a solution and preferred tools for build and deployment.
+
+It may be useful though to review some practices we share here, of how we build packages at Umbraco.
+
+Some add-ons to the CMS created by Umbraco are closed-source, but we have some we make freely available with open-source repositories. An example is [Umbraco.AuthorizedServices](../../../../marketplace-and-integrations/packages/authorized-services.md), that has a source code repository [here on GitHub](https://github.com/umbraco/Umbraco.AuthorizedServices).
+
+## Solution Organization
+
+The solution consists of three projects.
+
+### Package Project
+
+The [main package project](https://github.com/umbraco/Umbraco.AuthorizedServices/tree/main/src/Umbraco.AuthorizedServices) lives in `src/`. It contains in the project file a dependency on Umbraco CMS:
+
+```xml
+
+```
+
+Here we provide an upper bound on the package. This ensures that developers can only install it into projects that are using versions of Umbraco that we have tested the package with.
+
+When the next major version of Umbraco is released, we'll test and either extend the range or release a new version, as appropriate.
+
+### Tests Project
+
+We have a [project for unit tests](https://github.com/umbraco/Umbraco.AuthorizedServices/tree/main/tests/Umbraco.AuthorizedServices.Tests) in `tests/.Tests`. It contains references to `Umbraco.Cms.Tets` and a project reference to the package:
+
+```xml
+
+```
+
+### Example Website
+
+Finally there's an [example Umbraco website](https://github.com/umbraco/Umbraco.AuthorizedServices/tree/main/examples/Umbraco.AuthorizedServices.TestSite) that we use for manual testing of the package. It also has a project reference to the package project, allowing us to test updates as they are compiled.
+
+### Solution Items
+
+As well as the projects, the following files are added to the solution:
+
+- [.artifactignore](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/.artifactignore) - used by Azure DevOps services to [control which files are uploaded when you publish](https://learn.microsoft.com/en-us/azure/devops/artifacts/reference/artifactignore?view=azure-devops). This helps to reduce pipeline execution time.
+- [.editorconfig](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/.editorconfig) - used to [enforce consistent coding styles](https://editorconfig.org/) for multiple developers working on the same project across editors and IDEs.
+- [.gitignore](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/.gitignore) - controls which files are added to source control.
+- [.globalconfig](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/.globalconfig) - provides [further styling rules for the project files, even if stored outside of the project directory](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/configuration-files#global-analyzerconfig).
+- [Directory.Build.props](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/Directory.Build.props) - used to provide common setting across all projects in the solution.
+- global.json - ensures that the solution is always [built with a consistent version of .NET](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json). We add this when we have a solution that targets a single Umbraco major version.
+- [LICENSE.md](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/LICENSE.md) - indicates the license through which the code is available.
+- [README.md](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/README.md) - a top-level documentation page for the source code repository.
+- [icon.png](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/icon.png) - an icon used for the package on NuGet and the Umbraco Marketplace.
+- [umbraco-marketplace.json](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/umbraco-marketplace.json) - provides [additional details about the package when listed on the Umbraco Marketplace](https://docs.umbraco.com/umbraco-dxp/marketplace/listing-your-package).
+- [version.json](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/version.json) - provides package versioning information for use by [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning). We use this tool for generating version numbers.
+
+## Build and Deployment
+
+We use Azure DevOps pipelines for continuous integration and releasing new versions of the package. The definition of how the project is built is defined in a `.yaml` file that's part of the source code repository.
+
+The file can be found [here](https://github.com/umbraco/Umbraco.AuthorizedServices/blob/main/azure-pipeline%20-%20Umbraco.AuthorizedServices.yml).
+
+Even if using another tool it may be worth reviewing how we have setup our pipeline. It may be you can setup something similar with your own provider.
+
+### Building the Package
+
+The build consists of two stages: building the solution and running unit tests. Only if both succeed is the build as a whole considered successful.
+
+
+
+### Releasing the Package
+
+We release the package manually in Azure DevOps, with a two stage process. Firstly we release to a "pre-releases" feed, and then after manual approval, to NuGet.
+
+
+
+
+
+
+
+
diff --git a/16/umbraco-cms/extending/packages/good-practice-and-defaults.md b/16/umbraco-cms/extending/packages/good-practice-and-defaults.md
new file mode 100644
index 00000000000..d692b3ca0a1
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/good-practice-and-defaults.md
@@ -0,0 +1,208 @@
+---
+description: >-
+ Information on good practices and common defaults for Umbraco package
+ development.
+---
+
+# Good practice and defaults
+
+This document provides guides and notes on package development. It includes good practice guidelines that will help you maintain and support your package through multiple releases and versions of Umbraco. These good practices are not prescriptive, but offer a guide as to what often works well, and not-so-well, when developing packages for Umbraco.
+
+## Backoffice assets (JS/CSS/HTML)
+
+To extend the Umbraco backoffice, a package can provide files such as `umbraco-package.json` and TypeScript/JavaScript files that should be stored within the `App_Plugins` folder. It's recommended to put all files in a subfolder with a unique name, preferably using the package name, like `App_Plugins\MyPackage`.
+
+For more information on how to extend the Umbraco backoffice, have a look at the [customizing the backoffice documentation](../../customizing/overview.md)
+
+Files in the `App_Plugins` folder will be publicly available on the website even though they are not in the `wwwroot` folder. You should not store sensitive information in the `App_Plugins` folder.
+
+Files in the `App_Plugins` folder should be considered immutable. This means that they are not something a user of your package is expected to change on their site.
+
+The default delivery method for files to the `App_Plugins` folder is via a `.targets` file within a package. This means when a website is built, the files in this folder are copied over from the NuGet cache. When this happens, any changes a user might have made to these files will be lost. Equally, if the user performs a `dotnet clean` on a solution, all files in the `App_Plugins` folder will be deleted.
+
+{% hint style="info" %}
+If you have files that you expect users of your package to alter you should not place them in the `App_Plugins` folder.
+{% endhint %}
+
+## Views
+
+Views are used to render content on the front end of a website. If your package provides a way for the user to present the content publicly, you should copy these files to the views folder.
+
+As the files will still be copied during build you should ensure your target file does not overwrite newer or altered files. You should also ensure that it doesn't delete files on clean.
+
+{% hint style="info" %}
+When you have a package that contains many views you might consider building a dotnet template or Razor Class Library (RCL) instead. By doing this, the files will not pollute your user's solutions.
+{% endhint %}
+
+## License files
+
+Umbraco products store their licenses in `/umbraco/Licences`. It is recommended for third-party packages that require license files to also store their license files in this location.
+
+The default `.gitignore` for Umbraco templates will include any files in the `/Licenses` folder while ignoring most of the rest of the Umbraco folder.
+
+{% hint style="info" %}
+The `/umbraco/Licenses` folder does not exist on a fresh installation of Umbraco. You need to create it manually before you save your license file to this folder.
+{% endhint %}
+
+## Operating system considerations
+
+Umbraco a .NET application and can be run on multiple operating systems (Windows, Linux and macOS). When developing packages there are a few things you should be aware of for your package to run on all possible operating systems.
+
+### Case sensitivity
+
+The Linux and macOS file systems are case-sensitive by default. This means that `App_Plugins/myPackage` is a different location from `app_plugins/MyPACKAGE`. When building your package you should ensure that you always refer to folders and paths in a consistent way.
+
+A good way to ensure consistency is to use constants in your code to define file or folder locations.
+
+{% hint style="info" %}
+You can adjust the case sensitivity of a Windows folder by running a command against a newly created/empty folder:
+
+```bash
+fsutil.exe file queryCaseSensitiveInfo
+```
+{% endhint %}
+
+#### Case sensitivity in default files and folders
+
+Some folders within Umbraco will already exist for all installations. If you access these folders, you need to be aware of the case used to ensure you end up in the correct place:
+
+| Folder | Note |
+| ---------------------- | ------------------------------------------------------------------------------------- |
+| /App\_Plugins | Uppercase `A` and `P` |
+| /App\_Plugins/\[Ll]ang | Uppercase `L` |
+| /Views | Uppercase `V` |
+| /umbraco/Licenses | Lowercase `u` and uppercase `L` |
+| /config | Lowercase `c` |
+
+{% hint style="info" %}
+If you create a custom section/tree, Umbraco will build paths based on the name of that section or tree. These folder paths will be case-sensitive.
+
+For example: if you have a custom tree with the `treeAlias` of `MyCustomTree` Umbraco will look for files in `App_Plugins\MyPackage\backoffice\MyCustomTree\`.
+{% endhint %}
+
+### File/folder locations
+
+You should never hardwire a file or folder location into code. Instead, it is recommended to follow either of the options below:
+
+* Access files using the ASP.NET Core file providers from `IHostingEnvironment`.
+* Use the built-in methods to access well-known locations (see below).
+
+#### Temp folder
+
+The location of the Umbraco temp folder can be controlled via configuration and cannot be assumed. Use the `IHostingEnvironment.LocalTempPath` variable to locate the temp folder.
+
+```csharp
+var localTempRoot = Path.GetFullPath(hostingEnvironment.LocalTempPath);
+```
+
+#### Relative paths
+
+If you require the path of a folder relative to the site root, you can use the `IHostingEnvironment` method to map a path:
+
+```csharp
+// Full physical path to the content/project root
+var contentRootPath = hostingEnvironment.MapPathContentRoot("~/");
+// Full physical path to the web root (served publicly)
+var webRootPath = hostEnvironment.MapPathWebRoot("~/");
+// Absolute path to use as URL
+var absolutePath = hostEnvironment.ToAbsolute("~/");
+```
+
+### Folder/file system access
+
+It is not recommended to assume things about the folder structure of a site or use direct I/O commands to access the file system. Access to the disk within an ASP.NET Core site is usually managed with File Providers. You can access the file providers from the `IWebHostEnvironment` class.
+
+Example: If you want to read `robots.txt` from the `wwwroot` folder, use `WebRootFileProvider` in a controller to get to the root of the site and read the file:
+
+```csharp
+public class MyController: UmbracoAuthorizedJsonController
+{
+ public MyController(IWebHostEnvironment webHostEnvironment)
+ {
+ var webRootProvider = webHostEnvironment.WebRootFileProvider;
+
+ var myFileInfo = webRootProvider.GetFileInfo("robots.txt");
+ if (myFileInfo.Exists)
+ {
+ using (var stream = myFileInfo.CreateReadStream())
+ {
+ using(var streamReader = new StreamReader(stream))
+ {
+ var text = streamReader.ReadToEnd();
+ }
+ }
+ }
+ }
+}
+```
+
+{% hint style="info" %}
+This is the preferred method for file I/O. Not all files served up by a site are placed in the `wwwroot` folder when you expect them to be. This is especially true if the site is using Razor Class Library projects to insert static files.
+{% endhint %}
+
+### Path manipulation
+
+Building folder path strings manually can cause problems when swapping between file systems. Windows uses the backslash character ('\\') to separate folders and files while Linux uses the forward slash ('/').
+
+#### Example
+
+On Windows, a file might be located at `d:\website\robots.txt` while on Linux this might look like `/home/website/robots.txt` instead.
+
+You should use the .NET `Path` methods wherever possible when building paths to ensure that the correct path is built:
+
+```csharp
+// WRONG: Don't build paths manually
+var myPath = webrootPath + "\robots.txt";
+
+// CORRECT: Build the path using the correct separator for the current file system
+var myPath = Path.Combine(webrootPath, "robots.txt");
+```
+
+If you need to build a path manually, use `Path.DirectorySeparatorChar` instead to get the correct separator for the file system.
+
+## Settings
+
+Most packages will require some settings to be stored for the users to control in order to change the behavior of the package. Where you store these settings will depend a lot on the nature of the package.
+
+### Property Editors
+
+Property Editors should store their settings as part of their Data Type in Umbraco. This is the standard way property editor behavior is controlled while it is familiar to users and supported by deployment tools.
+
+### Do not save to appsettings.json
+
+You should not alter `appsettings.json` via code.
+
+Settings in ASP.NET Core are merged from a number of different locations at runtime. You cannot guarantee that `appsettings.json` is the location that a setting is read from and your users may not want certain settings in that file. You can read settings from the configuration, but you cannot assume they have come from `appsettings.json`.
+
+### Settings locations
+
+There are many options for where you might save your settings and a lot will depend on the nature of your package.
+
+Below you can find pros and cons for different places where you might save the settings for your package.
+
+#### Save to the database
+
+Settings can be saved to the database. Settings can be stored in the database using the Umbraco `IKeyValueService`, and for more complex settings you can use a custom database table.
+
+* Pros:
+ * Settings will be accessible directly from the database, and not dependent on deployed files on disk.
+* Cons:
+ * Setup is required to create the database tables for the settings to live in.
+ * The settings will only be available to the specific instance of the site, and any settings will not be deployed between a local, development, or staging site.
+
+#### Save to disk
+
+You can choose to save the settings to disk. As an example, the settings can be saved in the `/config` folder at the root of the site.
+
+* Pros:
+ * Settings will be accessible to the site and can be included in deployments between sites.
+* Cons:
+ * You cannot guarantee that the folder or files will be present on a site or that they will be writable.
+ * Using your own config means your users cannot harness the power of the .NET Core configuration system and move settings to environment variables or other key/value stores. This means that sensitive information may end up on disk.
+
+#### Provide the users with appsettings.json snippets
+
+You could choose to provide your users with a snippet they can copy into their `appsettings.json` file. This will ensure that the settings are stored in the correct location.
+
+* Pro: Allows your users to fully control how and where the settings are stored (eg. secure key/value stores).
+* Con: Requires the user to edit files on disk to get the settings in place.
diff --git a/16/umbraco-cms/extending/packages/images/Package-properties-Visual-Studio.png b/16/umbraco-cms/extending/packages/images/Package-properties-Visual-Studio.png
new file mode 100644
index 00000000000..8312d1e8cf7
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/Package-properties-Visual-Studio.png differ
diff --git a/16/umbraco-cms/extending/packages/images/PackagesPage.png b/16/umbraco-cms/extending/packages/images/PackagesPage.png
new file mode 100644
index 00000000000..cff25527501
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/PackagesPage.png differ
diff --git a/16/umbraco-cms/extending/packages/images/app-pligins-contents.png b/16/umbraco-cms/extending/packages/images/app-pligins-contents.png
new file mode 100644
index 00000000000..c0350372ad7
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/app-pligins-contents.png differ
diff --git a/16/umbraco-cms/extending/packages/images/app-plugins-content.png b/16/umbraco-cms/extending/packages/images/app-plugins-content.png
new file mode 100644
index 00000000000..69803716887
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/app-plugins-content.png differ
diff --git a/16/umbraco-cms/extending/packages/images/app-plugins-starterkit.png b/16/umbraco-cms/extending/packages/images/app-plugins-starterkit.png
new file mode 100644
index 00000000000..f69d24e28df
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/app-plugins-starterkit.png differ
diff --git a/16/umbraco-cms/extending/packages/images/backoffice-installed-packages.png b/16/umbraco-cms/extending/packages/images/backoffice-installed-packages.png
new file mode 100644
index 00000000000..74651ae2ada
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/backoffice-installed-packages.png differ
diff --git a/16/umbraco-cms/extending/packages/images/backoffice-package-section.png b/16/umbraco-cms/extending/packages/images/backoffice-package-section.png
new file mode 100644
index 00000000000..dca87d21e51
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/backoffice-package-section.png differ
diff --git a/16/umbraco-cms/extending/packages/images/backoffice-packages-section-package.png b/16/umbraco-cms/extending/packages/images/backoffice-packages-section-package.png
new file mode 100644
index 00000000000..c31ad803478
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/backoffice-packages-section-package.png differ
diff --git a/16/umbraco-cms/extending/packages/images/backoffice-packages-section.png b/16/umbraco-cms/extending/packages/images/backoffice-packages-section.png
new file mode 100644
index 00000000000..f14549ef229
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/backoffice-packages-section.png differ
diff --git a/16/umbraco-cms/extending/packages/images/cloud-flow.png b/16/umbraco-cms/extending/packages/images/cloud-flow.png
new file mode 100644
index 00000000000..1880ca8d129
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/cloud-flow.png differ
diff --git a/16/umbraco-cms/extending/packages/images/create-package.png b/16/umbraco-cms/extending/packages/images/create-package.png
new file mode 100644
index 00000000000..ec89f4f933f
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/create-package.png differ
diff --git a/16/umbraco-cms/extending/packages/images/creating-package-menu-v9.png b/16/umbraco-cms/extending/packages/images/creating-package-menu-v9.png
new file mode 100644
index 00000000000..da73453c0a6
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/creating-package-menu-v9.png differ
diff --git a/16/umbraco-cms/extending/packages/images/creating-package-menu.png b/16/umbraco-cms/extending/packages/images/creating-package-menu.png
new file mode 100644
index 00000000000..2bbadf1c1ba
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/creating-package-menu.png differ
diff --git a/16/umbraco-cms/extending/packages/images/display-retired.png b/16/umbraco-cms/extending/packages/images/display-retired.png
new file mode 100644
index 00000000000..9584bcae232
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/display-retired.png differ
diff --git a/16/umbraco-cms/extending/packages/images/download-package-button.png b/16/umbraco-cms/extending/packages/images/download-package-button.png
new file mode 100644
index 00000000000..ed8d1705221
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/download-package-button.png differ
diff --git a/16/umbraco-cms/extending/packages/images/embeded-resource-props.png b/16/umbraco-cms/extending/packages/images/embeded-resource-props.png
new file mode 100644
index 00000000000..ee8e0b6a49e
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/embeded-resource-props.png differ
diff --git a/16/umbraco-cms/extending/packages/images/embeded-resource.png b/16/umbraco-cms/extending/packages/images/embeded-resource.png
new file mode 100644
index 00000000000..f3ac2e59a1a
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/embeded-resource.png differ
diff --git a/16/umbraco-cms/extending/packages/images/embeded-zip-resource.png b/16/umbraco-cms/extending/packages/images/embeded-zip-resource.png
new file mode 100644
index 00000000000..4b85628f1a0
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/embeded-zip-resource.png differ
diff --git a/16/umbraco-cms/extending/packages/images/empty-package-from-template-v15.png b/16/umbraco-cms/extending/packages/images/empty-package-from-template-v15.png
new file mode 100644
index 00000000000..80e276ce065
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/empty-package-from-template-v15.png differ
diff --git a/16/umbraco-cms/extending/packages/images/empty-package-from-template.png b/16/umbraco-cms/extending/packages/images/empty-package-from-template.png
new file mode 100644
index 00000000000..0a692a5c54e
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/empty-package-from-template.png differ
diff --git a/16/umbraco-cms/extending/packages/images/flag-as-retired.png b/16/umbraco-cms/extending/packages/images/flag-as-retired.png
new file mode 100644
index 00000000000..bf4104ef5d4
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/flag-as-retired.png differ
diff --git a/16/umbraco-cms/extending/packages/images/forum-create.png b/16/umbraco-cms/extending/packages/images/forum-create.png
new file mode 100644
index 00000000000..7df1e4bd4ca
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/forum-create.png differ
diff --git a/16/umbraco-cms/extending/packages/images/forums-display.png b/16/umbraco-cms/extending/packages/images/forums-display.png
new file mode 100644
index 00000000000..accb6880390
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/forums-display.png differ
diff --git a/16/umbraco-cms/extending/packages/images/forums-link.png b/16/umbraco-cms/extending/packages/images/forums-link.png
new file mode 100644
index 00000000000..3c7540216a6
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/forums-link.png differ
diff --git a/16/umbraco-cms/extending/packages/images/fromArtifact.png b/16/umbraco-cms/extending/packages/images/fromArtifact.png
new file mode 100644
index 00000000000..22d50e7f5f1
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/fromArtifact.png differ
diff --git a/16/umbraco-cms/extending/packages/images/generate-package=schema.png b/16/umbraco-cms/extending/packages/images/generate-package=schema.png
new file mode 100644
index 00000000000..5df310e995d
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/generate-package=schema.png differ
diff --git a/16/umbraco-cms/extending/packages/images/hitting-breakpoints.png b/16/umbraco-cms/extending/packages/images/hitting-breakpoints.png
new file mode 100644
index 00000000000..2fbe4666e6e
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/hitting-breakpoints.png differ
diff --git a/16/umbraco-cms/extending/packages/images/installed-package-leftovers-backoffice.png b/16/umbraco-cms/extending/packages/images/installed-package-leftovers-backoffice.png
new file mode 100644
index 00000000000..48ee6810320
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/installed-package-leftovers-backoffice.png differ
diff --git a/16/umbraco-cms/extending/packages/images/installed-package.png b/16/umbraco-cms/extending/packages/images/installed-package.png
new file mode 100644
index 00000000000..715cf1f9bcb
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/installed-package.png differ
diff --git a/16/umbraco-cms/extending/packages/images/nuget-installing-options.png b/16/umbraco-cms/extending/packages/images/nuget-installing-options.png
new file mode 100644
index 00000000000..95d91944f82
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/nuget-installing-options.png differ
diff --git a/16/umbraco-cms/extending/packages/images/nuget-package-in-manager.png b/16/umbraco-cms/extending/packages/images/nuget-package-in-manager.png
new file mode 100644
index 00000000000..d5e1b3b80a5
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/nuget-package-in-manager.png differ
diff --git a/16/umbraco-cms/extending/packages/images/package-cli-command.png b/16/umbraco-cms/extending/packages/images/package-cli-command.png
new file mode 100644
index 00000000000..e763915d62b
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-cli-command.png differ
diff --git a/16/umbraco-cms/extending/packages/images/package-custom-folder.png b/16/umbraco-cms/extending/packages/images/package-custom-folder.png
new file mode 100644
index 00000000000..6d6d28f8af8
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-custom-folder.png differ
diff --git a/16/umbraco-cms/extending/packages/images/package-default-location.png b/16/umbraco-cms/extending/packages/images/package-default-location.png
new file mode 100644
index 00000000000..0e53c020cae
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-default-location.png differ
diff --git a/16/umbraco-cms/extending/packages/images/package-files-list.png b/16/umbraco-cms/extending/packages/images/package-files-list.png
new file mode 100644
index 00000000000..b3d5b4843ed
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-files-list.png differ
diff --git a/16/umbraco-cms/extending/packages/images/package-install-attended.png b/16/umbraco-cms/extending/packages/images/package-install-attended.png
new file mode 100644
index 00000000000..c6f31569b02
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-install-attended.png differ
diff --git a/16/umbraco-cms/extending/packages/images/package-options.gif b/16/umbraco-cms/extending/packages/images/package-options.gif
new file mode 100644
index 00000000000..0bd1a81695f
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-options.gif differ
diff --git a/16/umbraco-cms/extending/packages/images/package-properties.png b/16/umbraco-cms/extending/packages/images/package-properties.png
new file mode 100644
index 00000000000..b7fb1b0d7f5
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/package-properties.png differ
diff --git a/16/umbraco-cms/extending/packages/images/property-editor.png b/16/umbraco-cms/extending/packages/images/property-editor.png
new file mode 100644
index 00000000000..7b049f578ca
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/property-editor.png differ
diff --git a/16/umbraco-cms/extending/packages/images/removing-content.png b/16/umbraco-cms/extending/packages/images/removing-content.png
new file mode 100644
index 00000000000..3fa0db3b6ad
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/removing-content.png differ
diff --git a/16/umbraco-cms/extending/packages/images/removing-datatypes.png b/16/umbraco-cms/extending/packages/images/removing-datatypes.png
new file mode 100644
index 00000000000..7cd36ad62eb
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/removing-datatypes.png differ
diff --git a/16/umbraco-cms/extending/packages/images/removing-document-types.png b/16/umbraco-cms/extending/packages/images/removing-document-types.png
new file mode 100644
index 00000000000..40d0ad2a49d
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/removing-document-types.png differ
diff --git a/16/umbraco-cms/extending/packages/images/removing-media.png b/16/umbraco-cms/extending/packages/images/removing-media.png
new file mode 100644
index 00000000000..160ccfac9f6
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/removing-media.png differ
diff --git a/16/umbraco-cms/extending/packages/images/removing-partials.png b/16/umbraco-cms/extending/packages/images/removing-partials.png
new file mode 100644
index 00000000000..1fc93d8ccaa
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/removing-partials.png differ
diff --git a/16/umbraco-cms/extending/packages/images/removing-templates.png b/16/umbraco-cms/extending/packages/images/removing-templates.png
new file mode 100644
index 00000000000..08beb8e2c15
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/removing-templates.png differ
diff --git a/16/umbraco-cms/extending/packages/images/select-files-for-package.png b/16/umbraco-cms/extending/packages/images/select-files-for-package.png
new file mode 100644
index 00000000000..d059e30fe7d
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/select-files-for-package.png differ
diff --git a/16/umbraco-cms/extending/packages/images/seochecker-after-removal.png b/16/umbraco-cms/extending/packages/images/seochecker-after-removal.png
new file mode 100644
index 00000000000..9eb77e23309
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/seochecker-after-removal.png differ
diff --git a/16/umbraco-cms/extending/packages/images/seochecker-app-plugins.png b/16/umbraco-cms/extending/packages/images/seochecker-app-plugins.png
new file mode 100644
index 00000000000..b2b2ec0b92c
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/seochecker-app-plugins.png differ
diff --git a/16/umbraco-cms/extending/packages/images/seochecker-content-section.png b/16/umbraco-cms/extending/packages/images/seochecker-content-section.png
new file mode 100644
index 00000000000..5c83b0d11e6
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/seochecker-content-section.png differ
diff --git a/16/umbraco-cms/extending/packages/images/specify-version-info.png b/16/umbraco-cms/extending/packages/images/specify-version-info.png
new file mode 100644
index 00000000000..ece295fecdb
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/specify-version-info.png differ
diff --git a/16/umbraco-cms/extending/packages/images/steppingThroughCode.png b/16/umbraco-cms/extending/packages/images/steppingThroughCode.png
new file mode 100644
index 00000000000..2edb08c90e1
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/steppingThroughCode.png differ
diff --git a/16/umbraco-cms/extending/packages/images/team-link.png b/16/umbraco-cms/extending/packages/images/team-link.png
new file mode 100644
index 00000000000..61008aef4e3
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/team-link.png differ
diff --git a/16/umbraco-cms/extending/packages/images/uninstalling-via-nuget-package-manager.png b/16/umbraco-cms/extending/packages/images/uninstalling-via-nuget-package-manager.png
new file mode 100644
index 00000000000..b63cc056930
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/uninstalling-via-nuget-package-manager.png differ
diff --git a/16/umbraco-cms/extending/packages/images/valueconnector.gif b/16/umbraco-cms/extending/packages/images/valueconnector.gif
new file mode 100644
index 00000000000..40948d682f1
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/valueconnector.gif differ
diff --git a/16/umbraco-cms/extending/packages/images/vs-cleaning-solution.png b/16/umbraco-cms/extending/packages/images/vs-cleaning-solution.png
new file mode 100644
index 00000000000..435e2505b06
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/vs-cleaning-solution.png differ
diff --git a/16/umbraco-cms/extending/packages/images/zip-package-contents.png b/16/umbraco-cms/extending/packages/images/zip-package-contents.png
new file mode 100644
index 00000000000..9350caff0ed
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/zip-package-contents.png differ
diff --git a/16/umbraco-cms/extending/packages/images/zip-package-v9.png b/16/umbraco-cms/extending/packages/images/zip-package-v9.png
new file mode 100644
index 00000000000..169bbfb1591
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/zip-package-v9.png differ
diff --git a/16/umbraco-cms/extending/packages/images/zip-package.png b/16/umbraco-cms/extending/packages/images/zip-package.png
new file mode 100644
index 00000000000..0ec18b86ceb
Binary files /dev/null and b/16/umbraco-cms/extending/packages/images/zip-package.png differ
diff --git a/16/umbraco-cms/extending/packages/installing-and-uninstalling-packages.md b/16/umbraco-cms/extending/packages/installing-and-uninstalling-packages.md
new file mode 100644
index 00000000000..e132651cd2e
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/installing-and-uninstalling-packages.md
@@ -0,0 +1,189 @@
+---
+description: >-
+ The process of installing and, in turn, uninstalling packages in your Umbraco
+ CMS website.
+---
+
+# Installing and Uninstalling Packages
+
+This article will cover the process of installing as well as uninstalling packages from your Umbraco CMS website.
+
+## Installing packages
+
+In the Umbraco Backoffice, you will find a **Packages** section that displays the [Umbraco Marketplace](https://marketplace.umbraco.com/). From here you can browse all community-made as well as official Umbraco packages for the Umbraco CMS.
+
+
+
+Navigating to a specific package in the section will present you with an overview of the package, as well as an install snippet for NuGet CLI.
+
+
+
+The packages can be installed by using:
+
+* **NuGet Package Manager** in Visual Studio
+* **Package Manager Console** in Visual Studio
+* .NET CLI (usually accessible from the terminal/command prompt of your system)
+
+For example, to install the StarterKit package for the Umbraco CMS the command would be:
+
+`dotnet add package Umbraco.TheStarterKit`
+
+Navigating to the NuGet Package Manager in Visual Studio is more visual, and gives you an overview of already installed packages.
+
+
+
+The Package Manager has an integrated search function that allows you to find any public NuGet package and install it on the project.
+
+
+
+Once the package has been installed, it will show up under the **Packages** section in the backoffice, under **Installed** tab.
+
+
+
+## Uninstalling packages
+
+Uninstalling packages is not always as straightforward as installing them.
+
+In this section, we will provide two examples of uninstalling a package - the StarterKit package and the SEOChecker package.
+
+### Uninstalling packages like the StarterKit
+
+{% hint style="info" %}
+Keep in mind that this particular guide targets a specific package. There are many packages out there, and each one is different. The exact steps presented here might not work the exact same way for all the packages, though the general approach should still apply.
+{% endhint %}
+
+The Starter Kit provides you with a boilerplate website solution to build upon. The package installs Document Types, Templates, media, content, and everything else needed to set up a small website. There is little custom code/functionality involved which is usually the case for such starter kit or sample-site packages.
+
+To uninstall a package, either run a command or use the NuGet Package Manager in Visual Studio.
+
+`dotnet remove package Umbraco.TheStarterKit`
+
+
+
+It is recommended to clean the solution after removing any package. This can be done by right-clicking the project in Visual Studio and choosing the _Clean_ option, or using the `dotnet clean` command.
+
+
+
+#### Removing package leftovers from the backoffice
+
+With packages like the StarterKit, the process does not end there. While the package is gone, content - and everything else needed for the website - is still available in the backoffice. To fully remove this kind of package, additional steps are needed.
+
+
+
+Remove content provided by the package
+
+There is no universal way to tell what content comes from a package, and what content is custom-made. In the Content section, delete individual nodes accordingly. If the goal is to fully remove the package and clean the site, all the content can be removed (and the recycle bin emptied).
+
+
+
+
+
+
+
+Remove media provided by the package
+
+Similar to content, media also might have to be removed.
+
+
+
+
+
+
+
+Remove Document Types
+
+Document Types can be removed from the **Settings** section. If fully removing the package, all Document Types can be deleted, as there are no default Document Types in a clean-slate Umbraco installation.
+
+
+
+
+
+
+
+Removing Data Types
+
+As opposed to Document Types, there are some Data Types that are available out of the box when Umbraco is installed. It is not recommended to remove them. The safe approach is to delete any item that starts with a Document Type prefix and includes multiple dashes. That is the default naming convention for new configurations of Data Types (Example: "Blog - How many posts should be shown - Slider")
+
+
+
+
+
+
+
+Removing Templates
+
+No Templates are available out of the box in a new installation. If cleaning up after a package, it would be okay to delete all that are present
+
+
+
+
+
+
+
+Removing Partial Views
+
+Out of the box, there are a few views available in the `blocklist` and `grid` folders. Everything else can theoretically be removed.
+
+
+
+
+
+
+
+Cleaning leftover files on disk
+
+Some packages might reference other items. For example, installing the StarterKit also adds `Bergmania.OpenStreetMap` to your project. That component will show up as installed in the backoffice even after uninstalling the NuGet package.
+
+
+
+In many cases, custom dashboards, editors, and scripts are left in the `App_Plugins` folder after a package has been uninstalled via NuGet. These files also have to be deleted manually.
+
+
+
+
+
+### Uninstalling packages like the SEOChecker
+
+{% hint style="info" %}
+Keep in mind that this particular guide targets a specific package. There are many packages out there, and each one is different. The exact steps presented here might not work the exact same way for all the packages, though the general approach should still apply.
+{% endhint %}
+
+More advanced packages that add functionality on top of Umbraco, usually rely on providing custom, compiled code. That being said, many of such packages also implement custom Sections, Dashboards, editors, and views.
+
+In this example, we will be using the SEOChecker package. This package allows developers of the site to add custom properties to Document Types used to track search engine optimization practices.
+
+An example use case of the SEOChecker property on a Document Type, as presented in the Content section:
+
+
+
+To uninstall the SEOChecker from a website, the first step is to remove the package via a `dotnet` command or use the NuGet Package Manager.
+
+The following command can be used for uninstalling the package:
+
+`dotnet remove package SEOChecker`
+
+After that, cleaning the solution is recommended.
+
+
+
+
+
+Cleaning leftover files on disk
+
+While uninstalling the package would remove most of the custom code, the `App_Plugins` folder has to be cleaned manually.
+
+
+
+Removing _seochecker_ folder from `App_Plugins` will clean up the leftover backoffice section and dashboards.
+
+
+
+## Consequences of removing packages
+
+If content on the website relies on having a custom Property Editor or a data source installed, those properties will default to a `label` Data Type. All previously saved content in the property will in turn be converted to a string.
+
+In the case of the SEOChecker, the custom property added from the package would look like this after all the package files have been removed:
+
+
+
+Depending on the packages and the implementation, rendering of content from custom editors, or any frontend functionality dependent on external code, might not work correctly. It is always recommended to inspect the frontend of the site after removing any packages.
diff --git a/16/umbraco-cms/extending/packages/language-files-for-packages.md b/16/umbraco-cms/extending/packages/language-files-for-packages.md
new file mode 100644
index 00000000000..e5c50881d19
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/language-files-for-packages.md
@@ -0,0 +1,36 @@
+---
+description: >-
+ Information on how to use language files to make your Umbraco package UI
+ support multiple languages
+---
+
+# Language file for packages
+
+If you want your package to be available in different languages, you can use the existing localizations from Umbraco or register your own localizations. The localizations are written as a key-value pair pattern.
+
+To register localizations to a language, you must add a new manifest to the Extension API. The manifest can be added through the `umbraco-package.json` file like this:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```
+```
+{% endcode %}
+
+```json
+{
+ ...
+ "name": "MyPackage",
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "MyPackage.Localize.EnUS",
+ "name": "English (United States)",
+ "meta": {
+ "culture": "en-us"
+ },
+ "js": "/App_Plugins/MyPackage/Localization/en-us.js"
+ }
+ ]
+}
+```
+
+Read the [UI Localization documentation](../../customizing/foundation/localization.md) to learn in-depth on how you can use languages in your packages and Umbraco in general.
diff --git a/16/umbraco-cms/extending/packages/listing-on-marketplace.md b/16/umbraco-cms/extending/packages/listing-on-marketplace.md
new file mode 100644
index 00000000000..2cc27f0408c
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/listing-on-marketplace.md
@@ -0,0 +1,11 @@
+---
+description: Information on how to list your package on the Umbraco Marketplace.
+---
+
+# Listing on the Umbraco Marketplace
+
+The [Umbraco Marketplace](https://marketplace.umbraco.com) is a website built and maintained by Umbraco HQ to support searching and reviewing packages.
+
+It lists all commercial and open-source packages that the community has made available on NuGet.
+
+More information, including details of the steps for listing, are available at the dedicated [documentation space for the Marketplace](https://docs.umbraco.com/umbraco-dxp/marketplace/introduction).
diff --git a/16/umbraco-cms/extending/packages/maintaining-packages.md b/16/umbraco-cms/extending/packages/maintaining-packages.md
new file mode 100644
index 00000000000..562e0edf678
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/maintaining-packages.md
@@ -0,0 +1,50 @@
+---
+description: >-
+ Once you've created and published your package, here is what's involved in
+ it's ongoing maintenance
+---
+
+# Maintaining packages
+
+Once you've created and published your package, what's involved in its ongoing maintenance?
+
+## Updating with new Umbraco major versions
+
+Umbraco will regular release update to the CMS as patch or minor versions. These are verified to be backwards compatible. As such there's no expectation that a package may break when a new version of this type comes out.
+
+When a new major version of Umbraco is released, there will be breaking changes. You should test your package on this latest version to confirm it still works. Unless there's been a significant change to the CMS, many packages will continue to work with the new major version without any update. However you may be using a service or API that has undergone a breaking change.
+
+If this happens, the changes will be documented and you should be able to update your code, recompile and test. After that you can release a new major version of your own package.
+
+Even if there are no breaking changes that affect you, it's worth also looking for any code you using that is marked as obsolete. Umbraco will obsolete public methods or constructors that are expected to be removed in a future major version.
+
+### Referencing Umbraco dependencies
+
+When creating a package with Umbraco you will be taking a dependency on at least one Umbraco package. You will do this in the `.csproj` file for your package:
+
+```xml
+
+```
+
+As indicated, this states the package is compatible with Umbraco 10 and any future version. This would allow the developer to install the package into an Umbraco 12 or 13 solution for example.
+
+If you want to maintain tighter control over this, you can specify an upper bound, like this:
+
+```xml
+
+```
+
+This states that the package is compatible with Umbraco 10, 11 and 12, but not 13. Thus it prevents anyone installing your package into an Umbraco solution that you haven't verified compatibility with. Once you have, you can increase the bound or otherwise update the dependent Umbraco version as appropriate.
+
+## Manage feature requests and issues
+
+If you want to encourage feedback, feature requests, and issue reports then you should make available an issue tracker.
+
+This can be [provided as information about your package](https://docs.umbraco.com/umbraco-dxp/marketplace/listing-your-package) and will be linked from your package's page on the Umbraco Marketplace. Specifically you should populate the `IssueTrackerUrl` field.
+
+## Package no longer required?
+
+After some time it could be that your package should no longer be used. Perhaps it is now too old, or it has been superseded by another one that you recommend instead.
+
+You can indicate this by [deprecating your package on NuGet](https://learn.microsoft.com/en-us/nuget/nuget-org/deprecate-packages).
+
diff --git a/16/umbraco-cms/extending/packages/packages-on-umbraco-cloud.md b/16/umbraco-cms/extending/packages/packages-on-umbraco-cloud.md
new file mode 100644
index 00000000000..ec2f5295f35
--- /dev/null
+++ b/16/umbraco-cms/extending/packages/packages-on-umbraco-cloud.md
@@ -0,0 +1,44 @@
+---
+description: Things to consider for package development and usage in Umbraco Cloud
+---
+
+# Packages on Umbraco Cloud
+
+If you want to use or develop packages for Umbraco Cloud there are a few things to consider and be aware of. The two most important things to know about are
+
+* [How you should store data on Cloud](packages-on-umbraco-cloud.md#storing-data)
+* [Using custom property editors with Deploy](packages-on-umbraco-cloud.md#valueconnectors)
+
+## Storing data
+
+When developing a package you will sometimes store data, this can be data in many forms - Umbraco schema / content, package settings, etc.
+
+When you develop a package for Umbraco Cloud there are a few things to be aware of when storing data, mainly whether you want that data to be specific to 1 environment or more.
+
+Let's take a look at the most common ways of storing data in packages - and what to watch out for on Cloud.
+
+### Migrations
+
+A [migration](../database.md) is some code that you run as part of a migration plan. That migration plan has an ID that is stored in the database (in the KeyValue table). This means that when you add new migrations Umbraco will only execute the ones that came after the one with the stored ID. The most important difference between a migration and a package action is when they are initialized. A package action runs on package install and uninstall, whereas a migration will run whenever you want it to run, see below for common examples.
+
+As migration runs are stored in the database of the site it also means that they will run on each environment you trigger them on. The most common way to trigger a migration is to include them in a [composer](../../implementation/composing.md), which will ensure they run on site startup. This means any commands you have in your migration will automatically run when the site starts up. When your package code is pushed to a new environment it will run them from the beginning on that environment as no ID is saved in the database.
+
+This is normally a good thing. However if you generate any Umbraco schema then Umbraco Deploy will automatically create [UDA files](https://docs.umbraco.com/umbraco-cloud/set-up/power-tools/generating-uda-files) based on that schema, and commit them to source control. This means that when you deploy all your files to the next environment the migration will run again, create duplicates and generate duplicate UDA files, which could end up causing a lot of issues.
+
+You could consider creating Umbraco schema only during a package action, and then running things like creating database tables in migrations. Another good workaround could be to not run the migrations in a composer, but rather create a dashboard for the package where the user can choose which migrations to run themselves. The [Articulate package](https://github.com/Shazwazza/Articulate/blob/master/build/packageManifest.xml#L613) has an example of this.
+
+### Creating files
+
+You may sometimes choose to save data in a file. Could be a separate config file for your package or a [config transform file](https://docs.umbraco.com/umbraco-cloud/set-up/config-transforms) to add an app setting to the web.config. If you do this be aware of two things:
+
+1. If these files are generated on a Cloud environment they will not be stored in source control, and will be overwritten on next deployment. They need to be installed locally, committed to source control and then pushed up to the Cloud environments. We have an [existing feature request](../../reference/mapping.md) on allowing package creators to commit their files directly on Cloud, and it is possible to do so currently but not in a supported way, and it may change suddenly.
+2. If you need the content of the files to be different on the different environments you will need to use environment specific [config transforms](https://docs.umbraco.com/umbraco-cloud/set-up/config-transforms).
+
+## Value connectors
+
+A value connector is an extension to Umbraco Deploy that allows you to transform data when you deploy content of any kind between environments. When it comes to packages, one reason you need to consider these if you are supporting deploying content properties that rely on integer IDs. Content and other Umbraco data has two identifiers - an integer and a GUID. The GUID is consistent between environments but the integer ID is not. As such, if transferring content between environments and relying on integer IDs, you'll need to include a value connector to transform the value.
+
+They also manage dependencies for property data. If you save an ID of an image in your property editor, you can make sure the related image media item is transferred too.
+
+You can read more about value connectors and other extensions to Umbraco Deploy [here](https://docs.umbraco.com/umbraco-deploy/getting-started/extending).
+
diff --git a/16/umbraco-cms/extending/section-trees/images/add-custom-section-v8 (1).png b/16/umbraco-cms/extending/section-trees/images/add-custom-section-v8 (1).png
new file mode 100644
index 00000000000..d5465050e54
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/add-custom-section-v8 (1).png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/add-custom-section-v8.png b/16/umbraco-cms/extending/section-trees/images/add-custom-section-v8.png
new file mode 100644
index 00000000000..d5465050e54
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/add-custom-section-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/add-custom-section.png b/16/umbraco-cms/extending/section-trees/images/add-custom-section.png
new file mode 100644
index 00000000000..56ab633a134
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/add-custom-section.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/backoffice-search-v8 (1).png b/16/umbraco-cms/extending/section-trees/images/backoffice-search-v8 (1).png
new file mode 100644
index 00000000000..1ab9820f3bc
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/backoffice-search-v8 (1).png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/backoffice-search-v8.png b/16/umbraco-cms/extending/section-trees/images/backoffice-search-v8.png
new file mode 100644
index 00000000000..1ab9820f3bc
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/backoffice-search-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/backoffice-search.png b/16/umbraco-cms/extending/section-trees/images/backoffice-search.png
new file mode 100644
index 00000000000..31c5f536067
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/backoffice-search.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/custom-section-alias-v8 (1).png b/16/umbraco-cms/extending/section-trees/images/custom-section-alias-v8 (1).png
new file mode 100644
index 00000000000..6a8e9633af9
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/custom-section-alias-v8 (1).png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/custom-section-alias-v8.png b/16/umbraco-cms/extending/section-trees/images/custom-section-alias-v8.png
new file mode 100644
index 00000000000..6a8e9633af9
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/custom-section-alias-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/custom-section-alias.png b/16/umbraco-cms/extending/section-trees/images/custom-section-alias.png
new file mode 100644
index 00000000000..9cac915a1cb
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/custom-section-alias.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/favouritethings-search-v8 (1).png b/16/umbraco-cms/extending/section-trees/images/favouritethings-search-v8 (1).png
new file mode 100644
index 00000000000..c1010a8dda1
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/favouritethings-search-v8 (1).png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/favouritethings-search-v8.png b/16/umbraco-cms/extending/section-trees/images/favouritethings-search-v8.png
new file mode 100644
index 00000000000..c1010a8dda1
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/favouritethings-search-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/images/favouritethings-search.png b/16/umbraco-cms/extending/section-trees/images/favouritethings-search.png
new file mode 100644
index 00000000000..9b297a84ac5
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/images/favouritethings-search.png differ
diff --git a/16/umbraco-cms/extending/section-trees/trees/images/delete-raindrops-on-roses-v8.png b/16/umbraco-cms/extending/section-trees/trees/images/delete-raindrops-on-roses-v8.png
new file mode 100644
index 00000000000..ac562758a4b
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/trees/images/delete-raindrops-on-roses-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/trees/images/favourite-thing-custom-single-node-tree.png b/16/umbraco-cms/extending/section-trees/trees/images/favourite-thing-custom-single-node-tree.png
new file mode 100644
index 00000000000..c40ceb25a75
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/trees/images/favourite-thing-custom-single-node-tree.png differ
diff --git a/16/umbraco-cms/extending/section-trees/trees/images/favourite-thing-custom-tree-v8.png b/16/umbraco-cms/extending/section-trees/trees/images/favourite-thing-custom-tree-v8.png
new file mode 100644
index 00000000000..9dcef2ad50c
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/trees/images/favourite-thing-custom-tree-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/trees/images/favourite-things-custom-tree-v8.png b/16/umbraco-cms/extending/section-trees/trees/images/favourite-things-custom-tree-v8.png
new file mode 100644
index 00000000000..c6e99e95dc7
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/trees/images/favourite-things-custom-tree-v8.png differ
diff --git a/16/umbraco-cms/extending/section-trees/trees/images/favourite-things-custom-tree.png b/16/umbraco-cms/extending/section-trees/trees/images/favourite-things-custom-tree.png
new file mode 100644
index 00000000000..ada029e7947
Binary files /dev/null and b/16/umbraco-cms/extending/section-trees/trees/images/favourite-things-custom-tree.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/README.md b/16/umbraco-cms/fundamentals/backoffice/README.md
new file mode 100644
index 00000000000..cf1224b1a9c
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/README.md
@@ -0,0 +1,147 @@
+---
+description: >-
+ Learn more about the Umbraco backoffice which is the admin side of your
+ Umbraco website
+---
+
+# Backoffice
+
+In this article you can learn more about the common terms and concepts that are used throughout the Umbraco backoffice.
+
+## [Login screen](login.md)
+
+When you go to the backoffice for the first time, you're presented with the login screen.
+
+
+
+[Read more about the login screen](login.md).
+
+## [Section](sections.md)
+
+A section in Umbraco is where you do specific tasks related to that section. For example Content, Settings and Users. You can navigate between the different sections of the backoffice by clicking the corresponding icon in the section menu.
+
+_The **Section menu** is the horizontal menu located on the top of the backoffice._
+
+
+
+[Read more about the section menu](sections.md).
+
+## [Tree](../../customizing/section-trees.md)
+
+A tree is a hierarchical list of items related (and usually restricted) to a specific concept, like for example content or media.
+
+You can expand trees by clicking the side arrow  to the left of the node.
+
+
+
+[Read more about the Tree](../../customizing/section-trees.md)
+
+## Node
+
+A node is an item in a tree. Media section items appear as nodes in the Media tree, while pages and content are displayed in the Content tree, and so on.
+
+
+
+## [Dashboards](../../customizing/extending-overview/extension-types/dashboard.md)
+
+A dashboard is the main view you are presented with when entering a section within the backoffice. It can be used to show valuable information to the users of the system.
+
+
+
+[Read more about Dashboards](../../customizing/extending-overview/extension-types/dashboard.md)
+
+## Editor
+
+An editor is what you use to edit different items within the backoffice. There are editors specific to editing stylesheets, there are editors for editing Partial Views, and so forth.
+
+## [Content](../data/defining-content/)
+
+Content is what you find in the Content section. Each item in the tree is called a **content node**. Each content node in the content tree consists of different fields, and each of them is defined by a Document Type.
+
+
+
+[Read more about Content](../data/defining-content/)
+
+## Document Type
+
+Document Types define the types of content nodes that backoffice users can create in the content tree. Each Document Type contains different properties. Each property has a specific Data Type for example text or number.
+
+
+
+### Properties
+
+Every Document Type has properties. These are the fields that the content editor is allowed to edit for the content node.
+
+
+
+### [Data Type](../data/data-types/)
+
+Each Document Type property has a Data Type that defines the type of input of that property. Data Types reference a Property Editor and are configured in the Umbraco backoffice in the Settings section. A Data Type can be something basic (text string, number, true/false) or more complex (multi-node tree picker, image cropper, etc).
+
+
+
+[Read more about Data Types](../data/data-types/)
+
+### [Property Editors](property-editors/)
+
+A property editor is a view used by Data Types to insert content into Umbraco. An example of a property editor is the _Textarea_. It's possible to have many Textarea Data Types with different settings that all use the Textarea property editor.
+
+
+
+[Read more about Property Editors](property-editors/)
+
+## [Media](../data/creating-media/)
+
+Media items are used to store assets like images and video within the Media section and can be referenced from your content.
+
+
+
+[Read more about Media](../data/creating-media/)
+
+### Media Types
+
+Media Types are similar to Document Types in Umbraco, except they are specifically for media items in the Media section.
+
+Umbraco includes the following default Media Types - **Article**, **Audio**, **File**, **Folder**, **Image**, **Vector Graphics (SVG)**, and **Video**.
+
+
+
+## [Members](../data/members.md)
+
+A member is someone who has access to signup, register, and login into your **public website** and is not to be confused with Users.
+
+
+
+[Read more about Members](../data/members.md)
+
+### Member Types
+
+Similar to a Document Type and a Media Type. You are able to define custom properties to store on a member such as Twitter username or website URL.
+
+
+
+## [Templates](../design/templates/)
+
+A Template is where you define the HTML markup of your website and also where you output the data from your content nodes.
+
+
+
+[Read more about Templates](../design/templates/)
+
+## Packages
+
+A package is the Umbraco term for an add-on or plugin used to extend the core functionalities in Umbraco. The packages can be found on the [Umbraco Marketplace](https://marketplace.umbraco.com/), and the can also be browsed directly in the backoffice of the Umbraco CMS.
+
+
+
+## Users
+
+A user is someone who has access to the **Umbraco backoffice** and is not to be confused with Members. When Umbraco has been installed a user will automatically be generated with the login (email) and password entered during installation. Users can be created, edited, and managed in the User section.
+
+
+
+## [Document Blueprints](document-blueprints.md)
+
+Document Blueprint provide a blueprint for content nodes based on an existing node.
+
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/document-blueprints.md b/16/umbraco-cms/fundamentals/backoffice/document-blueprints.md
new file mode 100644
index 00000000000..66e2b9ee188
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/document-blueprints.md
@@ -0,0 +1,90 @@
+---
+description: >-
+ In this article you can learn about how to create and use Document Blueprints
+ in Umbraco.
+---
+
+# Document Blueprints
+
+{% hint style="info" %}
+Document Blueprints was previously called Content Templates.
+{% endhint %}
+
+## Document Blueprints Overview
+
+Document Blueprints allows a content editor to create a blueprint for new content nodes based on an existing node.
+
+### Create - Method 1
+
+{% hint style="warning" %}
+Before following this method you should have some [content](../data/defining-content/#3.-creating-the-content) created beforehand.
+{% endhint %}
+
+Select a **Content node** from the **Content** menu:
+
+
+
+Click **...** next to the Content node and select the **Create Document Blueprint** option.
+
+
+
+Give your document blueprint a **Name**:
+
+
+
+Click the **Save** button and if the creation was successful, you will see a success notification:
+
+
+
+The new document blueprint will be created in **Document Blueprints** node of the **Settings** tree:
+
+
+
+{% hint style="info" %}
+Refresh your browser, if you do not see the new document blueprint in the **Document Blueprints** folder.
+{% endhint %}
+
+### Create - Method 2
+
+Go to the **Settings** section:
+
+
+
+Click **...** next to the **Document Blueprints** tree and select the **Create Document Blueprint** menu item:
+
+
+
+Select the Document Type you want to create a document blueprint for:
+
+
+
+{% hint style="warning" %}
+You can create document blueprints only from **Document Types** or **Document Types with Templates**
+{% endhint %}
+
+Give your document blueprint a **Name** and click the **Save** button:
+
+
+
+The new document blueprint will be created in **Document Blueprints** folder of the **Settings** tree:
+
+
+
+### Edit
+
+To edit an existing document blueprint, select a document blueprint from the **Document Blueprints** folder of the **Settings** tree. When you have finished editing click the **Save** button:
+
+
+
+### Use
+
+Once you have created a document blueprint, you can use the template to create new content nodes. To use a document blueprint, Click **...** next to the **Content** tree and select **Create**:
+
+
+
+When you click on a Document Type that has a document blueprint, you will see two options:
+
+* Create a new node based on a document blueprint
+* Create a blank one
+
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/01-Content-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/01-Content-Menu.png
new file mode 100644
index 00000000000..fd1aa38c909
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/01-Content-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/02-Actions-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/02-Actions-Menu.png
new file mode 100644
index 00000000000..9a4c63c5b7a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/02-Actions-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/03-Name-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/03-Name-Content-Template.png
new file mode 100644
index 00000000000..30bd53bd31c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/03-Name-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/04-Save-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/04-Save-Content-Template.png
new file mode 100644
index 00000000000..92bda986ff2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/04-Save-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/05-Find-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/05-Find-Content-Template.png
new file mode 100644
index 00000000000..a27e7fccade
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/05-Find-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/06-Edit-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/06-Edit-Content-Template.png
new file mode 100644
index 00000000000..28fc44c2d47
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/06-Edit-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/07-Settings-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/07-Settings-Menu.png
new file mode 100644
index 00000000000..b337fcbdd64
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/07-Settings-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/08-Create-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/08-Create-Content-Template.png
new file mode 100644
index 00000000000..1e02b91ac87
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/08-Create-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/09-Select-Content-Type.png b/16/umbraco-cms/fundamentals/backoffice/images/09-Select-Content-Type.png
new file mode 100644
index 00000000000..1667a1004e1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/09-Select-Content-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/10-Save-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/10-Save-Template.png
new file mode 100644
index 00000000000..3eacba37b32
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/10-Save-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/11-Find-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/11-Find-Template.png
new file mode 100644
index 00000000000..ed641e4ff90
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/11-Find-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/12-Create-From-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/12-Create-From-Template.png
new file mode 100644
index 00000000000..147b376c44c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/12-Create-From-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/13-Select-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/13-Select-Template.png
new file mode 100644
index 00000000000..904351ebe5e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/13-Select-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Add-ons.png b/16/umbraco-cms/fundamentals/backoffice/images/Add-ons.png
new file mode 100644
index 00000000000..82c43f933e1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Add-ons.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Allowing-Variance-on-properties.png b/16/umbraco-cms/fundamentals/backoffice/images/Allowing-Variance-on-properties.png
new file mode 100644
index 00000000000..b9cb76264f6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Allowing-Variance-on-properties.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Assign-Access-Languages.png b/16/umbraco-cms/fundamentals/backoffice/images/Assign-Access-Languages.png
new file mode 100644
index 00000000000..e03a4c893e8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Assign-Access-Languages.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/BlockEditorConfigurationProgramatically.png b/16/umbraco-cms/fundamentals/backoffice/images/BlockEditorConfigurationProgramatically.png
new file mode 100644
index 00000000000..949ae88fff5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/BlockEditorConfigurationProgramatically.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/BlockEditorContentCreated.png b/16/umbraco-cms/fundamentals/backoffice/images/BlockEditorContentCreated.png
new file mode 100644
index 00000000000..4edfd5aba87
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/BlockEditorContentCreated.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Content-Type.png b/16/umbraco-cms/fundamentals/backoffice/images/Content-Type.png
new file mode 100644
index 00000000000..149c0b225f6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Content-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Content.png b/16/umbraco-cms/fundamentals/backoffice/images/Content.png
new file mode 100644
index 00000000000..9ab10d1fe04
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Create-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Create-Content-Template.png
new file mode 100644
index 00000000000..08207f2a985
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Create-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Create-From-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Create-From-Template.png
new file mode 100644
index 00000000000..c250d8ca953
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Create-From-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Developer.png b/16/umbraco-cms/fundamentals/backoffice/images/Developer.png
new file mode 100644
index 00000000000..ce155b66cc5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Developer.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Dropdown-DataType.png b/16/umbraco-cms/fundamentals/backoffice/images/Dropdown-DataType.png
new file mode 100644
index 00000000000..6785734474b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Dropdown-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Edit-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Edit-Content-Template.png
new file mode 100644
index 00000000000..37e7d82f950
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Edit-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/English_get.png b/16/umbraco-cms/fundamentals/backoffice/images/English_get.png
new file mode 100644
index 00000000000..70e3950dff0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/English_get.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Find-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Find-Content-Template.png
new file mode 100644
index 00000000000..8020ec1ba39
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Find-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Find-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Find-Template.png
new file mode 100644
index 00000000000..32ec568f82b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Find-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Forms.png b/16/umbraco-cms/fundamentals/backoffice/images/Forms.png
new file mode 100644
index 00000000000..6dfdf03de1b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Forms.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Help.png b/16/umbraco-cms/fundamentals/backoffice/images/Help.png
new file mode 100644
index 00000000000..bf96869ef08
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Help.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Infinite-editing.gif b/16/umbraco-cms/fundamentals/backoffice/images/Infinite-editing.gif
new file mode 100644
index 00000000000..b24121d92ba
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Infinite-editing.gif differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Media-Type-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/Media-Type-v14.png
new file mode 100644
index 00000000000..bd5e047e924
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Media-Type-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Media-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/Media-v14.png
new file mode 100644
index 00000000000..a65bda6939d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Media-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Media.png b/16/umbraco-cms/fundamentals/backoffice/images/Media.png
new file mode 100644
index 00000000000..77f0746531b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Media.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Member-Types-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/Member-Types-v14.png
new file mode 100644
index 00000000000..0a7147a93d6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Member-Types-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Members-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/Members-v14.png
new file mode 100644
index 00000000000..9ee60709619
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Members-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Members.png b/16/umbraco-cms/fundamentals/backoffice/images/Members.png
new file mode 100644
index 00000000000..d805f89a211
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Members.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Name-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Name-Content-Template.png
new file mode 100644
index 00000000000..d04b58c18e7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Name-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Save-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Save-Content-Template.png
new file mode 100644
index 00000000000..84b849c80e3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Save-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Save-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Save-Template.png
new file mode 100644
index 00000000000..3d3efe9bdc8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Save-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Select-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/Select-Template.png
new file mode 100644
index 00000000000..ffce97142d4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Select-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Settings-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/Settings-Menu.png
new file mode 100644
index 00000000000..fe0112dcef3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Settings-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Settings.png b/16/umbraco-cms/fundamentals/backoffice/images/Settings.png
new file mode 100644
index 00000000000..3c4a206e0a2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Settings.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Users-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/Users-v14.png
new file mode 100644
index 00000000000..7e73da5e53b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Users-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/Users.png b/16/umbraco-cms/fundamentals/backoffice/images/Users.png
new file mode 100644
index 00000000000..d589c44c76f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/Users.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/action-menu.png b/16/umbraco-cms/fundamentals/backoffice/images/action-menu.png
new file mode 100644
index 00000000000..a33cfb09ec6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/action-menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/adding-a-language.png b/16/umbraco-cms/fundamentals/backoffice/images/adding-a-language.png
new file mode 100644
index 00000000000..e5bb43dc9c0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/adding-a-language.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/allow-variance.png b/16/umbraco-cms/fundamentals/backoffice/images/allow-variance.png
new file mode 100644
index 00000000000..5fed09efd7c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/allow-variance.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/allow-variance2.png b/16/umbraco-cms/fundamentals/backoffice/images/allow-variance2.png
new file mode 100644
index 00000000000..65f9a34c499
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/allow-variance2.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/allow-variance_v10.png b/16/umbraco-cms/fundamentals/backoffice/images/allow-variance_v10.png
new file mode 100644
index 00000000000..828f73cdceb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/allow-variance_v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/backoffice-login.png b/16/umbraco-cms/fundamentals/backoffice/images/backoffice-login.png
new file mode 100644
index 00000000000..736a44a2f3e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/backoffice-login.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/content-menu.png b/16/umbraco-cms/fundamentals/backoffice/images/content-menu.png
new file mode 100644
index 00000000000..29e78f3e879
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/content-menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/data-types-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/data-types-v14.png
new file mode 100644
index 00000000000..bc854bff954
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/data-types-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/document-blueprint-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/document-blueprint-v14.png
new file mode 100644
index 00000000000..1e5e38f5fe2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/document-blueprint-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/document-type-properties-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/document-type-properties-v14.png
new file mode 100644
index 00000000000..1a3a99baaca
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/document-type-properties-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/document-types-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/document-types-v14.png
new file mode 100644
index 00000000000..f0f76e63f64
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/document-types-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/expand-node-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/expand-node-v14.png
new file mode 100644
index 00000000000..de3b284929b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/expand-node-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/has-unpublished-version.svg b/16/umbraco-cms/fundamentals/backoffice/images/has-unpublished-version.svg
new file mode 100644
index 00000000000..fd3509507a6
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/images/has-unpublished-version.svg
@@ -0,0 +1 @@
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/highlight-content-node-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/highlight-content-node-v14.png
new file mode 100644
index 00000000000..45db35b3703
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/highlight-content-node-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/highlight-content-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/highlight-content-v14.png
new file mode 100644
index 00000000000..8646513184d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/highlight-content-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/highlight-dashboard-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/highlight-dashboard-v14.png
new file mode 100644
index 00000000000..39adf28fa20
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/highlight-dashboard-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/highlight-sections-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/highlight-sections-v14.png
new file mode 100644
index 00000000000..52eb170b799
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/highlight-sections-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/highlight-tree-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/highlight-tree-v14.png
new file mode 100644
index 00000000000..aa086ceb376
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/highlight-tree-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/invariant-property-locked.png b/16/umbraco-cms/fundamentals/backoffice/images/invariant-property-locked.png
new file mode 100644
index 00000000000..7159ba8b58a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/invariant-property-locked.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/is-container.svg b/16/umbraco-cms/fundamentals/backoffice/images/is-container.svg
new file mode 100644
index 00000000000..b43024c3d0e
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/images/is-container.svg
@@ -0,0 +1 @@
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/languages.png b/16/umbraco-cms/fundamentals/backoffice/images/languages.png
new file mode 100644
index 00000000000..3820e0cae49
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/languages.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/languages_v10.png b/16/umbraco-cms/fundamentals/backoffice/images/languages_v10.png
new file mode 100644
index 00000000000..d8e66c08b24
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/languages_v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/locked-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/locked-v14.png
new file mode 100644
index 00000000000..22f7bee6520
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/locked-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/locked.svg b/16/umbraco-cms/fundamentals/backoffice/images/locked.svg
new file mode 100644
index 00000000000..782eb1006fb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/images/locked.svg
@@ -0,0 +1 @@
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/login-backoffice-login-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/login-backoffice-login-v14.png
new file mode 100644
index 00000000000..dc92982be28
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/login-backoffice-login-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/mntp.png b/16/umbraco-cms/fundamentals/backoffice/images/mntp.png
new file mode 100644
index 00000000000..47be9e4ce2d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/mntp.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type.png b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type.png
new file mode 100644
index 00000000000..82e3a4f40e9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root.png b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root.png
new file mode 100644
index 00000000000..c9cdfa8254e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_origin.png b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_origin.png
new file mode 100644
index 00000000000..401c38157a5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_origin.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_overview.png b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_overview.png
new file mode 100644
index 00000000000..d482460dd58
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_overview.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_steps.png b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_steps.png
new file mode 100644
index 00000000000..e1e0ad3db83
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/mntp_node_type_dynamic_root_steps.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/packages-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/packages-v14.png
new file mode 100644
index 00000000000..e1ab01a2da0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/packages-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/property-editor-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/property-editor-v14.png
new file mode 100644
index 00000000000..6553f609e08
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/property-editor-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/protected.svg b/16/umbraco-cms/fundamentals/backoffice/images/protected.svg
new file mode 100644
index 00000000000..3aab0c725f5
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/images/protected.svg
@@ -0,0 +1 @@
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/sections-highlight-sections.png b/16/umbraco-cms/fundamentals/backoffice/images/sections-highlight-sections.png
new file mode 100644
index 00000000000..246bb98a467
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/sections-highlight-sections.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/sections-highlight-sections2.png b/16/umbraco-cms/fundamentals/backoffice/images/sections-highlight-sections2.png
new file mode 100644
index 00000000000..3244d145125
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/sections-highlight-sections2.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/template-v14.png b/16/umbraco-cms/fundamentals/backoffice/images/template-v14.png
new file mode 100644
index 00000000000..7330f070a60
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/template-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/timeout-screen.jpg b/16/umbraco-cms/fundamentals/backoffice/images/timeout-screen.jpg
new file mode 100644
index 00000000000..c57857c7a3d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/timeout-screen.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_dashboard.jpg b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_dashboard.jpg
new file mode 100644
index 00000000000..fdac204aafe
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_dashboard.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_login.jpg b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_login.jpg
new file mode 100644
index 00000000000..6627a757b7c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_login.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_sections.jpg b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_sections.jpg
new file mode 100644
index 00000000000..b1dc1cd708e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_sections.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_tree.jpg b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_tree.jpg
new file mode 100644
index 00000000000..6de9e5a00d6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/umbraco7-6_tree.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/update-dropdown-options.gif b/16/umbraco-cms/fundamentals/backoffice/images/update-dropdown-options.gif
new file mode 100644
index 00000000000..475d8384b68
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/update-dropdown-options.gif differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-01-Content-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-01-Content-Menu.png
new file mode 100644
index 00000000000..dd375cca662
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-01-Content-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-02-Actions-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-02-Actions-Menu.png
new file mode 100644
index 00000000000..4f038a5eb3f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-02-Actions-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-03-Name-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-03-Name-Content-Template.png
new file mode 100644
index 00000000000..6a41f9aa5d6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-03-Name-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-04-Save-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-04-Save-Content-Template.png
new file mode 100644
index 00000000000..f7a15cb548e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-04-Save-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-05-Find-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-05-Find-Content-Template.png
new file mode 100644
index 00000000000..244f5d796b7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-05-Find-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-06-Edit-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-06-Edit-Content-Template.png
new file mode 100644
index 00000000000..5cdb17c7422
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-06-Edit-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-07-Settings-Menu.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-07-Settings-Menu.png
new file mode 100644
index 00000000000..e1f6910d596
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-07-Settings-Menu.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-08-Create-Content-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-08-Create-Content-Template.png
new file mode 100644
index 00000000000..2c610e04b97
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-08-Create-Content-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-09-Select-Content-Type.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-09-Select-Content-Type.png
new file mode 100644
index 00000000000..ca0480f2704
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-09-Select-Content-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-10-Save-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-10-Save-Template.png
new file mode 100644
index 00000000000..1d323d33295
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-10-Save-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-11-Find-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-11-Find-Template.png
new file mode 100644
index 00000000000..a7cde6aabef
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-11-Find-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-12-Create-From-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-12-Create-From-Template.png
new file mode 100644
index 00000000000..3b8be3c5dca
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-12-Create-From-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/v8-13-Select-Template.png b/16/umbraco-cms/fundamentals/backoffice/images/v8-13-Select-Template.png
new file mode 100644
index 00000000000..251ae8eded3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/v8-13-Select-Template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/varying-content.png b/16/umbraco-cms/fundamentals/backoffice/images/varying-content.png
new file mode 100644
index 00000000000..41247e7065e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/varying-content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/varying-content_v10.png b/16/umbraco-cms/fundamentals/backoffice/images/varying-content_v10.png
new file mode 100644
index 00000000000..79efa211c19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/varying-content_v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/varying-properties.png b/16/umbraco-cms/fundamentals/backoffice/images/varying-properties.png
new file mode 100644
index 00000000000..8c01350fe7c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/varying-properties.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/images/varying-properties_v10.png b/16/umbraco-cms/fundamentals/backoffice/images/varying-properties_v10.png
new file mode 100644
index 00000000000..fd949f8dad9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/images/varying-properties_v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/login.md b/16/umbraco-cms/fundamentals/backoffice/login.md
new file mode 100644
index 00000000000..287dd04a98a
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/login.md
@@ -0,0 +1,280 @@
+---
+description: >-
+ In this article you can learn the various ways of customizing the Umbraco
+ backoffice login screen and form.
+---
+
+# Login
+
+To access the backoffice, you will need to login. You can do this by adding `/umbraco` at the end of your website URL, for example `http://mywebsite.com/umbraco`.
+
+You will be presented with a login form similar to this:
+
+
+
+The **login** screen contains a short greeting, a **login form** and an optional **Forgotten password** link.
+
+Below, you will find instructions on how to customize the login screen.
+
+## Greeting
+
+The login screen features a greeting text: The "Welcome" headline. This can be personalized by overriding the existing language translation keys.
+
+To do this follow the steps below:
+
+1. Register a 'localization' manifest for the default language of your Umbraco site, (usually en-US) to override the greetings.
+
+{% code title="App_Plugins/Login/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "alias": "login.extensions",
+ "name": "Login extensions",
+ "version": "1.0.0",
+ "allowPublicAccess": true,
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "Login.Localize.EnUS",
+ "name": "English",
+ "js": "/App_Plugins/Login/en-us.js",
+ "meta": {
+ "culture": "en-US"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+2. Add an `en-us.js` file containing the following:
+
+{% code title="App_Plugins/Login/en-us.js" %}
+```javascript
+export default {
+ auth: {
+ instruction: "Log in again to continue",
+ greeting0: "Is is Sunday",
+ greeting1: "Is is Monday",
+ greeting2: "Is is Tuesday",
+ greeting3: "Is is Wednesday",
+ greeting4: "Is is Thursday",
+ greeting5: "Is is Friday",
+ greeting6: "Is is Saturday",
+ }
+}
+```
+{% endcode %}
+
+This will override the default greetings with the ones you provide. The login screen will now display "It is Sunday" instead of "Welcome" for example.
+
+{% hint style="info" %}
+The login screen has its own set of localization files independent of the rest of the Backoffice. You can read more about Backoffice localization in the [UI Localization](../../customizing/foundation/localization.md) article.
+{% endhint %}
+
+You can customize other text on the login screen as well. First, grab the default values and keys from the [en.ts](https://github.com/umbraco/Umbraco-CMS/blob/contrib/src/Umbraco.Web.UI.Login/src/localization/lang/en.ts) in the Umbraco CMS GitHub repository. Thereafter copy the ones you want to translate into `~/App_Plugins/Login/umbraco-package.json` file.
+
+## Password reset
+
+The **Forgotten password?** link allows your backoffice users to reset their password. To use this feature, you will need to add the following key to the `Umbraco.Cms.Security` section in the `appsettings.json` file:
+
+```json
+"Umbraco": {
+ "CMS": {
+ "Security": {
+ "AllowPasswordReset": true
+ }
+ }
+}
+```
+
+Set it to `true` to enable the password reset feature, and `false` to disable the feature.
+
+You will also need to configure a Simple Mail Transfer Protocol (SMTP) server in your `appsettings.json` file. When you get a successful result on the SMTP configuration when running a health check in the backoffice, you are good to go!
+
+An example:
+
+```json
+"Umbraco": {
+ "CMS": {
+ "Global": {
+ "Id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ "Smtp": {
+ "From": "noreply@test.com",
+ "Host": "127.0.0.1",
+ "Username": "username",
+ "Password": "password"
+ }
+ }
+ }
+}
+```
+
+## Custom background image and logo
+
+It is possible to customize the background image and the logo for the backoffice login screen by adding the `"Content"` section in the `appsettings.json` file:
+
+```json
+"Umbraco": {
+ "CMS": {
+ "Content": {
+ "LoginBackgroundImage": "../myImagesFolder/myLogin.jpg",
+ "LoginLogoImage": "../myImagesFolder/myLogo.svg",
+ "LoginLogoImageAlternative": "../myImagesFolder/myLogo.svg"
+ }
+ }
+}
+```
+
+The `LoginBackgroundImage`, `LoginLogoImage`, and `LoginLogoImageAlternative` are referenced from the `/wwwroot/umbraco/` folder.
+
+The `LoginLogoImage` is displayed on top of the `LoginBackgroundImage` and the `LoginLogoImageAlternative` is displayed when the `LoginLogoImage` is not available, for example on small resolutions.
+
+## Custom CSS
+
+You can also customize the login screen by adding a custom CSS file. To do this, you will need to add a new file inside the `~/App_Plugins` folder, for example `~/App_Plugins/Login/my-custom-login-screen.css`.
+
+You can then add your custom CSS to the file:
+
+```css
+:root {
+ --umb-login-curves-color: rgba(0, 0, 0, 0.1);
+}
+```
+
+This will change the color of the SVG graphics (curves) shown on the login screen. You can also hide the curves by adding the following CSS:
+
+```css
+:root {
+ --umb-login-curves-display: none;
+}
+```
+
+### Load the custom CSS file
+
+To tell Umbraco about your custom CSS file, you will need to add a `umbraco-package.json` file. The `umbraco-package.json` file should look like this:
+
+```json
+{
+ "alias": "login.extensions",
+ "name": "Login extensions",
+ "version": "1.0.0",
+ "allowPublicAccess": true,
+ "extensions": [
+ {
+ "type": "appEntryPoint",
+ "alias": "MyCustomLoginScreen",
+ "name": "My Custom Login Screen",
+ "js": "/App_Plugins/Login/my-custom-login-screen.js"
+ }
+ ]
+}
+```
+
+Next add a JavaScript file, for example `~/App_Plugins/Login/my-custom-login-screen.js`, and add the following code to load the custom CSS file:
+
+```javascript
+const link = document.createElement('link');
+link.rel = 'stylesheet';
+link.href = '/App_Plugins/Login/my-custom-login-screen.css';
+document.head.appendChild(link);
+```
+
+This will load the custom CSS file into Umbraco.
+
+{% hint style="warning" %}
+Be aware that the custom CSS file will be loaded on all Umbraco screens, not only the login screen.
+{% endhint %}
+
+### Custom CSS properties reference
+
+The following CSS properties are available for customization:
+
+| CSS Property | Description | Default Value |
+| ---------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------ |
+| `--umb-login-background` | The background of the layout | `#f4f4f4` |
+| `--umb-login-primary-color` | The color of the headline | `#283a97` |
+| `--umb-login-text-color` | The color of the text | `#000` |
+| `--umb-login-header-font-size` | The font-size of the headline | `3rem` |
+| `--umb-login-header-font-size-large` | The font-size of the headline on large screens | `4rem` |
+| `--umb-login-header-secondary-font-size` | The font-size of the secondary headline | `2.4rem` |
+| `--umb-login-image` | The background of the image wrapper | The value of the [LoginBackgroundImage](login.md#custom-background-image-and-logo) setting |
+| `--umb-login-image-display` | The display of the image wrapper | `flex` |
+| `--umb-login-image-border-radius` | The border-radius of the image wrapper | `38px` |
+| `--umb-login-content-background` | The background of the content wrapper | `none` |
+| `--umb-login-content-display` | The display of the content wrapper | `flex` |
+| `--umb-login-content-width` | The width of the content wrapper | `100%` |
+| `--umb-login-content-height` | The height of the content wrapper | `100%` |
+| `--umb-login-content-border-radius` | The border-radius of the content wrapper | `0` |
+| `--umb-login-align-items` | The align-items of the main wrapper | `unset` |
+| `--umb-login-button-border-radius` | The border-radius of the buttons | `45px` |
+| `--umb-login-curves-color` | The color of the curves | `#f5c1bc` |
+| `--umb-login-curves-display` | The display of the curves | `inline` |
+
+The CSS custom properties may change in future versions of Umbraco. You can always find the latest values in the [login layout element](https://github.com/umbraco/Umbraco-CMS/blob/v14/dev/src/Umbraco.Web.UI.Login/src/components/layouts/auth-layout.element.ts) in the Umbraco CMS GitHub repository.
+
+## The Time Out Screen
+
+
+
+The time out screen is displayed when the user has been inactive for a certain amount of time. The screen resembles the login screen in many ways and the two are sometimes confused. The most notable difference is that the time out screen does not have a login form. It only has a message and a button to log in again with Umbraco.
+
+If you have added more than one login provider, the users will also see this screen first. This is because they need to choose which provider to use first. In that case, the screen is also referred to as the **Choose provider screen**.
+
+You can customize the time out screen in the same way as the login screen. The time out screen uses the same localization files as the rest of the Backoffice and **not** those of the login screen. The notable difference is that the time out screen is scoped to the `login` section. The login screen is scoped to the `auth` section of the localization files.
+
+### Greeting
+
+To update the greeting message on this screen, you will have to change the section to `login`:
+
+{% code title="App_Plugins/Login/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "alias": "login.extensions",
+ "name": "Login extensions",
+ "version": "1.0.0",
+ "allowPublicAccess": true,
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "Login.Localize.EnUS",
+ "name": "English",
+ "js": "/App_Plugins/Login/en-us.js",
+ "meta": {
+ "culture": "en-US"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+The `en-us.js` file should contain the following:
+
+{% code title="App_Plugins/Login/en-us.js" %}
+```javascript
+export default {
+ auth: {
+ instruction: "Log in again to continue",
+ greeting0: "Is is Sunday",
+ greeting1: "Is is Monday",
+ greeting2: "Is is Tuesday",
+ greeting3: "Is is Wednesday",
+ greeting4: "Is is Thursday",
+ greeting5: "Is is Friday",
+ greeting6: "Is is Saturday",
+ }
+}
+```
+{% endcode %}
+
+The `instruction` key is shown when the user has timed out, and the `greeting0..6` keys are shown when the user has to choose a login provider.
+
+### Image
+
+You can update the image on the time out screen through a custom CSS variable. The default value is `--umb-login-image` and it is set to the same value as the login screen. You can override this value in your custom CSS file:
+
+```css
+:root {
+ --umb-login-image: url(../myImagesFolder/myTimeout.jpg);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/logviewer.md b/16/umbraco-cms/fundamentals/backoffice/logviewer.md
new file mode 100644
index 00000000000..c4ecca6f28c
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/logviewer.md
@@ -0,0 +1,163 @@
+---
+description: Information on using the Umbraco log viewer
+---
+
+# Log Viewer
+
+Umbraco ships with a built-in Log Viewer feature. This allows you to filter, view log entries, perform complex search queries, and analyze logs for debugging. You can find the Log viewer in the **Settings** section of the Umbraco backoffice.
+
+{% embed url="https://youtu.be/PDqIRVygAQ4?t=102" %}
+Learn how to use the Log Viewer to read and understand logs for your Umbraco CMS website.
+{% endembed %}
+
+## Benefits
+
+Ever needed to find all log entries containing the same request ID? Or locate all logs where a property called `Duration` exceeds 1000ms?
+
+With structured logging and a query language, you can efficiently search and identify log items for specific scenarios. This helps in debugging and finding patterns in your logs, making it easier to resolve issues.
+
+## Example Queries
+
+Here are some example queries to help you get started. For more details on the syntax, see the https://github.com/serilog/serilog-filters-expressions project.
+
+**Find all logs that are from the namespace 'Umbraco.Core'**
+`StartsWith(SourceContext, 'Umbraco.Core')`
+
+**Find all logs that have the property 'Duration' and the duration is greater than 1000ms**
+`Has(Duration) and Duration > 1000`
+
+**Find all logs where the message has localhost in it with SQL like**
+`@Message like '%localhost%'`
+
+## Saved Searches
+
+If you frequently use a custom query, you can save it for quick access. Type your query in the search box and click the heart icon to save it with a friendly name. Saved queries are stored in the `umbracoLogViewerQuery` table in the database.
+
+## Implementing Your Own Log Viewer
+
+Umbraco allows you to implement a customn `ILogViewer` to fetch logs from alternative sources, such as **Azure Table Storage**.
+
+### Creating a Custom Log Viewer
+
+To fetch logs from Azure Table Storage, implement the `SerilogLogViewerSourceBase` class from `Umbraco.Cms.Core.Logging.Viewer`.
+
+{% hint style="info" %}
+This implementation requires the `Azure.Data.Tables` NuGet package.
+{% endhint %}
+
+```csharp
+using Azure;
+using Azure.Data.Tables;
+using Serilog.Events;
+using Serilog.Formatting.Compact.Reader;
+using Serilog.Sinks.AzureTableStorage;
+using Umbraco.Cms.Core.Logging.Viewer;
+using ITableEntity = Azure.Data.Tables.ITableEntity;
+
+namespace My.Website;
+
+public class AzureTableLogViewer : SerilogLogViewerSourceBase
+{
+ public AzureTableLogViewer(ILogViewerConfig logViewerConfig, Serilog.ILogger serilogLog, ILogLevelLoader logLevelLoader)
+ : base(logViewerConfig, logLevelLoader, serilogLog)
+ {
+ }
+
+ public override bool CanHandleLargeLogs => true;
+
+ // This method will not be called - as we have indicated that this 'CanHandleLargeLogs'
+ public override bool CheckCanOpenLogs(LogTimePeriod logTimePeriod) => throw new NotImplementedException();
+
+ protected override IReadOnlyList GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take)
+ {
+ //Replace ACCOUNT_NAME and KEY with your actual Azure Storage Account details. The "Logs" parameter refers to the table name where logs will be stored and retrieved from.
+ var client =
+ new TableClient(
+ "DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=KEY;EndpointSuffix=core.windows.net",
+ "Logs");
+
+ // Table storage does not support skip, only take, so the best we can do is to not fetch more entities than we need in total.
+ // See: https://learn.microsoft.com/en-us/rest/api/storageservices/writing-linq-queries-against-the-table-service#returning-the-top-n-entities for more info.
+ var requiredEntities = skip + take;
+ IEnumerable results = client.Query().Take(requiredEntities);
+
+ return results
+ .Skip(skip)
+ .Take(take)
+ .Select(x => LogEventReader.ReadFromString(x.Data))
+ // Filter by timestamp to avoid retrieving all logs from the table, preventing memory and performance issues
+ .Where(evt => evt.Timestamp >= logTimePeriod.StartTime.Date &&
+ evt.Timestamp <= logTimePeriod.EndTime.Date.AddDays(1).AddSeconds(-1))
+ .Where(filter.TakeLogEvent)
+ .ToList();
+ }
+
+ public override IReadOnlyList? GetSavedSearches()
+ {
+ //This method is optional. If you store saved searches in Azure Table Storage, implement fetching logic here.
+ return base.GetSavedSearches();
+ }
+
+ public override IReadOnlyList? AddSavedSearch(string? name, string? query)
+ {
+ //This method is optional. If you store saved searches in Azure Table Storage, implement adding logic here.
+ return base.AddSavedSearch(name, query);
+ }
+
+ public override IReadOnlyList? DeleteSavedSearch(string? name, string? query)
+ {
+ //This method is optional. If you store saved searches in Azure Table Storage, implement deleting logic here.
+ return base.DeleteSavedSearch(name, query);
+ }
+}
+
+public class AzureTableLogEntity : LogEventEntity, ITableEntity
+{
+ public DateTimeOffset? Timestamp { get; set; }
+
+ public ETag ETag { get; set; }
+}
+```
+
+Azure Table Storage requires entities to implement the `ITableEntity` interface. Since Umbraco’s default log entity does not implement this, a custom entity (`AzureTableLogEntity`) must be created to ensure logs are correctly fetched and stored.
+
+### Register implementation
+
+Umbraco needs to be made aware that there is a new implementation of an `ILogViewer` to register. We also need to replace the default JSON LogViewer that we ship in the core of Umbraco.
+
+```csharp
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Infrastructure.DependencyInjection;
+
+namespace My.Website;
+
+public class LogViewerSavedSearches : IComposer
+{
+ public void Compose(IUmbracoBuilder builder) => builder.SetLogViewer();
+}
+```
+
+### Configuring Logging to Azure Table Storage
+
+With the above two classes, the setup is in place to view logs from an Azure Table. However, logs are not yet persisted into the Azure Table Storage account. To enable persistence, configure the Serilog logging pipeline to store logs in Azure Table Storage.
+
+* Install `Serilog.Sinks.AzureTableStorage` from NuGet.
+* Add a new sink to `appsettings.json` with credentials to persist logs to Azure.
+
+The following sink needs to be added to the [`Serilog:WriteTo`](https://github.com/serilog/serilog-sinks-azuretablestorage#json-configuration) array.
+
+```json
+{
+"Name": "AzureTableStorage",
+"Args": {
+ "storageTableName": "LogEventEntity",
+ "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
+ "connectionString": "DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=KEY;EndpointSuffix=core.windows.net"}
+}
+```
+
+For more in-depth information about logging and how to configure it, see the [Logging](../code/debugging/logging.md) article.
+
+### Compact Log Viewer - Desktop App
+
+[Compact Log Viewer](https://www.microsoft.com/store/apps/9N8RV8LKTXRJ?cid=storebadge\&ocid=badge). A desktop tool is available for viewing and querying JSON log files in the same way as the built-in Log Viewer in Umbraco.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/README.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/README.md
new file mode 100644
index 00000000000..9b7e69cf5ca
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/README.md
@@ -0,0 +1,36 @@
+---
+description: >-
+ Learn more about the default property editors that ships with an Umbraco
+ installation.
+---
+
+# Property Editors
+
+A Property Editor is the editor that a Data Type references. A Data Type is defined by a user in the Umbraco backoffice and references a Property Editor. In Umbraco a Property Editor is defined in a JSON manifest file and associated JavaScript files.
+
+{% hint style="info" %}
+**Are you looking for the Grid Layout or Nested Content?**
+
+The following Property Editors have been removed with the release of Umbraco 14:
+
+* Grid Layout
+* Nested content
+
+We recommend using the [Block Editor](built-in-umbraco-property-editors/block-editor/) or the [Rich Text Editor Blocks](built-in-umbraco-property-editors/rich-text-editor/blocks.md) instead.
+{% endhint %}
+
+When creating a Data Type, specify the property editor for the Data Type to use by selecting from the "Property editor" list (as shown below).
+
+
+
+## [Built-in Property Editors in Umbraco](built-in-umbraco-property-editors/)
+
+Umbraco comes pre-installed with many useful property editors.
+
+## More information
+
+* [Customizing Data Types](../../data/data-types/)
+
+## Tutorials
+
+* [How to create a custom Property Editor](../../../tutorials/creating-a-property-editor/)
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AddContent.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AddContent.png
new file mode 100644
index 00000000000..b77fcfc1257
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AddContent.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AddContentInline.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AddContentInline.png
new file mode 100644
index 00000000000..644ec9d1b1a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AddContentInline.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_Areas.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_Areas.png
new file mode 100644
index 00000000000..ae25f727ec1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_Areas.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AreasConfiguration.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AreasConfiguration.png
new file mode 100644
index 00000000000..27a9a510790
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_AreasConfiguration.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_BlockPicker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_BlockPicker.png
new file mode 100644
index 00000000000..b519f0b755b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_BlockPicker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_BlockPicker_exsetup.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_BlockPicker_exsetup.png
new file mode 100644
index 00000000000..826d46925e4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_BlockPicker_exsetup.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_Configuration.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_Configuration.png
new file mode 100644
index 00000000000..fe5fec9d0df
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_Configuration.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_DataType_Blocks.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_DataType_Blocks.png
new file mode 100644
index 00000000000..5509be958d5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_DataType_Blocks.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_DeleteContent.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_DeleteContent.png
new file mode 100644
index 00000000000..aee9a56f88a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockGridEditor_DeleteContent.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_AddContent.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_AddContent.png
new file mode 100644
index 00000000000..aeb71eb6354
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_AddContent.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_AddContentInline.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_AddContentInline.jpg
new file mode 100644
index 00000000000..8b20c59740b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_AddContentInline.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_BlockPicker.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_BlockPicker.jpg
new file mode 100644
index 00000000000..48ca8012ceb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_BlockPicker.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_BlockPicker_simplesetup.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_BlockPicker_simplesetup.jpg
new file mode 100644
index 00000000000..265f40b2b50
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_BlockPicker_simplesetup.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_DataType.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_DataType.jpg
new file mode 100644
index 00000000000..d55344cfab6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_DataType.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_DataType_Blocks.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_DataType_Blocks.png
new file mode 100644
index 00000000000..55f022f185c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_DataType_Blocks.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_EditingOverlay.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_EditingOverlay.jpg
new file mode 100644
index 00000000000..06e3952f0d6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_EditingOverlay.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_InlineEditing.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_InlineEditing.jpg
new file mode 100644
index 00000000000..0bc57cb6dcb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/BlockListEditor_InlineEditing.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Install-Sample-Configuration.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Install-Sample-Configuration.png
new file mode 100644
index 00000000000..3c461f50f2a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Install-Sample-Configuration.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Resizing-Blocks.gif b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Resizing-Blocks.gif
new file mode 100644
index 00000000000..3cd187ba55c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Resizing-Blocks.gif differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Sorting_BlockGrid_Blocks.gif b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Sorting_BlockGrid_Blocks.gif
new file mode 100644
index 00000000000..b5a762aad5d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/Sorting_BlockGrid_Blocks.gif differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/resizing-block-block-grid.gif b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/resizing-block-block-grid.gif
new file mode 100644
index 00000000000..f56d714d12b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/block-editor/images/resizing-block-block-grid.gif differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType-v10.png
new file mode 100644
index 00000000000..51a442213de
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType-v8.png
new file mode 100644
index 00000000000..0ea95d1f653
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType.png
new file mode 100644
index 00000000000..da2e4783a21
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Content.png
new file mode 100644
index 00000000000..748994a5133
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-DataType.png
new file mode 100644
index 00000000000..4c3e82f6475
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Keys-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Keys-Content.png
new file mode 100644
index 00000000000..9f32f5a1403
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Keys-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Keys-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Keys-DataType.png
new file mode 100644
index 00000000000..ffcdc6226ed
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/Dropdown-List-Keys-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/DropdownMultiple-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/DropdownMultiple-Content.png
new file mode 100644
index 00000000000..9d2fd30a993
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/DropdownMultiple-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/DropdownSingle-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/DropdownSingle-Content.png
new file mode 100644
index 00000000000..be48cc06e30
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/dropdown/images/DropdownSingle-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-config.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-config.png
new file mode 100644
index 00000000000..b1a7bebeeee
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-config.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-configuration.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-configuration.jpg
new file mode 100644
index 00000000000..1a1669ea764
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-configuration.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-NO-SIDEBAR-rows.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-NO-SIDEBAR-rows.jpg
new file mode 100644
index 00000000000..6f2ee70af01
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-NO-SIDEBAR-rows.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-rows.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-rows.jpg
new file mode 100644
index 00000000000..82c269292fa
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-rows.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-scenarios-1.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-scenarios-1.jpg
new file mode 100644
index 00000000000..68e9eaa12b6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-scenarios-1.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-scenarios.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-scenarios.jpg
new file mode 100644
index 00000000000..89c46c8e2a6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout-scenarios.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout.jpg
new file mode 100644
index 00000000000..c568c3bc883
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/Grid-layout.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/cells.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/cells.png
new file mode 100644
index 00000000000..7a08e22f31e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/cells.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/editor.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/editor.png
new file mode 100644
index 00000000000..f2cabc6bd80
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/editor.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-resizing.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-resizing.png
new file mode 100644
index 00000000000..43795bb6e72
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-resizing.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-settings-and-style.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-settings-and-style.png
new file mode 100644
index 00000000000..be277afce13
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-settings-and-style.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-wireframe.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-wireframe.jpg
new file mode 100644
index 00000000000..743294e00e0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/grid-wireframe.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/layout.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/layout.png
new file mode 100644
index 00000000000..1d56b4e1077
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/layout.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/layouts.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/layouts.png
new file mode 100644
index 00000000000..92d35914331
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/layouts.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/rows.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/rows.png
new file mode 100644
index 00000000000..324ada87d38
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/rows.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/settings.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/settings.png
new file mode 100644
index 00000000000..5cbec50a771
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/grid-layout/Images/settings.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Bulk-action.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Bulk-action.png
new file mode 100644
index 00000000000..317fcc0be6f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Bulk-action.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Content.png
new file mode 100644
index 00000000000..816cd894624
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Data-Type-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Data-Type-v10.png
new file mode 100644
index 00000000000..3f1b3f5769d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Data-Type-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Data-Type.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Data-Type.png
new file mode 100644
index 00000000000..b5c12f01a4f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Checkbox-Data-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-Content-v8.png
new file mode 100644
index 00000000000..1bf70361a19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-Content.png
new file mode 100644
index 00000000000..afa79301ebb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType-v10.png
new file mode 100644
index 00000000000..192d2d14d6a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType-v8.png
new file mode 100644
index 00000000000..dce3cfb3707
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType.png
new file mode 100644
index 00000000000..cdb0b000552
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Color-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content-v10.png
new file mode 100644
index 00000000000..7a5462d5c5f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content-v8.png
new file mode 100644
index 00000000000..e6501f8493b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content.png
new file mode 100644
index 00000000000..c8f7c80d8db
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType-8_1.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType-8_1.png
new file mode 100644
index 00000000000..19ee214659f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType-8_1.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType-v8.png
new file mode 100644
index 00000000000..b3fc75721fc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType.png
new file mode 100644
index 00000000000..9961538e7b7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-Content.png
new file mode 100644
index 00000000000..305193e35a5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-DataType-v10.png
new file mode 100644
index 00000000000..7785bfc843a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-DataType.png
new file mode 100644
index 00000000000..0488e5ca139
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-Picker2-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-app-icon.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-app-icon.png
new file mode 100644
index 00000000000..e24f72dc290
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Content-app-icon.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Csv-example-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Csv-example-v8.png
new file mode 100644
index 00000000000..ad132be4a7f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Csv-example-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-Content.png
new file mode 100644
index 00000000000..1ebdd54aaaa
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-With-Time-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-With-Time-Content.png
new file mode 100644
index 00000000000..2460047b337
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-With-Time-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-With-Time-Data-Type.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-With-Time-Data-Type.png
new file mode 100644
index 00000000000..1b1573f3cdc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Date-Time-With-Time-Data-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/DateTime-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/DateTime-DataType.png
new file mode 100644
index 00000000000..c0c5dfb8d60
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/DateTime-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-Content-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-Content-v10.png
new file mode 100644
index 00000000000..71b57446e23
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-Content-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-Content.png
new file mode 100644
index 00000000000..4d69318f166
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-v8.png
new file mode 100644
index 00000000000..8a23ef3e7dd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-v88.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-v88.png
new file mode 100644
index 00000000000..fe097a4cfab
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/EmailAddress-DataType-v88.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Eye-Dropper-Color-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Eye-Dropper-Color-Picker-Content-v8.png
new file mode 100644
index 00000000000..d404b98533b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Eye-Dropper-Color-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Eye-Dropper-Color-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Eye-Dropper-Color-Picker-DataType-v8.png
new file mode 100644
index 00000000000..c8d568092ed
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Eye-Dropper-Color-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/File-Upload-content-example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/File-Upload-content-example.png
new file mode 100644
index 00000000000..83a6fc3ac28
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/File-Upload-content-example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Json-example-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Json-example-v8.png
new file mode 100644
index 00000000000..509f6bc80d8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Json-example-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Label-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Label-Content-v8.png
new file mode 100644
index 00000000000..8542a32ceb9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Label-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Label-Setup-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Label-Setup-v8.png
new file mode 100644
index 00000000000..c3c57f0a063
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Label-Setup-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Markdown-Editor-content-example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Markdown-Editor-content-example.png
new file mode 100644
index 00000000000..e71cbb2825f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Markdown-Editor-content-example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Markdown-Editor-definition-example-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Markdown-Editor-definition-example-v10.png
new file mode 100644
index 00000000000..d697795c88a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Markdown-Editor-definition-example-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-Content-v8.png
new file mode 100644
index 00000000000..22adeb1cfed
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-Content.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-Content.jpg
new file mode 100644
index 00000000000..ab98dd1c544
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-Content.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-8_1.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-8_1.png
new file mode 100644
index 00000000000..06b96e1f7aa
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-8_1.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-v10.png
new file mode 100644
index 00000000000..761f85d1b08
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-v8.png
new file mode 100644
index 00000000000..47a81f806f8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType.jpg
new file mode 100644
index 00000000000..9ac41a5e833
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker-DataType.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker2-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker2-Content.png
new file mode 100644
index 00000000000..d608e07bddc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker2-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker2-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker2-DataType.png
new file mode 100644
index 00000000000..aebba80af59
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker2-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker3-Content.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker3-Content.jpg
new file mode 100644
index 00000000000..4cf7c146c4a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker3-Content.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker3-DataType.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker3-DataType.jpg
new file mode 100644
index 00000000000..5bd2ba0f4fa
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Media-Picker3-DataType.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/MediaPicker-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/MediaPicker-DataType-v10.png
new file mode 100644
index 00000000000..a779088cce0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/MediaPicker-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Group-Picker-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Group-Picker-Content.png
new file mode 100644
index 00000000000..33109a95d23
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Group-Picker-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-Content-v8.png
new file mode 100644
index 00000000000..5f01d0e0fac
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-Content.png
new file mode 100644
index 00000000000..7b192ab851c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-DataType-v8.png
new file mode 100644
index 00000000000..e1b845db8e7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-DataType.png
new file mode 100644
index 00000000000..b62615b15de
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Member-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-Content-v8.png
new file mode 100644
index 00000000000..83e70feba90
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-Content.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-Content.jpg
new file mode 100644
index 00000000000..1f59bd1aa4e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-Content.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType-8_1.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType-8_1.png
new file mode 100644
index 00000000000..a5b012f17c6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType-8_1.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType-v8.png
new file mode 100644
index 00000000000..373a1683542
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType.png
new file mode 100644
index 00000000000..824437a853c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker2-Content.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker2-Content.jpg
new file mode 100644
index 00000000000..bb3ab928c11
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker2-Content.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker2-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker2-DataType.png
new file mode 100644
index 00000000000..f6ce9d537f1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multinode-Treepicker2-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1) (1).png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1) (1).png
new file mode 100644
index 00000000000..7c3e61eae19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1) (1).png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1) (2).png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1) (2).png
new file mode 100644
index 00000000000..7c3e61eae19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1) (2).png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1).png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1).png
new file mode 100644
index 00000000000..7c3e61eae19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (1).png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (2).png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (2).png
new file mode 100644
index 00000000000..7c3e61eae19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content (2).png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content.png
new file mode 100644
index 00000000000..7c3e61eae19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multiple-Textbox-Repeatable-Textstrings-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-Content-v8.png
new file mode 100644
index 00000000000..ce2969ab86c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-8_1.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-8_1.png
new file mode 100644
index 00000000000..3e2453ac34e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-8_1.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-v10.png
new file mode 100644
index 00000000000..062da5499b4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-v8.png
new file mode 100644
index 00000000000..4f9616254e2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Multy-Url-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_AddContent.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_AddContent.png
new file mode 100644
index 00000000000..98414978dc3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_AddContent.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_DataType-v8.png
new file mode 100644
index 00000000000..161b7936661
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_DataTypeDefinition.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_DataTypeDefinition.png
new file mode 100644
index 00000000000..dda7d36f1eb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_DataTypeDefinition.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_EditItem-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_EditItem-v8.png
new file mode 100644
index 00000000000..94c5c38a18e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_EditItem-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_EditItem.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_EditItem.png
new file mode 100644
index 00000000000..da6b1155c87
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_EditItem.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NewItem-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NewItem-v8.png
new file mode 100644
index 00000000000..f762ddad70b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NewItem-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NewItem.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NewItem.png
new file mode 100644
index 00000000000..fcde18e4093
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NewItem.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NotSupported.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NotSupported.png
new file mode 100644
index 00000000000..0c6117c24cd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_NotSupported.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SelectSchema-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SelectSchema-v8.png
new file mode 100644
index 00000000000..d1ce4c68a49
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SelectSchema-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SelectSchema.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SelectSchema.png
new file mode 100644
index 00000000000..08e3d50241a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SelectSchema.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SingleItemMode-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SingleItemMode-v8.png
new file mode 100644
index 00000000000..7ca1a2aa5cd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SingleItemMode-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SingleItemMode.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SingleItemMode.png
new file mode 100644
index 00000000000..f0339bd55c7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/NestedContent_SingleItemMode.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-Content-v7.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-Content-v7.png
new file mode 100644
index 00000000000..1b127cb708f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-Content-v7.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-Content-v8.png
new file mode 100644
index 00000000000..dffc9993677
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v10.png
new file mode 100644
index 00000000000..2127a4f1ced
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v7.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v7.png
new file mode 100644
index 00000000000..142fa243b8b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v7.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v8.png
new file mode 100644
index 00000000000..8ba95eb0960
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/RadioButton-List-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links-Content.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links-Content.jpg
new file mode 100644
index 00000000000..69a93e1b650
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links-Content.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links-DataType.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links-DataType.jpg
new file mode 100644
index 00000000000..ed7f4b3cd0f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links-DataType.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links2-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links2-Content.png
new file mode 100644
index 00000000000..2a794696fc7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links2-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links2-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links2-DataType.png
new file mode 100644
index 00000000000..7dff6a53a7a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Related-Links2-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-Content.png
new file mode 100644
index 00000000000..7c3e61eae19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-DataType-v10.png
new file mode 100644
index 00000000000..9712de40e4b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-DataType.png
new file mode 100644
index 00000000000..4111a53f682
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Repeatable-Textstrings-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Content-Example-With-Range.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Content-Example-With-Range.png
new file mode 100644
index 00000000000..94a6744a65d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Content-Example-With-Range.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Content-Example-no-range.PNG b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Content-Example-no-range.PNG
new file mode 100644
index 00000000000..defbec9d5c0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Content-Example-no-range.PNG differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Data-Type-Definition-Example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Data-Type-Definition-Example.png
new file mode 100644
index 00000000000..83075cd06e3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Slider-Data-Type-Definition-Example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Tags-DataType-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Tags-DataType-v10.png
new file mode 100644
index 00000000000..28df576cc66
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Tags-DataType-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Tags-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Tags-DataType-v8.png
new file mode 100644
index 00000000000..4cdceafb098
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Tags-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Content-Limit-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Content-Limit-v8.png
new file mode 100644
index 00000000000..11b0429ae07
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Content-Limit-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Content-v8.png
new file mode 100644
index 00000000000..a705fe2e373
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-Limit-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-Limit-v8.png
new file mode 100644
index 00000000000..10056565a9e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-Limit-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-v10.png
new file mode 100644
index 00000000000..c9fc0f6ab18
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-v8.png
new file mode 100644
index 00000000000..57e204be5da
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textarea-Setup-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Content-Limit-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Content-Limit-v8.png
new file mode 100644
index 00000000000..3fac1920ccf
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Content-Limit-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Content-v8.png
new file mode 100644
index 00000000000..0d11476b79d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Setup-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Setup-v10.png
new file mode 100644
index 00000000000..63c007e993b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Setup-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Setup-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Setup-v8.png
new file mode 100644
index 00000000000..6be488e2c47
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Textbox-Setup-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/True-False-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/True-False-Content.png
new file mode 100644
index 00000000000..f9e2ee1d4f9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/True-False-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/True-False-DataType-742.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/True-False-DataType-742.jpg
new file mode 100644
index 00000000000..3fed90221c1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/True-False-DataType-742.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Typeahead-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Typeahead-v8.png
new file mode 100644
index 00000000000..36c7d8ab560
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/Typeahead-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/User-Picker-Content-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/User-Picker-Content-v8.png
new file mode 100644
index 00000000000..b10862a78f2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/User-Picker-Content-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/User-Picker-DataType-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/User-Picker-DataType-v8.png
new file mode 100644
index 00000000000..e2e6107c9e6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/User-Picker-DataType-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-content.png
new file mode 100644
index 00000000000..091b76744a6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-setup-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-setup-v8.png
new file mode 100644
index 00000000000..31e261468bb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-setup-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-setup.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-setup.png
new file mode 100644
index 00000000000..cbc8b32dab8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/checkbox-list-setup.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/configuration.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/configuration.png
new file mode 100644
index 00000000000..7fed23ebeaf
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/configuration.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/content-example-empty.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/content-example-empty.png
new file mode 100644
index 00000000000..c52090520a5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/content-example-empty.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/content-example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/content-example.png
new file mode 100644
index 00000000000..43de1d23057
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/content-example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/crop.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/crop.png
new file mode 100644
index 00000000000..9eab72c6175
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/crop.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/datatype.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/datatype.png
new file mode 100644
index 00000000000..679cf442191
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/datatype.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/date-picker-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/date-picker-v8.png
new file mode 100644
index 00000000000..af4255a5566
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/date-picker-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/date-time-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/date-time-v8.png
new file mode 100644
index 00000000000..04e52f6da2c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/date-time-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/definition-example-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/definition-example-v10.png
new file mode 100644
index 00000000000..64f63e9d0d3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/definition-example-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/definition-example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/definition-example.png
new file mode 100644
index 00000000000..16ad8acfcd0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/definition-example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/emailaddress-datatype-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/emailaddress-datatype-v10.png
new file mode 100644
index 00000000000..d89366ff495
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/emailaddress-datatype-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/enable-listview.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/enable-listview.png
new file mode 100644
index 00000000000..1bd0f06ee35
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/enable-listview.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/focalpoint.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/focalpoint.png
new file mode 100644
index 00000000000..e315b62e092
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/focalpoint.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-crop-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-crop-v8.png
new file mode 100644
index 00000000000..fbbb3983ca0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-crop-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-focalpoint-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-focalpoint-v8.png
new file mode 100644
index 00000000000..6d7faf59490
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-focalpoint-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-upload-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-upload-v8.png
new file mode 100644
index 00000000000..94e5f4e3056
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-upload-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-v8.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-v8.png
new file mode 100644
index 00000000000..71285c8067a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-v9.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-v9.png
new file mode 100644
index 00000000000..18bddd8e816
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/imageCropper-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-icon.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-icon.png
new file mode 100644
index 00000000000..e9ed8be01f5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-icon.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-member-picked.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-member-picked.png
new file mode 100644
index 00000000000..303197e4571
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-member-picked.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-view-settings1-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-view-settings1-v10.png
new file mode 100644
index 00000000000..779fee60cd3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-view-settings1-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-view-settings2-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-view-settings2-v10.png
new file mode 100644
index 00000000000..ddb8b025c09
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/list-view-settings2-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-content-example-email-settings.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-content-example-email-settings.png
new file mode 100644
index 00000000000..4224ff7dcad
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-content-example-email-settings.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-content-example-email.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-content-example-email.png
new file mode 100644
index 00000000000..b20a1a15a63
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-content-example-email.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-property-dropdown.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-property-dropdown.png
new file mode 100644
index 00000000000..55783a6a881
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-property-dropdown.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-property.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-property.png
new file mode 100644
index 00000000000..6d8cc9b007a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-property.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-settings-2.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-settings-2.png
new file mode 100644
index 00000000000..3f79b7b6af9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-settings-2.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-settings.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-settings.png
new file mode 100644
index 00000000000..c34dd7dd17b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview-settings.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview.png
new file mode 100644
index 00000000000..6e6495012ec
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/listview.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/mandatory-checkbox.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/mandatory-checkbox.png
new file mode 100644
index 00000000000..72956366eb8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/mandatory-checkbox.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/member-picker-settings.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/member-picker-settings.png
new file mode 100644
index 00000000000..888e6eeb6ee
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/member-picker-settings.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/member-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/member-picker.png
new file mode 100644
index 00000000000..a750e3f6ab5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/member-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-content.png
new file mode 100644
index 00000000000..165126a8334
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-datatype-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-datatype-v10.png
new file mode 100644
index 00000000000..80cab7f01f1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-datatype-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-datatype.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-datatype.png
new file mode 100644
index 00000000000..cca349097c3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/numeric-datatype.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/others-result.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/others-result.png
new file mode 100644
index 00000000000..d9ca0303dc3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/others-result.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/others.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/others.png
new file mode 100644
index 00000000000..29780fc0632
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/others.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/picked-member.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/picked-member.png
new file mode 100644
index 00000000000..e7ebbae510e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/picked-member.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/upload.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/upload.png
new file mode 100644
index 00000000000..2d0bddbf0c7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/upload.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/wip.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/wip.png
new file mode 100644
index 00000000000..0665c1c1b87
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-property-editors/images/wip.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/README.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/README.md
new file mode 100644
index 00000000000..59ba7b8ffe7
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/README.md
@@ -0,0 +1,2 @@
+# Built-in Property Editors
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/README.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/README.md
new file mode 100644
index 00000000000..bf1f3ed396e
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/README.md
@@ -0,0 +1,19 @@
+# Block Editors
+
+The Block Editors are property editors that enabled you to build advanced editor tools using a set of predefined Document Types.
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Umbraco CMS currently ships with two Block Editors: the Block List and the Block Grid.
+
+## [Block List](block-list-editor.md)
+
+## [Block Grid](block-grid-editor.md)
+
+## Customizing Block Editors
+
+### [Creating custom views for blocks](../../../../../tutorials/creating-custom-views-for-blocklist.md)
+
+Learn how to create custom views for the blocks used in your Block Grid or Block List property editors.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-grid-editor.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-grid-editor.md
new file mode 100644
index 00000000000..9e5ee12fe48
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-grid-editor.md
@@ -0,0 +1,737 @@
+# Block Grid
+
+`Schema Alias: Umbraco.BlockGrid`
+
+`UI Alias: Umb.PropertyEditorUi.BlockGrid`
+
+`Returns: BlockGridModel`
+
+The **Block Grid** property editor enables editors to layout their content in the Umbraco backoffice. The content is made of Blocks that can contain different types of data.
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+## Sample configuration
+
+When testing out the property editor, you can use a set of predefined Blocks. The option will only be possible when there are no other Data Types using the Block Grid property editor.
+
+
+
+* Create a new **Data Type**.
+* Select the **Block Grid** as the **Property editor**.
+* **Install** the "Sample Configuration".
+
+4 Blocks will be added to the property, ready for testing.
+
+## Configuring the Block Grid
+
+The Block Grid property editor is configured via the **Data Types** backoffice interface.
+
+To set up the Block Grid property editor, follow these steps:
+
+1. Navigate to the **Settings** section in the Umbraco backoffice.
+2. Click **...** next to the **Data Types** folder.
+3. Select **Create** -> **New Data Type**.
+4. Select **Block Grid** from the list of available property editors.
+
+You will see the configuration options for a Block Grid property editor as shown below:
+
+
+
+The Data Type editor allows you to configure the following properties:
+
+* **Blocks** - Defines the Block Types available for use in the property. For more information, see [Setup Block Types](block-grid-editor.md#setup-block-types).
+* **Amount** - Sets the minimum and/or the maximum number of Blocks that should be allowed at the root of the layout.
+* **Live editing mode** - Enabling this option will allow you to see the changes as you are editing them.
+* **Editor width** - Overwrites the width of the property editor. This field takes any valid CSS value for "max-width". For example: 100% or 800px.
+* **Grid Columns** - Define the number of columns in your Block Grid. The default is 12 columns.
+* **Layout Stylesheet** - Replaces the built-in Layout Stylesheet. Additionally, you can retrieve the default layout stylesheet to use as a base for your own inspiration or for writing your own stylesheet.
+* **Create Button Label** - Overwrites the label on the Create button.
+
+## Setup Block Types
+
+Block Types are based on [**Element Types**](../../../../data/defining-content/#element-types). These can be created beforehand or while setting up your Block Types.
+
+Once you have added an Element Type as a Block Type on your Block Grid Data Type you have the option to configure it.
+
+
+
+### Groups
+
+Blocks can also be grouped. This is visible in the Block Catalogue and can also be used to allow a group of Blocks in an Area.
+
+## Block Configuration Settings
+
+Each Block has a set of properties that are optional to configure. These are described below.
+
+### General
+
+Customize the user experience for your content editors when they work with the Blocks in the Content section.
+
+* **Label** - Defines a label for the appearance of the Block in the editor. The label can use AngularJS template-string-syntax to display values of properties.
+
+{% hint style="info" %}
+Label example: "My Block {=myPropertyAlias}" will be shown as: "My Block FooBar".
+{% endhint %}
+
+* **Content model** - Presents the Element Type used as model for the Content section of this Block. This cannot be changed but you can open the Element Type to perform edits or view the properties available. Useful when writing your Label.
+* **Settings model** - Adds a Settings section to your Block based on a given Element Type. When selected you can open the Element Type or choose to remove the Settings section again.
+
+### Size options
+
+Customize the Blocks size in the Grid. If you define multiple options, the Block becomes scalable.
+
+By default, a Block takes up the available width.
+
+A Block can be resized in two ways:
+
+1. When a Block is placed in an Area, it will fit to the Areas width. Learn more about [Areas](block-grid-editor.md#areas).
+2. A Block can have one or more Column Span options defined.
+
+A Column Span option is used to define the width of a Block. With multiple Column Span options defined, the Content Editor can scale the Block to fit specific needs.
+
+Additionally, Blocks can be configured to span rows, this enables one Block to be placed next to a few rows containing other Blocks.
+
+* **Available column spans** - Defines one or more columns, the Block spans across. For example: in a 12 columns grid, 6 columns is equivalent to half width. By enabling 6 columns and 12 columns, the Block can be scaled to either half width or full width.
+* **Available row spans** - Defines the amount of rows the Block spans across.
+
+See the [scaling blocks](block-grid-editor.md#scaling-blocks) section of this article for an example of how scaling works.
+
+### Catalogue appearance
+
+These properties refer to how the Block is presented in the Block catalogue when editors choose which Blocks to use for their content.
+
+* **Background color** - Defines a background color to be displayed beneath the icon or thumbnail. Example: `#424242`.
+* **Icon color** - Changes the color of the Element Type icon. Example: `#242424`.
+* **Thumbnail** - Pick an image or Scalable Vector Graphics (SVG) file to replace the icon of the Block in the catalogue.
+
+The thumbnails for the catalogue are presented in the format of 16:10. We recommend a resolution of 400px width and 250px height.
+
+### Permissions
+
+* **Allow in root** - Determines whether the Block can be created at the root of your layout. Turn this off if you only want a Block to appear within Block Areas.
+* **Allow in areas** - Determines whether the Block can be created inside Areas of other Blocks. If this is turned off it can still be allowed in Block Areas by defining specific allowed Blocks.
+
+## Areas
+
+Blocks can nest other Blocks to support specific compositions. These compositions can be used as a layout for other Blocks.
+
+To achieve nesting, a Block must have one or more Areas defined. Each Area can contain one or more Blocks.
+
+Each Area has a size, defined by column and rows spans. The grid for the Areas are based on the same amount of columns as your root grid, unless you choose to change it.
+
+To scale an Area, click and drag the scale-button in the bottom-right corner of an Area.
+
+* **Grid Columns for Areas** - Overwrites the amount of columns used for the Area grid.
+* **Areas** - Determines whether the Block can be created inside Areas of other Blocks.
+
+
+
+### Area configuration
+
+
+
+* **Alias** - The alias is used to identify this Area. It is being printed by `GetBlockGridHTML()` and used as name for the Area slot in Custom Views. The alias is also available for CSS Selectors to target the HTML-Element representing an Area.
+* **Create Button Label** - Overwrites the Create Button Label of the Area.
+* **Number of blocks** - Determines the total number of Blocks in an Area.
+* **Allowed block types** - When this is empty, all Blocks with Permissions for creation in Areas, will be available. This can be overwritten by specifying the allowed Blocks. Define the types of Blocks or Groups of Blocks that are allowed. Additionally, you can also set how many Blocks of each type/group should be present.
+
+When allowing a Group of Blocks, you might want to require a specific amount for a certain Block of that Group. This can be done by adding that Block Type to the list as well and set the requirements.
+
+## Advanced
+
+These properties are relevant when working with custom views or complex projects.
+
+* **Custom view** - Overwrites the AngularJS view for the block presentation in the Content editor. Use this view to make a more visual presentation of the Block or make your own editing experience by adding your own AngularJS controller to the view.
+
+{% hint style="info" %}
+Notice that any styling of a Block is scoped. This means that the default backoffice styles are not present for the view of this Block.
+{% endhint %}
+
+* **Custom stylesheet** - Pick your own stylesheet to be used by the Block in the Content editor.
+* **Overlay editor size** - Sets the size for the Content editor overlay for editing this block.
+* **Hide content editor** - Hides the UI for editing the content in a Block Editor. This is only relevant if you made a custom view that provides the UI for editing of content.
+
+## Editing Blocks
+
+When viewing a **Block Grid** property editor in the **Content** section for the first time, you will be presented with the option to **Add content**.
+
+
+
+Clicking the **Add content** button opens up the **Block Catalogue**.
+
+
+
+The Block Catalogue looks different depending on the amount of available Blocks and their catalogue appearance.
+
+
+
+Click the Block Type you wish to create and a new Block will appear in the layout.
+
+More Blocks can be added to the layout by clicking the Add content button. Alternatively, use the Add content button that appears on hover to add new Blocks between, besides, or above the existing Blocks.
+
+
+
+To delete a Block, click the trash icon which appears on the mouse hover.
+
+
+
+## Sorting Blocks
+
+Blocks can be rearranged using the click and drag feature. Move them up or down to place them in the desired order.
+
+Moving a Block from one Area to another is done in the same way. If a Block is not allowed in the given position, the area will display a red color and not allow the new position.
+
+
+
+## Scaling Blocks
+
+If a Block has multiple size options it can be scaled via the UI. This appears in the bottom left corner of the Block.
+
+The Block is resized using a click-and-drag feature. Moving the mouse will change the size to the size options closest to the mouse pointer.
+
+
Scale blocks in the grid by dragging from the bottom-right corner.
+
+## Rendering Block Grid Content
+
+Rendering the stored value of your **Block Grid** property editor can be done in two ways:
+
+1. [Default rendering](block-grid-editor.md#1-default-rendering)
+2. [Build your own rendering](block-grid-editor.md#2-build-your-own-rendering)
+
+### 1. Default rendering
+
+You can choose to use the built-in rendering mechanism for rendering Blocks using a Partial View for each block.
+
+The default rendering method is named `GetBlockGridHtmlAsync()` and comes with a few options - for example:
+
+```csharp
+@await Html.GetBlockGridHtmlAsync(Model, "myGrid")
+```
+
+In the sample above `"myGrid"` is the alias of the Block Grid editor.
+
+If you are using ModelsBuilder, the example will look like this:
+
+```csharp
+@await Html.GetBlockGridHtmlAsync(Model.MyGrid)
+```
+
+To use the `GetBlockGridHtmlAsync()` method, you will need to create a Partial View for each Block Type. The Partial View must be named using the alias of the Element Type that is being used as Content Model for the Block Type.
+
+These Partial View files need to go into the `Views/Partials/blockgrid/Components/` folder.
+
+Example: `Views/Partials/blockgrid/Components/MyElementTypeAliasOfContent.cshtml`.
+
+The Partial Views will receive a model of type `Umbraco.Cms.Core.Models.Blocks.BlockGridItem`. This model contains `Content` and `Settings` from your block, as well as the configured `RowSpan`, `ColumnSpan`, and `Areas` of the Block.
+
+#### Rendering the Block Areas
+
+The Partial View for the Block is responsible for rendering its own Block Areas. This is done using another built-in rendering mechanism:
+
+```csharp
+@await Html.GetBlockGridItemAreasHtmlAsync(Model)
+```
+
+Here you will need to create a Partial View for each Block Type within the Block Area. For the name, use the alias of the Element Type that is being used as Content Model for the Block Type.
+
+These Partial Views must be placed in the same folder as before, (`Views/Partials/blockgrid/Components/`), and will receive a model of type `Umbraco.Cms.Core.Models.Blocks.BlockGridItem`.
+
+#### Putting it all together
+
+The following is an example of a Partial View for a Block Type of type `MyElementTypeAliasOfContent`.
+
+{% code title="MyElementTypeAliasOfContent.cshtml" %}
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
+
+@* Render the value of field with alias 'heading' from the Element Type selected as Content section *@
+
@Model.Content.Value("heading")
+
+@* Render the block areas *@
+@await Html.GetBlockGridItemAreasHtmlAsync(Model)
+```
+{% endcode %}
+
+If you are using ModelsBuilder, you can make the property rendering strongly typed by letting your view accept a model of type `BlockGridItem`. For example:
+
+{% code title="MyElementTypeAliasOfContent.cshtml" %}
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage>;
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+
+@* Render the Heading property from the Element Type selected as Content section *@
+
@Model.Content.Heading
+
+@* Render the block areas *@
+@await Html.GetBlockGridItemAreasHtmlAsync(Model)
+```
+{% endcode %}
+
+#### Stylesheet
+
+Using the default rendering together with your layout stylesheet will provide what you need for rendering the layout.
+
+To use the Default Layout Stylesheet, copy the stylesheet to your frontend. You can download the default layout stylesheet from the link within the DataType, we recommend putting the file in the `css` folder, example: `wwwroot/css/umbraco-blockgridlayout.css`.
+
+```csharp
+
+```
+
+{% hint style="info" %}
+A set of built-in Partial Views are responsible for rendering the Blocks and Areas in a Block Grid. If you want to tweak or change the way the Block Grid is rendered, you can use the built-in Partial Views as a template:
+
+1. Clone the views from [GitHub](https://github.com/umbraco/Umbraco-CMS/tree/contrib/src/Umbraco.Web.UI/Views/Partials/blockgrid). They can be found in `src/Umbraco.Web.UI/Views/Partials/blockgrid` .
+2. Copy the cloned views to the local folder `Views/Partials/blockgrid/` .
+3. Make changes to your copied views. The entry point for `GetBlockGridHtmlAsync()` is the view `default.cshtml` .
+{% endhint %}
+
+### 2. Build custom rendering
+
+The built-in value converter for the Block Grid property editor lets you use the block data as you like. Call the `Value` method with a type of `BlockGridModel` to have the stored value returned as a `BlockGridModel` instance.
+
+`BlockGridModel` contains the Block Grid configuration (like the number of columns as `GridColumns`) whilst also being an implementation of `IEnumerable` (see details for `BlockGridItem` above).
+
+The following example mimics the built-in rendering mechanism for rendering Blocks using Partial Views:
+
+{% code title="View.cshtml" %}
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+@using Umbraco.Cms.Core.Models.Blocks
+@{
+ var grid = Model.Value("myGrid");
+
+ // get the number of columns defined for the grid
+ var gridColumns = grid.GridColumns;
+
+ // iterate the block items
+ foreach (var item in grid)
+ {
+ var content = item.Content;
+
+ @await Html.PartialAsync("PathToMyFolderOfPartialViews/" + content.ContentType.Alias, item);
+ }
+}
+```
+{% endcode %}
+
+If you do not want to use Partial Views, you can access the block item data directly within your rendering:
+
+{% code title="View.cshtml" %}
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+@using Umbraco.Cms.Core.Models.Blocks
+@{
+ var grid = Model.Value("myGrid");
+
+ // get the number of columns defined for the grid
+ var gridColumns = grid.GridColumns;
+
+ // iterate the block items
+ foreach (var item in grid)
+ {
+ // get the content and settings of the block
+ var content = item.Content;
+ var settings = item.Settings;
+ // get the areas of the block
+ var areas = item.Areas;
+ // get the dimensions of the block
+ var rowSpan = item.RowSpan;
+ var columnSpan = item.ColumnSpan;
+
+ // render the block data
+
+
@(content.Value("title"))
+ This block is supposed to span @rowSpan rows and @columnSpan columns
+
+ }
+}
+```
+{% endcode %}
+
+## Write a Custom Layout Stylesheet
+
+The default layout stylesheet is using CSS Grid. This can be modified to fit your implementation and your project.
+
+### Adjusting the Default Layout Stylesheet
+
+To make additions or overwrite parts of the default layout stylesheet, import the default stylesheet at the top of your own file.
+
+```css
+@import 'css/umbblockgridlayout.css';
+```
+
+You need to copy the Default Layout Stylesheet to your frontend. You can download the default layout stylesheet from the link within the DataType, we recommend putting the file in the `css` folder, example: `wwwroot/css/umbraco-blockgridlayout.css`.
+
+### Write a new Layout Stylesheet
+
+In this case, you would have to write the layout from scratch.
+
+You are free to pick any style, meaning there is no requirement to use CSS Grid. It is, however, recommended to use CSS Grid to ensure complete compatibility with the Umbraco backoffice.
+
+### CSS Class structure and available data
+
+When extending or writing your own layout, you need to know the structure and what data is available.
+
+For example: You can use the below HTML structure:
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## Build a Custom Backoffice View
+
+Building Custom Views for Block representations in Backoffice is based on the same API for all Block Editors.
+
+[Read about building a Custom View for Blocks here](../../../../../customizing/extending-overview/extension-types/block-custom-view.md)
+
+## Creating a Block Grid programmatically
+
+In this example, we will be creating content programmatically for a "spot" Blocks in a Block Grid.
+
+1. On a Document Type add a property called **blockGrid**.
+2. Then add as editor **Block Grid**.
+3. In the Block Grid add a new block and click to **Create new Element Type**
+4. Name this element type **spotElement** with the following properties:
+
+* A property called **title** with the editor of **Textstring**
+* A property called **text** with the editor of **Textstring**
+
+5. Then on the **Settings model** click to add a new Setting.
+6. Then click to **Create new Element Type**.
+7. Name this element type **spotSettings** with the following properties:
+
+* A property called **featured** with the editor of **True/false**.
+
+
+
+The raw input data for the spots looks like this:
+
+```csharp
+new[]
+{
+ new { Title = "Item one", Text = "This is item one", Featured = false, ColumnSpan = 12, RowSpan = 1 },
+ new { Title = "Item two", Text = "This is item two", Featured = true, ColumnSpan = 6, RowSpan = 2 }
+}
+```
+
+The resulting JSON object stored for the Block Grid will look like this:
+
+```json
+{
+ "layout": {
+ "Umbraco.BlockGrid": [{
+ "contentUdi": "umb://element/bb23fe28160941efa506da7aa314172d",
+ "settingsUdi": "umb://element/9b832ee528464456a8e9a658b47a9801",
+ "areas": [],
+ "columnSpan": 12,
+ "rowSpan": 1
+ }, {
+ "contentUdi": "umb://element/a11e06ca155d40b78189be0bdaf11c6d",
+ "settingsUdi": "umb://element/d182a0d807fc4518b741b77c18aa73a1",
+ "areas": [],
+ "columnSpan": 6,
+ "rowSpan": 2
+ }
+ ]
+ },
+ "contentData": [{
+ "contentTypeKey": "0e9f8609-1904-4fd1-9801-ad1880825ff3",
+ "udi": "umb://element/bb23fe28160941efa506da7aa314172d",
+ "title": "Item one",
+ "text": "This is item one"
+ }, {
+ "contentTypeKey": "0e9f8609-1904-4fd1-9801-ad1880825ff3",
+ "udi": "umb://element/a11e06ca155d40b78189be0bdaf11c6d",
+ "title": "Item two",
+ "text": "This is item two"
+ }
+ ],
+ "settingsData": [{
+ "contentTypeKey": "22be457c-8249-42b8-8685-d33262f7ce2a",
+ "udi": "umb://element/9b832ee528464456a8e9a658b47a9801",
+ "featured": "0"
+ }, {
+ "contentTypeKey": "22be457c-8249-42b8-8685-d33262f7ce2a",
+ "udi": "umb://element/d182a0d807fc4518b741b77c18aa73a1",
+ "featured": "1"
+ }
+ ]
+}
+```
+
+For each item in the raw data, we need to create:
+
+* One `contentData` entry with the _title_ and _text_.
+* One `settingsData` entry with the _featured_ value (the checkbox expects `"0"` or `"1"` as data value).
+* One `layout` entry with the desired column and row spans.
+
+All `contentData` and `layoutData` entries need their own unique `Udi` as well as the ID (key) of their corresponding Element Types. In this sample, we only have one Element Type for content (`spotElement`) and one for settings (`spotSettings`). In a real life scenario, there could be any number of Element Type combinations.
+
+8. First and foremost, we need models to transform the raw data into Block Grid compatible JSON. Create a class called **Model.cs** containing the following:
+
+{% code title="Models.cs" lineNumbers="true" %}
+```csharp
+using Umbraco.Cms.Core;
+using System.Text.Json.Serialization;
+namespace My.Site.Models;
+
+// this is the "root" of the block grid data
+public class BlockGridData
+{
+ public BlockGridData(BlockGridLayout layout, BlockGridElementData[] contentData, BlockGridElementData[] settingsData)
+ {
+ Layout = layout;
+ ContentData = contentData;
+ SettingsData = settingsData;
+ }
+
+ [JsonPropertyName("layout")]
+ public BlockGridLayout Layout { get; }
+
+ [JsonPropertyName("contentData")]
+ public BlockGridElementData[] ContentData { get; }
+
+ [JsonPropertyName("settingsData")]
+ public BlockGridElementData[] SettingsData { get; }
+}
+
+// this is a wrapper for the block grid layout, purely required for correct serialization
+public class BlockGridLayout
+{
+ public BlockGridLayout(BlockGridLayoutItem[] layoutItems) => LayoutItems = layoutItems;
+
+ [JsonPropertyName("Umbraco.BlockGrid")]
+ public BlockGridLayoutItem[] LayoutItems { get; }
+}
+
+// this represents an item in the block grid layout collection
+public class BlockGridLayoutItem
+{
+ public BlockGridLayoutItem(Udi contentUdi, Udi settingsUdi, int columnSpan, int rowSpan)
+ {
+ ContentUdi = contentUdi;
+ SettingsUdi = settingsUdi;
+ ColumnSpan = columnSpan;
+ RowSpan = rowSpan;
+ }
+
+ [JsonPropertyName("contentUdi")]
+ public Udi ContentUdi { get; }
+
+ [JsonPropertyName("settingsUdi")]
+ public Udi SettingsUdi { get; }
+
+ [JsonPropertyName("areas")]
+ // areas are omitted from this sample for abbreviation
+ public object[] Areas { get; } = { };
+
+ [JsonPropertyName("columnSpan")]
+ public int ColumnSpan { get; }
+
+ [JsonPropertyName("rowSpan")]
+ public int RowSpan { get; }
+
+}
+
+// this represents an item in the block grid content or settings data collection
+public class BlockGridElementData
+{
+ public BlockGridElementData(Guid contentTypeKey, Udi udi)
+ {
+ ContentTypeKey = contentTypeKey;
+ Udi = udi;
+ }
+
+ [JsonPropertyName("contentTypeKey")]
+ public Guid ContentTypeKey { get; }
+
+ [JsonPropertyName("udi")]
+ public Udi Udi { get; }
+
+ [JsonExtensionData]
+ public Dictionary? Data { get; set;}
+}
+```
+{% endcode %}
+
+9. By injecting [ContentService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html) and [ContentTypeService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentTypeService.html) into an API controller, we can transform the raw data into Block Grid JSON. It can then be saved to the target content item. Create a class called **BlockGridTestController.cs** containing the following:
+
+{% code title="BlockGridTestController.cs" lineNumbers="true" %}
+```csharp
+using Microsoft.AspNetCore.Mvc;
+using My.Site.Models;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Serialization;
+using Umbraco.Cms.Core.Services;
+
+namespace My.Site.Controllers;
+
+[ApiController]
+[Route("/umbraco/api/blockgridtest")]
+public class BlockGridTestController : Controller
+{
+ private readonly IContentService _contentService;
+ private readonly IContentTypeService _contentTypeService;
+ private readonly IJsonSerializer _serializer;
+
+ public BlockGridTestController(IContentService contentService, IContentTypeService contentTypeService, IJsonSerializer serializer)
+ {
+ _contentService = contentService;
+ _contentTypeService = contentTypeService;
+ _serializer = serializer;
+ }
+
+ // POST: /umbraco/api/blockgridtest/create
+ [HttpPost("create")]
+ public ActionResult Create()
+ {
+ // get the item content to modify
+ IContent? content = _contentService.GetById(Guid.Parse("efba7b97-91b6-4ddf-b2cc-eef89ff48c3b"));
+ if (content == null)
+ {
+ return NotFound("Could not find the content item to modify");
+ }
+
+ // get the element types for spot blocks (content and settings)
+ IContentType? spotContentType = _contentTypeService.Get("spotElement");
+ IContentType? spotSettingsType = _contentTypeService.Get("spotSettings");
+ if (spotContentType == null || spotSettingsType == null)
+ {
+ return NotFound("Could not find one or more content types for block data");
+ }
+
+ // this is the raw data to insert into the block grid
+ var rawData = new[]
+ {
+ new { Title = "Item one", Text = "This is item one", Featured = false, ColumnSpan = 12, RowSpan = 1 },
+ new { Title = "Item two", Text = "This is item two", Featured = true, ColumnSpan = 6, RowSpan = 2 }
+ };
+
+ // build the individual parts of the block grid data from the raw data
+ var layoutItems = new List();
+ var spotContentData = new List();
+ var spotSettingsData = new List();
+ foreach (var data in rawData)
+ {
+ // generate new UDIs for block content and settings
+ var contentUdi = Udi.Create(Constants.UdiEntityType.Element, Guid.NewGuid());
+ var settingsUdi = Udi.Create(Constants.UdiEntityType.Element, Guid.NewGuid());
+
+ // create a new layout item
+ layoutItems.Add(new BlockGridLayoutItem(contentUdi, settingsUdi, data.ColumnSpan, data.RowSpan));
+
+ // create new content data
+ spotContentData.Add(new BlockGridElementData(spotContentType.Key, contentUdi)
+ {
+ Data = new Dictionary
+ {
+ { "title", data.Title },
+ { "text", data.Text },
+ }
+ });
+
+ // create new settings data
+ spotSettingsData.Add(new BlockGridElementData(spotSettingsType.Key, settingsUdi)
+ {
+ Data = new Dictionary
+ {
+ { "featured", data.Featured ? "1" : "0" },
+ }
+ });
+ }
+
+ // construct the block grid data from layout, content and settings
+ var blockGridData = new BlockGridData(
+ new BlockGridLayout(layoutItems.ToArray()),
+ spotContentData.ToArray(),
+ spotSettingsData.ToArray());
+
+ // serialize the block grid data as JSON and save it to the "blockGrid" property on the content item
+ var propertyValue = _serializer.Serialize(blockGridData);
+ content.SetValue("blockGrid", propertyValue);
+ _contentService.Save(content);
+
+ return Ok("Saved");
+ }
+}
+```
+{% endcode %}
+
+For the above code `IContent? content = _contentService.GetById(1203);` change the id with your content node that is using the Block Grid.
+
+10. In order to test this implementation, run the project and add `/umbraco/api/blockgridtest/create` after your domain name. If the result shows as **Saved** then check your content node and you will see the 2 spotElement contents.
+
+
+
+_This can also be tested via Postman as well if preffered._
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-level-variance.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-level-variance.md
new file mode 100644
index 00000000000..339e0404f8c
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-level-variance.md
@@ -0,0 +1,68 @@
+---
+description: An intro to achieving content variance at block level.
+---
+
+# Block Level Variance
+
+In a variant context, a Block Editor behaves like any other Umbraco property editor by default. The Blocks contained within the editor "belong" to the Document variant, and there is no connection between Blocks across variants.
+
+In other words, both Block content and structure can vary between each Document variant.
+
+
+
+This is the desired behavior for many cases. However, in some cases it is preferable to have a shared Block structure across all variants, where only the Block content varies.
+
+This is known as Block Level Variance:
+
+
+
+Block Level Variance is achieved when:
+
+* The [Document Type](../../../../data/defining-content/default-document-types.md#document-type) is configured for variance, and
+* The Block Editor property is _not_ configured for variance, and
+* The Block Editor property editor is configured to use [Element Types](../../../../data/defining-content/default-document-types.md#element-type) that _do_ vary.
+
+## The "unexposed" Block state
+
+When adding a new _variant_ Block to one Document variant, it is automatically added to all variants of the Document.
+
+The Block will start out in an "unexposed" state for all other Document variants than the one where it was added. It will remain like that for each variant until it is edited in that variant.
+
+The "unexposed" state is visualized by a dimmed-down icon and title (or likely a missing title, if [Umbraco Flavored Markdown](../../../../../reference/umbraco-flavored-markdown.md) is used):
+
+
+
+{% hint style="info" %}
+"Unexposed" Blocks are omitted from the published Document output. So, you do not need to worry about defensive coding to avoid rendering these Blocks.
+{% endhint %}
+
+## Invariance vs. Block Level Variance
+
+It is entirely possible to mix and match variance and invariance within the scope of Block Level Variance. Invariance is fully supported, both at Block level and at Block property level.
+
+Invariance within Block Level Variance follows the same rules as invariance at Document level:
+
+- Invariant content is added to and updated across all Document variants.
+- Invariant content is explicitly published for all published Document variants when one or more variants are published.
+
+### Examples
+
+Consider a Document with English and Danish language variants, which is published in both languages.
+
+- An editor opens the English variant.
+- They add an invariant Block, and
+- They re-publish the English variant.
+
+**Result:** The new block will appear in both the English and Danish published content.
+
+- An editor opens the Danish variant.
+- They update an invariant property value in a variant Block, and
+- They re-publish the Danish variant.
+
+**Result:** The updated property value appears in both the English and Danish published content.
+
+## Structure vs. Block Level Variance
+
+The Block Editor structure is _invariant_ for Block Level Variance. This means that the structure follows the same rules for invariance as outlined in the section above.
+
+In other words: If an editor changes the order of the Blocks in one Document variant, it changes for all Document variants. The change is applied to all published Document variants, as soon as one or more variants are published.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-list-editor.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-list-editor.md
new file mode 100644
index 00000000000..4cc0075e30f
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-list-editor.md
@@ -0,0 +1,248 @@
+# Block List
+
+`Schema Alias: Umbraco.BlockList`
+
+`UI Alias: Umb.PropertyEditorUi.BlockList`
+
+`Returns: IEnumerable`
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+**Block List** is a list editing property editor, using [Element Types](../../../../data/defining-content/#element-types) to define the list item schema.
+
+{% hint style="info" %}
+The _Block List_ replaces the obsolete _Nested Content_ editor.
+{% endhint %}
+
+## Configure Block List
+
+The Block List property editor is configured in the same way as any standard property editor, via the _Data Types_ admin interface.
+
+To set up your Block List Editor property, create a new _Data Type_ and select **Block List** from the list of available property editors.
+
+Then you will see the configuration options for a Block List as shown below.
+
+
+
+The Data Type editor allows you to configure the following properties:
+
+* **Available Blocks** - Here you will define the Block Types to be available for use in the property. Read more on how to set up Block Types below.
+* **Amount** - Sets the minimum and/or maximum number of blocks that should be allowed in the list.
+* **Single block mode** - When in Single block mode, the output will be `BlockListItem<>` instead of `BlockListModel`
+* **Live editing mode** - Enabling this will make editing of a block happening directly to the document model, making changes appear as you type.
+* **Inline editing mode** - Enabling this will change editing experience to inline, meaning that editing the data of blocks happens at sight as accordions.
+* **Property editor width** - Overwrite the width of the property editor. This field takes any valid css value for "max-width".
+
+## Setup Block Types
+
+Block Types are **Element Types** which need to be created before you can start configuring them as Block Types. This can be done either directly from the property editor setup process, or you can set them up beforehand and add them to the block list after.
+
+Once you have added an element type as a Block Type on your Block List Data Type you will have the option to configure it further.
+
+
+
+Each Block has a set of properties that are optional to configure. They are described below.
+
+### Editor Appearance
+
+By configuring the properties in the group you can customize the user experience for your content editors when they work with the blocks in the Content section.
+
+* **Label** - Define a label for the appearance of the Block in the editor. The label uses [Umbraco Flavoured Markdown](../../../../../reference/umbraco-flavored-markdown.md) to display values of properties.
+* **Overlay editor size** - Set the size for the Content editor overlay for editing this block.
+
+### Data Models
+
+It is possible to use two separate Element Types for your Block Types. Its required to have one for Content and optional to add one for Settings.
+
+* **Content model** - This presents the Element Type used as model for the content section of this Block. This cannot be changed, but you can open the Element Type to perform edits or view the properties available. Useful when writing your Label.
+* **Settings model** - Add a Settings section to your Block based on a given Element Type. When picked you can open the Element Type or choose to remove the settings section again.
+
+### Catalogue appearance
+
+These properties refer to how the Block is presented in the Block catalogue, when editors choose which Blocks to use for their content.
+
+* **Background color** - Define a background color to be displayed beneath the icon or thumbnail. Eg. `#424242`.
+* **Icon color** - Change the color of the Element Type icon. Eg. `#242424`.
+* **Thumbnail** - Pick an image or SVG file to replace the icon of this Block in the catalogue.
+
+The thumbnails for the catalogue are presented in the format of 16:10, and we recommend a resolution of 400px width and 250px height.
+
+### Advanced
+
+These properties are relevant when you work with custom views.
+
+* **Force hide content editor** - If you made a custom view that enables you to edit the content part of a block and you are using default editing mode (not inline) you might want to hide the content-editor from the block editor overlay.
+
+## Editing Blocks
+
+When viewing a **Block List** editor in the Content section for the first time, you will be presented with the option to Add content.
+
+
+
+Clicking the Add content button brings up the Block Catalogue.
+
+
+
+The Block Catalogue looks different depending on the amount of available Blocks and their catalogue appearance.
+
+
+
+Click the Block Type you wish to create and a new Block will appear in the list.
+
+Depending on whether your Block List Editor is setup to use default or inline editing mode you will see one of the following things happening:
+
+In default mode you will enter the editing overlay of that Block:
+
+
+
+In inline editing mode the new Blocks will expand to show its inline editor:
+
+
+
+More Blocks can be added to the list by clicking the Add content button or using the inline Add content button that appears on hover between or above existing Blocks.
+
+
+
+To reorder the Blocks, click and drag a Block up or down to place in the desired order.
+
+To delete a Block click the trash-bin icon appearing on hover.
+
+## Rendering Block List Content
+
+Rendering the stored value of your **Block List** property can be done in two ways.
+
+### 1. Default rendering
+
+You can choose to use the built-in rendering mechanism for rendering blocks via a Partial View for each block.
+
+The default rendering method is named `GetBlockListHtml()` and comes with a few options to go with it. The typical use could be:
+
+```csharp
+@Html.GetBlockListHtml(Model, "MyBlocks")
+```
+
+"MyBlocks" above is the alias for the Block List editor.
+
+If using ModelsBuilder the example can be simplified:
+
+Example:
+
+```csharp
+@Html.GetBlockListHtml(Model.MyBlocks)
+```
+
+To make this work you will need to create a Partial View for each block, named by the alias of the Element Type that is being used as Content Model.
+
+These partial views must be placed in this folder: `Views/Partials/BlockList/Components/`. Example: `Views/Partials/BlockList/Components/MyElementTypeAliasOfContent.cshtml`.
+
+A Partial View will receive the model of `Umbraco.Core.Models.Blocks.BlockListItem`. This gives you the option to access properties of the Content and Settings section of your Block.
+
+In the following example of a Partial view for a Block Type, please note that the `MyElementTypeAliasOfContent`and `MyElementTypeAliasOfSettings` should correspond with the selected Element Type Alias for the given model in your case.
+
+Example:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+@{
+ var content = (ContentModels.MyElementTypeAliasOfContent)Model.Content;
+ var settings = (ContentModels.MyElementTypeAliasOfSettings)Model.Settings;
+}
+
+// Output the value of field with alias 'heading' from the Element Type selected as Content section
+
@content.Value("heading")
+```
+
+With ModelsBuilder:
+
+```csharp
+// Output the value of field with alias 'heading' from the Element Type selected as Content section
+
@content.Heading
+```
+
+### 2. Build your own rendering
+
+A built-in value converter is available to use the data as you like. Call the `Value` method with a generic type of `IEnumerable` and the stored value will be returned as a list of `BlockListItem` entities.
+
+Example:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
+@using Umbraco.Cms.Core.Models.Blocks;
+@{
+ var blocks = Model.Value>("myBlocksProperty");
+ foreach (var block in blocks)
+ {
+ var content = block.Content;
+
+ @Html.Partial("MyFolderOfBlocks/" + content.ContentType.Alias, block)
+ }
+}
+```
+
+Each item is a `BlockListItem` entity that contains two main properties `Content` and `Settings`. Each of these is a `IPublishedElement` which means you can use all the value converters you are used to using.
+
+Example:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+@using Umbraco.Cms.Core.Models.Blocks;
+@{
+ var blocks = Model.Value>("myBlocksProperty");
+ foreach (var block in blocks)
+ {
+ var content = (ContentModels.MyAliasOfContentElementType)block.Content;
+ var settings = (ContentModels.MyAliasOfSettingsElementType)block.Settings;
+
+
@content.MyExampleHeadlinePropertyAlias
+ }
+}
+```
+
+## Extract Block List Content data
+
+In some cases, you might want to use the Block List Editor to hold some data and not necessarily render a view since the data should be presented in different areas on a page. An example could be a product page with variants stored in a Block List Editor.
+
+In this case, you can extract the variant's data using the following, which returns `IEnumerable`.
+
+Example:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+@using Umbraco.Cms.Core.Models.Blocks;
+@{
+ var variants = Model.Value>("variants").Select(x => x.Content);
+ foreach (var variant in variants)
+ {
+
@variant.Value("variantName")
+
@variant.Value("description")
+ }
+}
+```
+
+If using ModelsBuilder the example can be simplified:
+
+Example:
+
+```csharp
+@inherits Umbraco.Web.Mvc.UmbracoViewPage
+@using ContentModels = Umbraco.Web.PublishedModels;
+@{
+ var variants = Model.Variants.Select(x => x.Content).OfType();
+ foreach (var variant in variants)
+ {
+
@variant.VariantName
+
@variant.Description
+ }
+}
+```
+
+If you know the Block List Editor only uses a single block, you can cast the collection to a specific type `T` using `.OfType()` otherwise the return value will be `IEnumerable`.
+
+## Build a Custom Backoffice View
+
+Building Custom Views for Block representations in Backoffice is the same for all Block Editors. [Read about building a Custom View for Blocks here](../../../../../customizing/extending-overview/extension-types/block-custom-view.md)
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-1.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-1.png
new file mode 100644
index 00000000000..437c13e81e8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-1.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-2.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-2.png
new file mode 100644
index 00000000000..e20614bac8a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-2.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-3.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-3.png
new file mode 100644
index 00000000000..35b5a386e49
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/images/block-level-variance-3.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/checkbox-list.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/checkbox-list.md
new file mode 100644
index 00000000000..c9b965db5c3
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/checkbox-list.md
@@ -0,0 +1,113 @@
+# Checkbox List
+
+`Schema Alias: Umbraco.CheckBoxList`
+
+`UI Alias: Umb.PropertyEditorUi.CheckBoxList`
+
+`Returns: IEnumerable`
+
+Displays a list of preset values as a list of checkbox controls. The text saved is an IEnumerable collection of the text values.
+
+{% hint style="info" %}
+Unlike other property editors, the Option IDs are not directly accessible in Razor.
+{% endhint %}
+
+## Data Type Definition Example
+
+
+
+{% hint style="info" %}
+You can use dictionary items to translate the options in a Checkbox List property editor in a multilingual setup. For more details, see the [Creating a Multilingual Site](../../../../tutorials/multilanguage-setup.md#translating-multi-value-property-editors) article.
+{% endhint %}
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (Model.HasValue("superHeros"))
+ {
+
+ @foreach (var item in Model.Value>("superHeros"))
+ {
+
@item
+ }
+
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ if (Model.SuperHeros.Any())
+ {
+
+ @foreach (var item in Model.SuperHeros)
+ {
+
@item
+ }
+
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@inject IContentService Services;
+@using Umbraco.Cms.Core.Serialization
+@using Umbraco.Cms.Core.Services;
+@inject IJsonSerializer Serializer;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'superHeros'.
+ content.SetValue("superHeros", Serializer.Serialize(new[] { "Umbraco", "CodeGarden"}));
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@using Umbraco.Cms.Core.PublishedCache;
+@{
+
+// Set the value of the property with alias 'superHeros'
+content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor,x => x.SuperHeros).Alias, Serializer.Serialize(new[] { "Umbraco", "CodeGarden"}));
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/collection.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/collection.md
new file mode 100644
index 00000000000..89b88a394a6
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/collection.md
@@ -0,0 +1,116 @@
+# Collection
+
+`Schema Alias: Umbraco.ListView`
+
+`UI Alias: Umb.PropertyEditorUi.Collection`
+
+`Returns: IEnumerable`
+
+**Collection** displays a collection of categories when it is enabled on a Document Type with children.
+
+
+
+## Configure Collection
+
+Once Collections are configured, the parent content item displays its child items in a list view format within the content item itself. If Collections are not configured, the child items are displayed directly in the Content Tree, rather than being grouped within the parent content item.
+
+
+
+## Settings
+
+
+
+### Columns Displayed
+
+It is possible to add more columns to the collection, via adding the properties through the picker modal. These properties are based on the Data Types which are used by the Document Type. The properties will listed for selection.
+
+
+
+Once you have selected a column you want to display, define what its heading label should be and what kind of value it should display. You can also move the headers around, re-ordering how they should look. This is done by the move icon on the left side of the alias.
+
+The template section is where you define what kind of value you want to display. The value of the column is in the `value` variable.
+
+### Layouts
+
+Collection comes with two layouts by default. A list and a grid view. These views can be disabled if you are not interested in any of them.
+
+{% hint style="info" %}
+A minimum of one layout needs to be enabled for Collection to work.
+{% endhint %}
+
+You can also make your own layout and add it to the settings. For example, if you wanted to change the width or length of the grid, you will be able to do so.
+
+### Order By
+
+Will sort your collection by the selection you choose in the dropdown. By default it selects "Last edited" and you get the following three columns:
+
+* **Last edited** - When the content node was last edited and saved.
+* **Name** - Name of the content node(s).
+* **Created by** - This is the user who the content node was created by.
+
+You can add more sorting to this collection by adding more datatypes to the columns in the "Columns Displayed" section.
+
+### Order Direction
+
+You can select order of the content nodes displayed, "Ascending [a-z]" or "Descending [z-a]". The order is affected by the "Order By" selection.
+
+### Page Size
+
+Defines how many child content nodes you want to see per page. This will limit how many content items you will see in your collection. If you set it to 5, then only 5 content items will be shown in the collection.
+
+### Workspace View icon
+
+{% hint style="info" %}
+Support for changing the Workspace View icon has not been implemented yet.
+{% endhint %}
+
+Changes the icon in the backoffice of the collection. By default it will look like the image below.
+
+
+
+### Workspace View name
+
+{% hint style="info" %}
+Support for changing the Workspace View name has not been implemented yet.
+{% endhint %}
+
+You can change the name of the collection itself. Default if empty: 'Child Items'.
+
+### Show Content Workspace View First
+
+{% hint style="info" %}
+Support for setting the Content Workspace View First has not been implemented yet.
+{% endhint %}
+
+Enable this to show the Content Workspace View by default instead of the collection's.
+
+## Content Example
+
+### Generic field value
+
+This example shows how to use a generic field from a child item and display its value in a collection.
+
+
+
+You can use the [Umbraco Flavored Markdown](../../../../reference/umbraco-flavored-markdown.md) syntax to display the label value. Here, the `{=value}` placeholder retrieves the value of the *Email* property and displays it in the collection, as shown in the image below:
+
+
+
+### Content name
+
+First, a Content Picker property needs to be present on the content item. In this example, the `child item` has gotten a Content Picker Data Type with the alias of `contentPicker`.
+
+
+
+The child item has a document and the value that should be displayed is the name of the picked value. The next step is to reconfigure the template value in the collection setting.
+
+
+
+This will take the value picked up by the content picker.
+
+
+
+And display it in the collection. Shown in the example below:
+
+
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/color-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/color-picker.md
new file mode 100644
index 00000000000..f6399f438bd
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/color-picker.md
@@ -0,0 +1,132 @@
+# Color Picker
+
+`Schema Alias: Umbraco.ColorPicker`
+
+`UI Alias: Umb.PropertyEditorUi.ColorPicker`
+
+`Returns: String (Hexadecimal)`
+
+`Returns: Umbraco.Cms.Core.PropertyEditors.ValueConverters.ColorPickerValueConverter.PickedColor (When using labels)`
+
+The Color picker allows you to set some predetermined colors that the editor can choose between.
+
+It is possible to add a label to use with the color.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## Example with Modelsbuilder
+
+```csharp
+@{
+ // Model has a property called "Color" which holds a Color Picker editor
+ var hexColor = Model.Color;
+ // Define the label if you've included it
+ String colorLabel = Model.Color.Label;
+
+ if (hexColor != null)
+ {
+
@colorLabel
+ }
+}
+```
+
+## Example without Modelsbuilder
+
+```csharp
+@using Umbraco.Cms.Core.PropertyEditors.ValueConverters
+@{
+ // Model has a property called "Color" which holds a Color Picker editor
+ var hexColor = Model.Value("Color");
+ // Define the label if you've included it
+ var colorLabel = Model.Value("Color").Label;
+
+ if (hexColor != null)
+ {
+
@colorLabel
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+### Without labels
+
+```csharp
+@inject IContentService Services;
+@using Umbraco.Cms.Core.Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'color'.
+ // The value set here, needs to be one of the colors on the Color Picker
+ content.SetValue("color", "38761d");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+### With labels
+
+```csharp
+@inject IContentService Services;
+@using Umbraco.Cms.Core.Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'color'.
+ // The value set here, needs to be one of the colors on the Color Picker
+ content.SetValue("color", "{'value':'000000', 'label':'Black', 'sortOrder':1, 'id':'1'}");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@using Umbraco.Cms.Core.PublishedCache;
+@{
+ // Set the value of the property with alias 'color'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Color).Alias, "38761d");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/content-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/content-picker.md
new file mode 100644
index 00000000000..59f53d6e103
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/content-picker.md
@@ -0,0 +1,291 @@
+# Content Picker
+
+`Schema Alias: Umbraco.ContentPicker`
+
+`UI Alias: Umb.PropertyEditorUi.DocumentPicker`
+
+`Returns: IEnumerable`
+
+The Content Picker enables choosing the type of content tree to display and which specific part to render. It also allows you to set a dynamic root node for the content based on the current document using the Content Picker.
+
+{% hint style="info" %}
+The Content Picker was formerly known as the **Multinode Treepicker** in version 13 and below.
+
+The renaming is purely a client-side UI change, meaning the property editor still uses the `Umbraco.MultiNodeTreePicker` schema alias.
+
+The change was made as the word **Content** in the backoffice acts as an umbrella term covering Documents, Media, and Members.
+
+**Are you looking for the original Content Picker?**
+
+The Content Picker from version 13 and below has been renamed [Document Picker](document-picker.md).
+{% endhint %}
+
+## Data Type Definition Example
+
+
+
+### Minimum/maximum number of items
+
+Define a limit on the number of items allowed to be selected.
+
+### Ignore user start nodes
+
+Checking this field allows users to choose nodes they normally cannot access.
+
+### Node Type
+
+This option allows for configuring what type of content is available when using the Data Type. The available types of content are Content, Members, or Media items.
+
+When selecting Content from the dropdown, the option to specify a root node, also called the **origin**, becomes available.
+
+
The option to specify a root node also called the "origin" becomes available when Content is selected as the Node Type.
+
+
+
+When picking the **origin** there are several different options available:
+
+
The available options for setting a root node (origin) for the Content Picker.
+
+The following options are available when picking the origin:
+
+* **Root**: The root is the first level item of the sub-tree of the current node.
+* **Parent**: The parent is the nearest ancestor of the current node.
+* **Current**: The current node.
+ * A picker that uses the current node, cannot pick anything when the current node is created, as it will not have any children.
+* **Site**: The nearest ancestor of the current node with a domain assigned.
+* **Specific node**: A specific node selected from the existing content.
+
+When an origin has been specified, it becomes possible to continue to build a _Dynamic Root_ by adding additional query steps.
+
+Navigate the content tree relative to the specified origin to execute multiple query steps and find the root node needed.
+
+
+
+The following options are available:
+
+* **Nearest Ancestor or Self:** Find the nearest ancestor or current item that fits with one of the configured Document Types.
+* **Furthest Ancestor or Self:** Find the furthest ancestor or current item that fits with one of the configured Document Types.
+* **Nearest Descendant or Self:** Find the nearest descendant or current item that fits with one of the configured Document Types.
+* **Furthest Descendant or Self:** Find the furthest descendant or current item that fits with one of the configured Document Types.
+
+The options above are all based on navigating the document hierarchy by locating ancestors and descendants. It is possible to execute **custom steps** to build even more complex queries. Once a custom query is available it will be added to the bottom of the _Append steps to query_ dialog. Learn more about [adding custom query steps in the section below](content-picker.md#adding-a-custom-query-step).
+
+Each query step takes the output from the origin or the previous step as input. It is only ever the result of the last query step that is passed to the next step.
+
+
+
+#### Adding a custom query step
+
+Custom query steps can be used to solve specific use cases, such as traversing sibling documents or matching property values. Before the custom query steps can be selected in the Data Type settings, they must be defined via code.
+
+When implementing a query step it requires a collection of origins and information about the query step. The collection is taken from where the name specified in the UI can be found.
+
+{% hint style="warning" %}
+**Specifying the origin is required** for the custom query step to become available.
+
+Read the [Node Type section](content-picker.md#node-type) above to learn more about this.
+{% endhint %}
+
+You can inject dependencies into the constructor. These dependencies could be custom repositories or the `IVariationContextAccessor`, if you want to use the current culture.
+
+The `ExecuteAsync` method receives a set of content keys from the last executed query step or the origin. It has to return a new set of content keys.
+
+```csharp
+public class MyCustomDynamicRootQueryStep : IDynamicRootQueryStep
+{
+ private readonly IMyCustomRepository _myCustomRepository;
+
+ public MyCustomDynamicRootQueryStep(IMyCustomRepository myCustomRepository)
+ {
+ _myCustomRepository = myCustomRepository;
+ }
+
+ // The string below is what you specify in the UI to execute this custom query step.
+ public virtual string SupportedDirectionAlias { get; set; } = "MyCustomStep";
+
+ public async Task>> ExecuteAsync(ICollection origins, DynamicRootQueryStep filter)
+ {
+ if (filter.Alias != SupportedDirectionAlias)
+ {
+ return Attempt>.Fail();
+ }
+
+ if (origins.Any() is false)
+ {
+ return Attempt>.Succeed(Array.Empty());
+ }
+
+ // Replace the following with your custom logic
+ var result = await _myCustomRepository.GetWhateverIWantAsync(origins);
+
+ return Attempt>.Succeed(result);
+ }
+}
+```
+
+To register the custom query step, append it to the existing query steps, `DynamicRootSteps()`. This is done from a composer as shown below.
+
+```csharp
+public class CustomQueryStepComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.DynamicRootSteps().Append();
+ }
+}
+```
+
+Finally, register the custom query step on the client side and provide a brief description.
+
+You can do this in an `umbraco-package.json` file, as shown below:
+
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My.Test.Extension",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "dynamicRootQueryStep",
+ "alias": "Umb.DynamicRootQueryStep.MyCustomStep",
+ "name": "Dynamic Root Query Step: My Custom Step",
+ "meta": {
+ "queryStepAlias": "MyCustomStep",
+ "label": "My Custom Step",
+ "description": "My custom step description.",
+ "icon": "icon-coffee"
+ },
+ "weight": 0
+ }
+ ]
+}
+```
+
+### Allow items of type
+
+Choose which types of content should be available to pick using the Content Picker.
+
+This is done by selecting one or more Document Types.
+
+## Query Example
+
+Consider the following tree structure where the Document Type alias is presented in square brackets.
+
+* Codegarden
+ * 2023 \[`year`]
+ * Talks \[`talks`]
+ * ...
+ * Umbraco anno MMXXIII \[`talk`]
+ * Stages \[`stages`]
+ * Social Space \[`stage`]
+ * No 10 \[`stage`]
+ * No 16 \[`stage`]
+ * The Theatre \[`stage`]
+ * 2022 \[`year`]
+ * Talks \[`talks`]
+ * ...
+ * Stages \[`stages`]
+ * Main Stage \[`stage`]
+ * The Barn \[`stage`]
+ * The Theatre \[`stage`]
+
+Consider configuring a Content Picker on the `talk` Document Type to select a `stage` for the `talk`. Here, you want to display only the stages for the actual year. To do this, you need to set the parent as the origin.
+
+For instance, if you are on the `Umbraco anno MMXXIII` node, the collection of content keys passed into the first query step will only contain the `Talks` content node.
+
+* First, query for the nearest ancestors of the type `year`. This will return `2023`.
+* Second, query for the nearest descendants of the type `stages`.
+
+When opening the picker on the `Umbraco anno MMXXIII` node, it will now show the children of the node on the path `Codegarden > 2023 > Stages`.
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ var typedContentPicker = Model.Value>("featuredArticles");
+ if (typedContentPicker != null) {
+ foreach (var item in typedContentPicker)
+ {
+
@item.Name
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ var typedContentPicker = Model.FeaturedArticles;
+ foreach (var item in typedContentPicker)
+ {
+
@item.Name
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update the value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@inject IContentService Services;
+@using Umbraco.Cms.Core;
+@using Umbraco.Cms.Core.Services
+
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Get the pages you want to assign to the Content Picker
+ var page = Umbraco.Content("665d7368-e43e-4a83-b1d4-43853860dc45");
+ var anotherPage = Umbraco.Content("1f8cabd5-2b06-4ca1-9ed5-fbf14d300d59");
+
+ // Create Udi's of the pages
+ var pageUdi = Udi.Create(Constants.UdiEntityType.Document, page.Key);
+ var anotherPageUdi = Udi.Create(Constants.UdiEntityType.Document, anotherPage.Key);
+
+ // Create a list of the page udi's
+ var udis = new List{pageUdi.ToString(), anotherPageUdi.ToString()};
+
+ // Set the value of the property with alias 'featuredArticles'.
+ content.SetValue("featuredArticles", string.Join(",", udis));
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@using Umbraco.Cms.Core.PublishedCache;
+
+@{
+ // Set the value of the property with alias 'featuredArticles'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor ,x => x.FeaturedArticles).Alias, string.Join(",", udis));
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time.md
new file mode 100644
index 00000000000..d566af2ee51
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time.md
@@ -0,0 +1,87 @@
+# DateTime
+
+`Schema Alias: Umbraco.DateTime`
+
+`UI Alias: Umb.PropertyEditorUi.DatePicker`
+
+`Returns: DateTime`
+
+Displays a calendar UI for selecting dates which are saved as a DateTime value.
+
+## Data Type Definition Example
+
+
+
+There is one setting available for manipulating the DateTime property.
+
+The setting involves defining the format. The default date format in the Umbraco backoffice is `YYYY-MM-DD HH:mm:ss`, but you can change it to a different format. See [MomentJS.com](https://momentjs.com/) for the supported formats.
+
+## Content Example
+
+
+
+## MVC View Example - displays a datetime
+
+### With Modelsbuilder
+
+```csharp
+@Model.DatePicker
+```
+
+### Without Modelsbuilder
+
+```csharp
+@Model.Value("datePicker")
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@inject IContentService Services;
+@using Umbraco.Cms.Core.Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'datePicker'
+ content.SetValue("datePicker", DateTime.Now);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+
+ // Set the value of the property with alias 'datePicker'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.DatePicker).Alias, DateTime.Now);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date.md
new file mode 100644
index 00000000000..f570390121e
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date.md
@@ -0,0 +1,39 @@
+# Date
+
+`Schema Alias: Umbraco.DateTime`
+
+`UI Alias: Umb.PropertyEditorUi.DatePicker`
+
+`Returns: Date`
+
+Displays a calendar UI for selecting dates which are saved as a DateTime value.
+
+## Data Type Definition Example
+
+
+
+The only setting that is available for manipulating the Date property is to set a format. By default the format of the date in the Umbraco backoffice will be `YYYY-MM-DD`, but you can change this to something else. See [MomentJS.com](https://momentjs.com/) for the supported formats.
+
+## Content Example
+
+
+
+## MVC View Example - displays a datetime
+
+### Typed
+
+```csharp
+@(Model.Content.GetPropertyValue("datePicker").ToString("dd MM yyyy"))
+```
+
+### Dynamic (Obsolete)
+
+{% hint style="warning" %}
+See [Common pitfalls](../../../../reference/common-pitfalls.md) for more information about why the dynamic approach is obsolete.
+{% endhint %}
+
+```csharp
+@{
+ @CurrentPage.datePicker.ToString("dd-MM-yyyy")
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/decimal.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/decimal.md
new file mode 100644
index 00000000000..069f5f13722
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/decimal.md
@@ -0,0 +1,86 @@
+# Decimal
+
+`Schema Alias: Umbraco.Decimal`
+
+`UI Alias: Umb.PropertyEditorUi.Decimal`
+
+`Returns: decimal`
+
+## Data Type Definition Example
+
+
+
+In the example above the possible values for the input field would be \[8, 8.5, 9, 9.5, 10]
+
+_All other values will be removed in the content editor when saving or publishing._
+
+If the value of **Step Size** is not set then all decimal values between 8 and 10 is possible to input in the content editor.
+
+## Content Example
+
+
+
+## MVC View Example
+
+### With Modelsbuilder
+
+```csharp
+@Model.MyDecimal
+```
+
+### Without Modelsbuilder
+
+```csharp
+@Model.Value("MyDecimal")
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@inject IContentService Services;
+@using Umbraco.Cms.Core.Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'myDecimal'.
+ content.SetValue("myDecimal", 3);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@using Umbraco.Cms.Core.PublishedCache;
+@{
+ // Set the value of the property with alias 'myDecimal'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.MyDecimal).Alias, 3);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/document-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/document-picker.md
new file mode 100644
index 00000000000..cf312983c59
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/document-picker.md
@@ -0,0 +1,111 @@
+# Document Picker
+
+`Schema Alias: Umbraco.ContentPicker`
+
+`UI Alias: Umb.PropertyEditorUi.DocumentPicker`
+
+`Returns: IPublishedContent`
+
+The Document Picker opens a panel to pick a specific page from the content structure. The value saved is the selected nodes [UDI](../../../../reference/querying/udi-identifiers.md).
+
+{% hint style="info" %}
+The Document Picker was formerly known as the **Content Picker** in version 13 and below.
+
+The renaming is purely a client-side UI change, meaning the property editor still uses the `Umbraco.ContentPicker` schema alias.
+
+The change was made as the word **Content** in the backoffice acts as an umbrella term covering the terms Document, Media, and Member.
+{% endhint %}
+
+## Data Type Definition Example
+
+
+
+## Document Picker Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ IPublishedContent typedContentPicker = Model.Value("featurePicker");
+ if (typedContentPicker != null)
+ {
+
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Get the page you want to assign to the document picker
+ var page = Umbraco.Content("665d7368-e43e-4a83-b1d4-43853860dc45");
+
+ // Create an Udi of the page
+ var udi = Udi.Create(Constants.UdiEntityType.Document, page.Key);
+
+ // Set the value of the property with alias 'featurePicker'.
+ content.SetValue("featurePicker", udi.ToString());
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@using Umbraco.Cms.Core;
+
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'featurePicker'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.FeaturePicker).Alias, udi.ToString());
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/dropdown/README.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/dropdown/README.md
new file mode 100644
index 00000000000..965dfd2afe5
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/dropdown/README.md
@@ -0,0 +1,139 @@
+# Dropdown
+
+`Schema Alias: Umbraco.DropDown.Flexible`
+
+`UI Alias: Umb.PropertyEditorUi.Dropdown`
+
+`Returns: String` or `IEnumerable`
+
+Displays a list of preset values. Either a single value or multiple values (formatted as a collection of strings) can be returned.
+
+## Settings
+
+### Enable multiple choice
+
+If enabled, editors will be able to select multiple values from the dropdown otherwise only a single value can be selected.
+
+### Add options
+
+Options are the values which are shown in the dropdown list. You can add, edit, or remove values here.
+
+{% hint style="info" %}
+You can use dictionary items to translate the options in a Dropdown property editor in a multilingual setup. For more details, see the [Creating a Multilingual Site](../../../../../tutorials/multilanguage-setup.md#translating-multi-value-property-editors) article.
+{% endhint %}
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+### Single Value
+
+
+
+### Multiple Values
+
+
+
+## MVC View Example
+
+### Single item - without Modelsbuilder
+
+```csharp
+@if (Model.HasValue("category"))
+{
+
@(Model.Value("category"))
+}
+```
+
+### Multiple items - without Modelsbuilder
+
+```csharp
+@if (Model.HasValue("categories"))
+{
+ var categories = Model.Value>("categories");
+
+ @foreach (var category in categories)
+ {
+
@category
+ }
+
+}
+```
+
+### Single item - with Modelsbuilder
+
+```csharp
+@if (!Model.HasValue(Model.Category))
+{
+
+ @foreach (var category in Model.Categories)
+ {
+
@category
+ }
+
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@using Umbraco.Cms.Core.Serialization
+@inject IJsonSerializer Serializer;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'categories'.
+ content.SetValue("categories", Serializer.Serialize(new[] { "News" }));
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'categories'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Categories).Alias, Serializer.Serialize(new[] { "News" }));
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/email-address.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/email-address.md
new file mode 100644
index 00000000000..73085cfc942
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/email-address.md
@@ -0,0 +1,79 @@
+---
+description: In this article you can learn how to use the build in email property editor
+---
+
+# Email Address
+
+`Schema Alias: Umbraco.EmailAddress`
+
+`UI Alias: Umb.PropertyEditorUi.EmailAddress`
+
+`Returns: String`
+
+Displays an email address.
+
+## Settings
+
+The Email Address Property Editor does not come with any further configuration. The property can be configured once it has been added to a Document Type.
+
+
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@if (Model.HasValue("email"))
+{
+ var emailAddress = Model.Value("email");
+
+}
+```
+
+## Add value programmatically
+
+See the example below to learn how a value can be added or changed programmatically to an Email-address property. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of your page
+ var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
+
+ // Get the page using the GUID you've just defined
+ var content = contentService.GetById(guid);
+ // Set the value of the property with alias 'email'
+ content.SetValue("email", "jpk@umbraco.dk");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+{% hint style="info" %}
+The value sent to an EmailAddress property needs to be a correct email address, For example: [name@domain.com](mailto:name@domain.com).
+
+It is recommended that you set up validation on this property, in order to verify whether the value added is in the correct format.
+{% endhint %}
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/eye-dropper-color-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/eye-dropper-color-picker.md
new file mode 100644
index 00000000000..38430db5703
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/eye-dropper-color-picker.md
@@ -0,0 +1,97 @@
+# Eye Dropper Color Picker
+
+`Schema Alias: Umbraco.ColorPicker.EyeDropper`
+
+`UI Alias: Umb.PropertyEditorUi.EyeDropper`
+
+`Returns: string`
+
+The Eye Dropper Color picker allows you to choose a color from the full color spectrum using HEX and RGBA.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## Example with Modelsbuilder
+
+```csharp
+@{
+ var color = Model.Color?.ToString();
+
+ if (color != null)
+ {
+
+ }
+}
+```
+
+## Example without Modelsbuilder
+
+```csharp
+@{
+ var color = Model.Value("Color");
+
+ if (color != null)
+ {
+
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'color'.
+ content.SetValue("color", "#6fa8dc");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'color'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Color).Alias, "#6fa8dc");
+
+ // Set the value of the property with alias 'theme'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Theme).Alias, "rgba(111, 168, 220, 0.7)");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/file-upload.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/file-upload.md
new file mode 100644
index 00000000000..962846a7b68
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/file-upload.md
@@ -0,0 +1,143 @@
+# File Upload
+
+`Schema Alias: Umbraco.UploadField`
+
+`UI Alias: Umb.PropertyEditorUi.UploadField`
+
+`Returns: string`
+
+Adds an upload field, which allows documents or images to be uploaded to Umbraco.
+
+You can define which file types should be accepted through the upload field.
+
+{% hint style="info" %}
+For uploading and adding files and images to your Umbraco project, we recommend using the Media Picker.
+
+Find the full documentation for the property in the [Media Picker](media-picker-3.md) article.
+{% endhint %}
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+ 
+
+In code, the property is a string, which references the location of the file.
+
+Example: `"/media/o01axaqu/guidelines-on-remote-working.pdf"`
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@using System.IO;
+@{
+ if (Model.HasValue("myFile"))
+ {
+ var myFile = Model.Value("myFile");
+
+ @System.IO.Path.GetFileName(myFile)
+ }
+
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@if (!Model.HasValue(Model.MyFile))
+{
+ @System.IO.Path.GetFileName(Model.MyFile)
+}
+```
+
+## Add values programmatically
+
+{% hint style="info" %}
+The samples in this section have not been verified against the latest version of Umbraco.
+
+Instead, we recommend using the [Media Picker](media-picker-3.md) for uploading files to your Umbraco website.
+{% endhint %}
+
+See the example below to see how a value can be added or changed programmatically. To update a value of this property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html) and the [Media Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.MediaService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.IO
+@using Umbraco.Cms.Core.Serialization
+@using Umbraco.Cms.Core.Strings
+@inject MediaFileManager _mediaFileManager;
+@inject IShortStringHelper _shortStringHelper;
+@inject IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
+@inject IContentService Services;
+@inject IJsonSerializer _serializer;
+@inject MediaUrlGeneratorCollection _mediaUrlGeneratorCollection;
+
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Get access to MediaService
+ var mediaService = MediaService;
+
+ // Create a variable for the GUID of the parent where you want to add a child item
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Create a variable for the file you want to upload, in this case the Our Umbraco logo
+ var imageUrl = "https://our.umbraco.com/assets/images/logo.svg";
+
+ // Create a request to get the file
+ var request = WebRequest.Create(imageUrl);
+ var webResponse = request.GetResponse();
+ var responseStream = webResponse.GetResponseStream();
+
+ // Get the file name
+ var lastIndex = imageUrl.LastIndexOf("/", StringComparison.Ordinal) + 1;
+ var filename = imageUrl.Substring(lastIndex, imageUrl.Length - lastIndex);
+
+ // Create a media file
+ var media = mediaService.CreateMediaWithIdentity("myImage", -1, "File");
+ media.SetValue(_mediaFileManager, _mediaUrlGeneratorCollection, _shortStringHelper, _contentTypeBaseServiceProvider, Constants.Conventions.Media.File, filename, responseStream);
+ // Save the created media
+ mediaService.Save(media);
+
+ // Get the published version of the media (IPublishedContent)
+ var publishedMedia = Umbraco.Media(media.Id);
+
+ // Set the value of the property with alias 'myFile'
+ content.SetValue("myFile", publishedMedia.Url());
+
+ // Save the child item
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'myFile'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.MyFile).Alias, publishedMedia.Url();
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md
new file mode 100644
index 00000000000..5a99d0b7b60
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md
@@ -0,0 +1,243 @@
+# Image Cropper
+
+`Schema Alias: Umbraco.ImageCropper`
+
+`UI Alias: Umb.PropertyEditorUi.ImageCropper`
+
+`Returns: MediaWithCrops`
+
+Returns a path to an image, along with information about focal point and available crops.
+
+When the Image Cropper is used on a Media Type the crops are shared between all usages of a Media Item. This is called **global crops**.
+
+If the Image Cropper is used on a Document Type, the file and crops will be **local** to the Document.
+
+Notice that it is possible make local crops on shared Media Items via the [Media Picker Property Editor](media-picker-3.md).
+
+## Settings
+
+### Define Crops
+
+You can add, edit & delete crop presets the cropper UI can use.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+The Image Cropper provides a UI to upload an image, set a focal point on the image, and use predefined crops.
+
+By default, images in the Image Cropper will be shown based on a set focal point and only use specific crops if they are available.
+
+The Image Cropper comes with 3 modes:
+
+* Uploading an image
+* Setting a focal point
+* Cropping the image to predefined crops
+
+### Uploading images
+
+The editor exposes a drop area for files. Select it to upload an image.
+
+
+
+### Set focal point
+
+By default, the Image Cropper allows the editor to set a focal point on the uploaded image.
+
+All the preset crops are shown to give the editor a preview of what the image will look like on the frontend.
+
+
+
+### Crop and resize
+
+The editor can fit the crop to the image to ensure that the image is presented as intended.
+
+
+
+## Powered by ImageSharp.Web
+
+[ImageSharp.Web](https://sixlabors.com/products/imagesharp-web/) is image processing middleware for ASP.NET.
+
+We bundle this package with Umbraco and you can therefore take full advantage of all its features for resizing and format changing. Learn more about the built in processing commands in [the official ImageSharp documentation](https://docs.sixlabors.com/articles/imagesharp.web/processingcommands.html).
+
+## Sample code
+
+The Image Cropper comes with an API to generate crop URLs. You can also access the raw data directly as a dynamic object.
+
+For rendering a cropped media item, the `.GetCropUrl` is used:
+
+```html
+
+```
+
+The third parameter is `HtmlEncode` and is by default set to true. This means you only need to define the parameter if you want to disable HTML encoding.
+
+### Example to output a "banner" crop from a cropper property with the property alias "customCropper"
+
+```html
+
+```
+
+Or, alternatively using the `MediaWithCrops` extension method:
+
+```html
+
+```
+
+### Example to dynamically create a crop using the focal point - in this case 300 x 400px image
+
+```csharp
+@if (Model.Photo is not null)
+{
+
+}
+```
+
+### CSS background example to output a "banner" crop
+
+Set the `htmlEncode` to false so that the URL is not HTML encoded
+
+```csharp
+@if (Model.Photo is not null)
+{
+ var cropUrl = Url.GetCropUrl(Model.Photo, "square", false);
+
+
+}
+```
+
+## Add values programmatically
+
+To update a content property value you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+The following sample demonstrates how to add or change the value of an Image Cropper property programmatically. The sample creates an API controller with an action, which must be invoked via a POST request to the URL written above the action.
+
+```csharp
+using Microsoft.AspNetCore.Mvc;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.PropertyEditors;
+using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
+using Umbraco.Cms.Core.Serialization;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Docs.Samples.Web.Property_Editors_Add_Values;
+
+[ApiController]
+[Route("/umbraco/api/createimagecroppervalues")]
+public class CreateImageCropperValuesController : Controller
+{
+ private readonly IContentService _contentService;
+ private readonly IMediaService _mediaService;
+ private readonly MediaUrlGeneratorCollection _mediaUrlGeneratorCollection;
+ private readonly IJsonSerializer serializer;
+
+ public CreateImageCropperValuesController(
+ IContentService contentService,
+ IMediaService mediaService,
+ MediaUrlGeneratorCollection mediaUrlGeneratorCollection, IJsonSerializer serializer)
+ {
+ _contentService = contentService;
+ _mediaService = mediaService;
+ _mediaUrlGeneratorCollection = mediaUrlGeneratorCollection;
+ this.serializer = serializer;
+ }
+
+ // /Umbraco/Api/CreateImageCropperValues/CreateImageCropperValues
+ [HttpPost("createimagecroppervalues")]
+ public ActionResult CreateImageCropperValues()
+ {
+ // Create a variable for the GUID of the page you want to update
+ var contentKey = Guid.Parse("89974f8b-e213-4c32-9f7a-40522d87aa2f");
+
+ // Get the page using the GUID you've defined
+ IContent? content = _contentService.GetById(contentKey);
+ if (content == null)
+ {
+ return false;
+ }
+
+ // Create a variable for the GUID of the media item you want to use
+ var mediaKey = Guid.Parse("b6d4e98a-07c0-45f9-bfcc-52994f2806b6");
+
+ // Get the desired media file
+ IMedia? media = _mediaService.GetById(mediaKey);
+ if (media == null)
+ {
+ return false;
+ }
+
+ // Create a variable for the image cropper and set the source
+ var imageCropperValue = new ImageCropperValue
+ {
+ Src = media.GetUrl("umbracoFile", _mediaUrlGeneratorCollection)
+ };
+
+ // Serialize the image cropper value
+ var propertyValue = serializer.Serialize(imageCropperValue);
+
+ // Set the value of the property with alias "cropper"
+ // - remember to add the "culture" parameter if "cropper" is set to vary by culture
+ content.SetValue("cropper", propertyValue);
+
+ return _contentService.Save(content).Success;
+ }
+}
+```
+
+If you use Models Builder to generate source code (modes `SourceCodeAuto` or `SourceCodeManual`), you can use `nameof([generated property name])` to access the desired property without using a magic string:
+
+```csharp
+// Set the value of the "Cropper" property on content of type MyContentType
+// - remember to add the "culture" parameter if "cropper" is set to vary by culture
+content.SetValue(nameof(MyContentType.Cropper).ToFirstLowerInvariant(), propertyValue);
+```
+
+## Get all the crop urls for a specific image
+
+Crop URLs are not limited to usage within a view. `IPublishedContent` has a `GetCropUrl` extension method, which can be used to access crop URLs anywhere.
+
+The following sample demonstrates how to use `GetCropUrl` to retrieve URLs for all crops defined on a specific image:
+
+```csharp
+public Dictionary GetCropUrls(IPublishedContent image)
+{
+ // Get the Image Cropper property value for property with alias "umbracoFile"
+ ImageCropperValue? imageCropperValue = image.Value("umbracoFile");
+ if (imageCropperValue?.Crops == null)
+ {
+ return new Dictionary();
+ }
+
+ // Return all crop aliases and their corresponding crop URLs as a dictionary
+ var cropUrls = new Dictionary();
+ foreach (ImageCropperValue.ImageCropperCrop crop in imageCropperValue.Crops)
+ {
+ // Get the cropped URL and add it to the dictionary that I will return
+ var cropUrl = crop.Alias != null
+ ? image.GetCropUrl(crop.Alias)
+ : null;
+ if (cropUrl != null)
+ {
+ cropUrls.Add(crop.Alias!, cropUrl);
+ }
+ }
+
+ return cropUrls;
+}
+```
+
+## Sample on how to change the format of the image
+
+Below the example to output a PNG using ImageSharp.Web [format](https://docs.sixlabors.com/articles/imagesharp.web/processingcommands.html#format) command.
+
+```html
+
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Checkbox-Data-Type.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Checkbox-Data-Type.png
new file mode 100644
index 00000000000..70eab847d64
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Checkbox-Data-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Color-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Color-Picker-DataType.png
new file mode 100644
index 00000000000..c6ea4a2cd1f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Color-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Document-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Document-Picker-DataType.png
new file mode 100644
index 00000000000..18573dd59d2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Document-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Dropdown-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Dropdown-DataType.png
new file mode 100644
index 00000000000..ea1da4a3cfc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Dropdown-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Eye-Dropper-Color-Picker-Content.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Eye-Dropper-Color-Picker-Content.png
new file mode 100644
index 00000000000..d8ce4de3f88
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Eye-Dropper-Color-Picker-Content.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Eye-Dropper-Color-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Eye-Dropper-Color-Picker-DataType.png
new file mode 100644
index 00000000000..0f1fb36893a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Eye-Dropper-Color-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Label-Setup.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Label-Setup.png
new file mode 100644
index 00000000000..11094fa224c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Label-Setup.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Markdown-Editor-definition-example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Markdown-Editor-definition-example.png
new file mode 100644
index 00000000000..0b4b46160d6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Markdown-Editor-definition-example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Media-picker-dataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Media-picker-dataType.png
new file mode 100644
index 00000000000..0521ffd75db
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Media-picker-dataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/MediaPicker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/MediaPicker-DataType.png
new file mode 100644
index 00000000000..bc6ac25056b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/MediaPicker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Member-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Member-Picker-DataType.png
new file mode 100644
index 00000000000..a0510029d2f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Member-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Member-Picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Member-Picker.png
new file mode 100644
index 00000000000..2f42aa8db1c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Member-Picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Multi-Url-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Multi-Url-Picker-DataType.png
new file mode 100644
index 00000000000..63981d74060
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Multi-Url-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/RadioButton-List-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/RadioButton-List-DataType.png
new file mode 100644
index 00000000000..ec80c6b02c1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/RadioButton-List-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Repeatable-Textstrings-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Repeatable-Textstrings-DataType.png
new file mode 100644
index 00000000000..eda135248f9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Repeatable-Textstrings-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Slider-Data-Type-Definition.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Slider-Data-Type-Definition.png
new file mode 100644
index 00000000000..9620542ac7f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Slider-Data-Type-Definition.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Textarea-Setup.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Textarea-Setup.png
new file mode 100644
index 00000000000..0373a9f3dec
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Textarea-Setup.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Textbox-Setup.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Textbox-Setup.png
new file mode 100644
index 00000000000..75804945088
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/Textbox-Setup.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/User-Picker-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/User-Picker-DataType.png
new file mode 100644
index 00000000000..4edc07b73e6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/User-Picker-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/checkbox-list-setup.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/checkbox-list-setup.png
new file mode 100644
index 00000000000..798ccd419be
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/checkbox-list-setup.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-column-content-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-column-content-picker.png
new file mode 100644
index 00000000000..f0e664a416b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-column-content-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-label-template.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-label-template.png
new file mode 100644
index 00000000000..30d0e0033ec
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-label-template.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-property-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-property-picker.png
new file mode 100644
index 00000000000..375af70dc02
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-property-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-view-cards-content-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-view-cards-content-picker.png
new file mode 100644
index 00000000000..cfb2e51eb9f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collection-view-cards-content-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collections-display-email.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collections-display-email.png
new file mode 100644
index 00000000000..d54e5d4a712
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/collections-display-email.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-example.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-example.png
new file mode 100644
index 00000000000..98474c05999
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-example.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-picker-picked-value.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-picker-picked-value.png
new file mode 100644
index 00000000000..9726d5c05ea
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-picker-picked-value.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-picker-property.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-picker-property.png
new file mode 100644
index 00000000000..a20251e8876
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/content-picker-property.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/date-time.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/date-time.png
new file mode 100644
index 00000000000..260e07b5791
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/date-time.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/emailaddress-datatype.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/emailaddress-datatype.png
new file mode 100644
index 00000000000..6806c536bb2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/emailaddress-datatype.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/enable-listview-v14.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/enable-listview-v14.png
new file mode 100644
index 00000000000..f15477d46b6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/enable-listview-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/file-upload-definition.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/file-upload-definition.png
new file mode 100644
index 00000000000..8fd78917069
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/file-upload-definition.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper-crop.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper-crop.png
new file mode 100644
index 00000000000..de2e956bea5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper-crop.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper-focalpoint.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper-focalpoint.png
new file mode 100644
index 00000000000..8124cc53681
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper-focalpoint.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper.png
new file mode 100644
index 00000000000..786888e25e9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/imageCropper.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/list-view-settings.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/list-view-settings.png
new file mode 100644
index 00000000000..dad410c9d85
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/list-view-settings.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/listview-v14.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/listview-v14.png
new file mode 100644
index 00000000000..63e85069886
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/listview-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/numeric-datatype.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/numeric-datatype.png
new file mode 100644
index 00000000000..359e2787a82
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/numeric-datatype.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/tags-DataType.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/tags-DataType.png
new file mode 100644
index 00000000000..007770a99a3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/images/tags-DataType.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/label.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/label.md
new file mode 100644
index 00000000000..1c9043287aa
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/label.md
@@ -0,0 +1,97 @@
+# Label
+
+`Schema Alias: Umbraco.Label`
+
+`UI Alias: Umb.PropertyEditorUi.Label`
+
+`Returns: String`
+
+Label is a non-editable control and can only be used to display a pre-set value.
+
+## Data Type Definition Example
+
+
+
+### Value type
+
+If you want to set a value other than a String, you can define the data using one of the other available Data Types. These include Decimal, Date/time, Time, Integer, and Big integer.
+
+There is also a Value Type: Long string if you need to set a long string value for your Label.
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without ModelsBuilder
+
+```csharp
+@{
+ if (Model.HasValue("pageLabel")){
+
@(Model.Value("pageLabel"))
+ }
+}
+```
+
+### With ModelsBuilder
+
+```csharp
+@{
+ if (!string.IsNullOrEmpty(Model.PageLabel))
+ {
+
@Model.PageLabel
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@{
+ @inject IContentService Services;
+
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'pageLabel'.
+ content.SetValue("pageLabel", "A pre-set string value");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@{
+ @inject IPublishedSnapshotAccessor _publishedSnapshotAccessor
+
+ // Set the value of the property with alias 'pageLabel'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.MyLabel).Alias, "A Preset string");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/markdown-editor.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/markdown-editor.md
new file mode 100644
index 00000000000..67c298f50f5
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/markdown-editor.md
@@ -0,0 +1,116 @@
+# Markdown Editor
+
+`Schema Alias: Umbraco.MarkdownEditor`
+
+`UI Alias: Umb.PropertyEditorUi.MarkdownEditor`
+
+`Returns: System.Web.HtmlString`
+
+This built-in editor allow the user to use the markdown formatting options, from within a tinyMCE-like interface.
+
+## Data Type Definition Example
+
+
+
+There are three settings available for manipulating the **Markdown editor** property.
+
+* **Preview** toggles if a preview of the markdown should be displayed beneath the editor in the content view.
+* **Default value** is inserted if no content has been saved to the Document Type using this property editor.
+* **Overlay Size** is used to select the width of the link picker overlay in the content view.
+
+## Content Example
+
+
+
+### Explanation of buttons from left to right
+
+| Function | Shortcut | Further explanation |
+| --------------------- | -------- | -------------------------------------- |
+| toggle **bold** text | Ctrl + B | |
+| toggle _italic_ text | Ctrl + I | |
+| insert link | Ctrl + L | This opens the Select Link interface. |
+| toggle quote | Ctrl + Q | |
+| toggle code block | Ctrl + K | |
+| insert image | Ctrl + G | This opens the Select Media interface. |
+| toggle ordered list | Ctrl + O | |
+| toggle unordered list | Ctrl + U | |
+| toggle heading | Ctrl + H | This toggles between h1, h2 and off. |
+| toggle a hr | | |
+| undo | Ctrl + Z | |
+| redo | Ctrl + Y | |
+
+### Other functionality
+
+| Function | Shortcut |
+| ---------- | -------- |
+| select all | Ctrl + A |
+| copy | Ctrl + C |
+| paste | Ctrl + V |
+
+## MVC View Example
+
+### With Modelsbuilder
+
+```csharp
+@Model.MyMarkdownEditor
+```
+
+### Without Modelsbuilder
+
+```csharp
+@Model.Value("MyMarkdownEditor")
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Create markdown value
+ var markdownValue = new HtmlString("#heading \n**strong text**");
+
+ // Set the value of the property with alias 'myMarkdownEditor'.
+ content.SetValue("myMarkdownEditor", markdownValue);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'myMarkdownEditor'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.MyMarkdownEditor).Alias, markdownValue);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/media-picker-3.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/media-picker-3.md
new file mode 100644
index 00000000000..5371ed8c4eb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/media-picker-3.md
@@ -0,0 +1,220 @@
+# Media Picker
+
+`Schema Alias: Umbraco.MediaPicker3`
+
+`UI Alias: Umb.PropertyEditorUi.MediaPicker`
+
+`Returns: IEnumerable` or `MediaWithCrops`
+
+This property editors returns one of the following:
+
+- A collection (`IEnumerable`) if the **Pick multiple items** setting is enabled.
+- A single `MediaWithCrops` item if the **Pick multiple items** setting is disabled.
+
+## Data Type Definition Example
+
+
+
+### Accepted types
+
+Use setting to limit the picker to only select Media Items of these types.
+
+### Pick multiple items
+
+Use this setting to enable the property to contain multiple items. When this is enabled the property editor returns an `IEnumerable`.
+
+You can still set the maximum amount to 1. Do so when you want to retrieve a collection but only allow the Content Editors to select one Media Item.
+
+### Amount
+
+Use this setting to enforce a minimum and/or maximum amount of selected Media Items.
+
+{% hint style="info" %}
+It is not possible to set a maximum amount when the "Pick multiple items" feature is disabled.
+{% endhint %}
+
+### Start node
+
+This setting is used to limit the Media Picker to certain parts of the Media Tree.
+
+### Ignore user start nodes
+
+Use this setting to overrule user permissions, to enable any user of this property to pick any Media Item of the chosen Start node.
+
+When this setting is enabled, a user can access the media available under the selected "Start Node" (/Design in this case). This applies even if they normally lack access. The access is granted specifically when using this particular Media Picker.
+
+### Enable Focal Point
+
+Enable the focal point setter, do only enable this if the focal point is used or if you have Image crops defined.
+
+### Image Crops
+
+Define local image crops. Local image crop data is stored on the document in this property. This means it can differentiate between documents.
+
+This is different from Global crops as they are defined on the Media Item, making the crops shared between all usage of that Media Item.
+
+Global crops are configured on the Image Cropper property of the Image Media Type
+
+[Read about the Image Cropper here](image-cropper.md)
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Multiple enabled without Modelsbuilder
+
+```csharp
+@using Umbraco.Cms.Core.Models
+@{
+ var typedMultiMediaPicker = Model.Value>("medias");
+ foreach (var entry in typedMultiMediaPicker)
+ {
+
+ }
+}
+```
+
+#### Multiple enabled without Modelsbuilder to retrieve IEnumerable data
+
+```csharp
+@using Umbraco.Cms.Core.Models
+@{
+ var listOfImages = Model.Value>("medias");
+ foreach (var image in listOfImages)
+ {
+
+ }
+}
+```
+
+{% hint style="info" %}
+While `MediaWithCrops` is the default return type, `IPublishedContent` may be used in backward-compatible implementations or when working directly with core APIs.
+{% endhint %}
+
+### Multiple enabled with Modelsbuilder
+
+```csharp
+@{
+ var typedMultiMediaPicker = Model.Medias;
+ foreach (var entry in typedMultiMediaPicker)
+ {
+
+ }
+}
+```
+
+### Multiple disabled without Modelsbuilder
+
+```csharp
+@using Umbraco.Cms.Core.Models
+@{
+ var typedMediaPickerSingle = Model.Value("media");
+ if (typedMediaPickerSingle != null)
+ {
+
+ }
+}
+```
+
+### Multiple disabled with Modelsbuilder
+
+```csharp
+@using Umbraco.Cms.Core.Models
+@{
+ var typedMediaPickerSingle = Model.Media;
+ if (typedMediaPickerSingle is MediaWithCrops mediaEntry)
+ {
+
+ }
+}
+```
+
+## Using crops
+
+Both local and global crops are retrieved using the method `GetCropUrl`. If crops with identical aliases are defined both locally and globally, the locally defined crops are always prioritized by `GetCropUrl`.
+
+The following is an example of how to retrieve a crop from a `MediaWithCrops` entry:
+
+```csharp
+@{
+ foreach (var entry in Model.Medias)
+ {
+
+ }
+}
+```
+
+### Explicitly retrieving global crops
+
+You can retrieve globally defined crops explicitly by using `GetCropUrl` on the `UrlHelper`:
+
+```csharp
+@{
+ foreach (var entry in Model.Medias)
+ {
+
+ }
+}
+```
+
+### Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+The following sample will update a single image in a Media Picker.
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core;
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Get the media you want to assign to the media picker
+ var media = Umbraco.Media("bca8d5fa-de0a-4f2b-9520-02118d8329a8");
+
+ // Create an Udi of the media
+ var udi = Udi.Create(Constants.UdiEntityType.Media, media.Key);
+
+ // Set the value of the property with alias 'featuredBanner'.
+ content.SetValue("featuredBanner", udi.ToString());
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'featuredBanner'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.FeaturedBanner).Alias, udi.ToString());
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-group-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-group-picker.md
new file mode 100644
index 00000000000..7799b66b1f1
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-group-picker.md
@@ -0,0 +1,101 @@
+# Member Group Picker
+
+`Schema Alias: Umbraco.MemberGroupPicker`
+
+`UI Alias: Umb.PropertyEditorUi.MemberGroupPicker`
+
+`Returns: string`
+
+The Member Group Picker opens a panel to pick one or more member groups from the Member section. The value saved is of type string (comma separated IDs).
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@if (Model.HasValue("memberGroup"))
+{
+ var memberGroup = Model.Value("memberGroup");
+
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'memberGroup'. The value is the specific ID of the member group
+ content.SetValue("memberGroup", 1067);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+You can also add multiple groups by creating a comma separated string with the desired member group IDs.
+
+```csharp
+@{
+ // Set the value of the property with alias 'memberGroup'.
+ content.SetValue("memberGroup", "1067","1068");
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@using Umbraco.Cms.Core;
+
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'memberGroup'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.MemberGroup).Alias, 1067);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-picker.md
new file mode 100644
index 00000000000..a39b0b3aca7
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/member-picker.md
@@ -0,0 +1,102 @@
+# Member Picker
+
+`Schema Alias: Umbraco.MemberPicker`
+
+`UI Alias: Umb.PropertyEditorUi.MemberPicker`
+
+`Returns: IPublishedContent`
+
+The member picker opens a panel to pick a specific member from the member section. The value saved is of type IPublishedContent.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (Model.HasValue("author"))
+ {
+ var member = Model.Value("author");
+ @member.Name
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ if (Model.Author != null)
+ {
+ var member = Model.Author;
+ @member.Name
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Create a variable for the GUID of the member ID
+ var authorId = Guid.Parse("ed944097281e4492bcdf783355219450");
+
+ // Set the value of the property with alias 'author'.
+ content.SetValue("author", authorId);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@using Umbraco.Cms.Core;
+
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ var udi = Udi.Create(Constants.UdiEntityType.Member, authorId);
+
+ // Set the value of the property with alias 'author'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Author).Alias, udi);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multi-url-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multi-url-picker.md
new file mode 100644
index 00000000000..7f509db6989
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multi-url-picker.md
@@ -0,0 +1,152 @@
+# Multi Url Picker
+
+`Schema Alias: Umbraco.MultiUrlPicker`
+
+`UI Alias: Umb.PropertyEditorUi.MultiUrlPicker`
+
+`Returns: IEnumerable or Link`
+
+Multi Url Picker allows an editor to pick and sort multiple urls. This property editor returns a single item if the "Maximum number of items" Data Type setting is set to 1 or a collection if it is 0. These can either be internal, external or media.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## MVC View Example - value converters enabled
+
+## Typed
+
+```csharp
+@using Umbraco.Cms.Core.Models
+@{
+ var links = Model.Value>("footerLinks");
+ if (links.Any())
+ {
+
+ }
+}
+```
+
+If `Max number of items` is configured to `1`
+
+```csharp
+@using Umbraco.Cms.Core.Models
+@{
+ var link = Model.Value("link");
+ if (link != null)
+ {
+ @link.Name
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core;
+@using Umbraco.Cms.Core.Serialization
+@using Umbraco.Cms.Core.Services;
+@using Umbraco.Cms.Core.Models;
+@inject IContentService Services;
+@inject IJsonSerializer Serializer;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Get the media you want to assign to the footer links property
+ var media = Umbraco.Media("bca8d5fa-de0a-4f2b-9520-02118d8329a8");
+
+ // Create an Udi of the media
+ var mediaUdi = Udi.Create(Constants.UdiEntityType.Media, media.Key);
+
+ // Get the content you want to assign to the footer links property
+ var contentPage = Umbraco.Content("665d7368-e43e-4a83-b1d4-43853860dc45");
+
+ // Create an Udi of the Content
+ var contentPageUdi = Udi.Create(Constants.UdiEntityType.Document, contentPage.Key);
+
+ // Create a list with different link types
+ var externalLinks = new List
+ {
+ // External Link
+ new Link
+ {
+ Target = "_blank",
+ Name = "Our Umbraco",
+ Url = "https://our.umbraco.com/",
+ Type = LinkType.External
+ },
+ // Media
+ new Link
+ {
+ Target = "_self",
+ Name = media.Name,
+ Url = media.MediaUrl(),
+ Type = LinkType.Media,
+ Udi = mediaUdi
+ },
+ // Content
+ new Link
+ {
+ Target = "_self",
+ Name = contentPage.Name,
+ Url = contentPage.Url(),
+ Type = LinkType.Content,
+ Udi = contentPageUdi
+ }
+ };
+
+ // Serialize the list with links to JSON
+ var links = Serializer.Serialize(externalLinks);
+
+
+ // Set the value of the property with alias 'footerLinks'.
+ content.SetValue("footerLinks", links);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'footerLinks'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.FooterLinks).Alias, links);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multiple-textbox.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multiple-textbox.md
new file mode 100644
index 00000000000..f22ad3a1114
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/multiple-textbox.md
@@ -0,0 +1,106 @@
+# Repeatable Textstrings
+
+`Schema Alias: Umbraco.MultipleTextstring`
+
+`UI Alias: Umb.PropertyEditorUi.MultipleTextString`
+
+`Returns: array of strings`
+
+The Repeatable textstrings property editor enables a content editor to make a list of text items. For best use with an unordered-list.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+ (1).png>)
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (Model.Value("keyFeatureList").Length > 0)
+ {
+
+ @foreach (var item in Model.Value("keyFeatureList"))
+ {
+
@item
+ }
+
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ if (Model.KeyFeatureList.Any())
+ {
+
+ @foreach (var item in Model.KeyFeatureList)
+ {
+
@item
+ }
+
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'keyFeatureList'
+ content.SetValue("keyFeatureList", "Awesome" + Environment.NewLine + "Super");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+{% hint style="info" %}
+To add multiple values to the repeatable text strings property editor you have to put each value on a new line. This can be achieved using either `\r\n\` or `Environment.NewLine`.
+{% endhint %}
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'keyFeatureList'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.KeyFeatureList).Alias, "Awesome" + Environment.NewLine + "Super");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/numeric.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/numeric.md
new file mode 100644
index 00000000000..806ec75d0f1
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/numeric.md
@@ -0,0 +1,123 @@
+# Numeric
+
+`Schema Alias: Umbraco.Integer`
+
+`UI Alias: Umb.PropertyEditorUi.Integer`
+
+`Returns: Integer`
+
+Numeric is an HTML input control for entering numbers. Since it's a standard HTML element the options and behaviour are all controlled by the browser and therefore is beyond the control of Umbraco.
+
+## Data Type Definition Example
+
+
+
+### Minimum
+
+This allows you to set up a minimum value. If you will always need a minimum value of 10 this is where you set it up and whenever you use the datatype the value will always start at 10. It's not possible to change the value to anything lower than 10. Only higher values will be accepted.
+
+### Step Size
+
+This allows you to control by how much value should be allowed to increase/decrease when clicking the up/down arrows. If you try to enter a value that does not match with the step setting then it will not be accepted.
+
+### Maximum
+
+This allows you to set up a maximum value. If you will always need a maximum value of 100 this is where you set it up. It's not possible to change the value to anything higher than 100. Only lower values will be accepted.
+
+## Settings
+
+## Content Example
+
+
+
+## MVC View Examples
+
+### Rendering the output casting to an int (without Modelsbuilder)
+
+By casting the output as an int it's possible for you to do mathematical operations with the value.
+
+```csharp
+@{
+ int students = Model.HasValue("students") ? Model.Value("students") : 0;
+ int teachers = Model.HasValue("teachers") ? Model.Value("teachers") : 0;
+ int totalTravellers = students + teachers;
+
+
@totalTravellers
+}
+```
+
+### Rendering the output casting to a string (Without Modelsbuilder)
+
+You can also render the output by casting it to a string, which means you will not be able to do mathematical operations
+
+```csharp
+@{
+ if(Model.HasValue("students")){
+
@(Model.Value("students"))
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ int students = Model.Students;
+ int teachers = Model.Teachers;
+ int totalTravellers = students + teachers;
+
+
@totalTravellers
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'students'
+ content.SetValue("students", 20);
+
+ // Save the change
+ contentService.Save(content);
+
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'students'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Students).Alias, 20);
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/radiobutton-list.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/radiobutton-list.md
new file mode 100644
index 00000000000..18596f1dbe0
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/radiobutton-list.md
@@ -0,0 +1,96 @@
+# Radiobutton List
+
+`Schema Alias: Umbraco.RadioButtonList`
+
+`UI Alias: Umb.PropertyEditorUi.RadioButtonList`
+
+`Returns: string`
+
+Pretty much like the name indicates this Data type enables editors to choose from list of radio buttons and returns the value of the selected item as string.
+
+## Data Type Definition Example
+
+
+
+{% hint style="info" %}
+You can use dictionary items to translate the values of a Radiobutton List property editor in a multilingual setup. For more details, see the [Creating a Multilingual Site](../../../../tutorials/multilanguage-setup.md#translating-multi-value-property-editors) article.
+{% endhint %}
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Typed
+
+#### Without Modelsbuilder
+
+```csharp
+@if (Model.HasValue("colorTheme"))
+{
+ var value = Model.Value("colorTheme");
+
@value
+}
+```
+
+#### With Modelsbuilder
+
+```csharp
+@if (Model.ColorTheme != null)
+{
+ var value = Model.ColorTheme;
+
@value
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'colorTheme'
+ content.SetValue("colorTheme", "water");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'colorTheme'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.ColorTheme).Alias, "water");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/README.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/README.md
new file mode 100644
index 00000000000..c0c2f12ff39
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/README.md
@@ -0,0 +1,123 @@
+# Rich Text Editor TinyMce
+
+`Schema Alias: Umbraco.RichText`
+
+`UI Alias: Umb.PropertyEditorUi.TinyMCE`
+
+`Returns: HTML`
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Rich Text Editor (RTE) is highly configurable and based on [TinyMCE](https://www.tinymce.com/). Depending on the configuration, it will give your content editors more flexibility when working with content that should be more than plain text.
+
+{% hint style="info" %}
+**Are you using custom configurations or plugins with TinyMCE?**
+
+In Umbraco 11 the TinyMCE version supported has been upgraded from version 4 to version 6. You need to migrate to the latest version if you are using TinyMCE plugins or custom configuration.
+
+If your site is upgraded from an older version, follow the migration guides below to upgrade the TinyMCE version as well.
+
+* [Migrate from version 4 to version 5](https://www.tiny.cloud/docs/tinymce/5/migration-from-4x/)
+* [Migrate from version 5 to version 6](https://www.tiny.cloud/docs/tinymce/6/migration-from-5x/)
+{% endhint %}
+
+## [Configuration options](configuration.md)
+
+Customize everything from toolbar options to editor size to where pasted images are saved.
+
+## [Styles](styles.md)
+
+Use CSS to define specific editor styles and add them as formatting options of the Rich Text Editor.
+
+## [Blocks](blocks.md)
+
+Use Blocks to define specific parts that can be added as part of the markup of the Rich Text Editor.
+
+## [Plugins](plugins.md)
+
+Extend the functionality of the Rich Text Editor with plugins.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (Model.HasValue("richText")){
+
@(Model.Value("richText"))
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ if (!string.IsNullOrEmpty(Model.RichText.ToString()))
+ {
+
@Model.RichText
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Create a variable for the desired value
+ var htmlValue = new HtmlString("Add some text here");
+
+ // Set the value of the property with alias 'richText'.
+ content.SetValue("richText", htmlValue);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string.
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'richText'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.RichText).Alias, "Add some text here");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/blocks.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/blocks.md
new file mode 100644
index 00000000000..4263b54ad75
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/blocks.md
@@ -0,0 +1,101 @@
+# Blocks
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+It is possible to insert Blocks into the markup of the Rich Text Editor (RTE). Once you've defined the Block Type as part of the RTE Data Type and enabled the Blocks Toolbar Option. Then Blocks can be created directly inside the Rich Text Editor.
+
+## Configure Blocks
+
+The Block List property editor is configured in the same way as any standard property editor, via the _Data Types_ admin interface.
+
+To set up your Block List Editor property, create a new _Data Type_ and select **Block List** from the list of available property editors.
+
+Then you will see the configuration options for a Block List as shown below.
+
+
+
+The Data Type editor allows you to configure the following properties:
+
+* **Available Blocks** - Here you will define the Block Types to be available for use in the property. Read more on how to set up Block Types below.
+* **Blocks Live editing mode** - Enabling this will make editing of a Block happen directly to the Rich Text Editor, making changes appear as you type.
+
+## Setup Block Types
+
+Block Types are **Element Types** that need to be created before you can start configuring them as Block Types. This can be done either directly from the property editor setup process, or you can set them up beforehand. If they are set beforehand then they need to be added to the Rich Text Editor afterward.
+
+Once you add an Element Type as a Block Type on your Rich Text Editor Data Type you will have options to configure it further.
+
+
+
+Each Block has a set of properties that are optional to configure. They are described below.
+
+### Editor Appearance
+
+By configuring the properties in the group you can customize the user experience for your content editors when they work with the blocks in the Content section.
+
+* **Label** - Define a label for the appearance of the Block in the editor. The label can use AngularJS template string syntax to display values of properties.
+* **Display Inline with text** - When turned on the Block Element will be able to stay in line with text or other elements. If not the Block will stay on its own line.
+* **Custom view** - Overwrite the AngularJS view for the block presentation in the Content editor. Use this to make a more visual presentation of the block or even make your own editing experience by adding your own AngularJS controller to the view.
+* **Custom stylesheet** - Pick your own stylesheet to be used for this block in the Content editor. By adding a stylesheet the styling of this block will become scoped. Meaning that backoffice styles are no longer present for the view of this block.
+* **Overlay editor size** - Set the size for the Content editor overlay for editing this block.
+
+### Data Models
+
+It is possible to use two separate Element Types for your Block Types. It's required to have one for Content and optional to add one for Settings.
+
+* **Content model** - This presents the Element Type used as a model for the content section of this Block. This cannot be changed, but you can open the Element Type to perform edits or view the properties available. Useful when writing your Label.
+* **Settings model** - Add a Settings section to your Block based on a given Element Type. When picked you can open the Element Type or choose to remove the settings section again.
+
+### Catalogue appearance
+
+These properties refer to how the Block is presented in the Block catalog when editors choose which Blocks to use for their content.
+
+* **Background color** - Define a background color to be displayed beneath the icon or thumbnail. Eg. `#424242`.
+* **Icon Color** - Change the color of the Element Type icon. Eg. `#242424`.
+* **Thumbnail** - Pick an image or Scalable Vector Graphics (SVG) file to replace the icon of this Block in the catalog.
+
+The thumbnails for the catalog are presented in the format of 16:10, and we recommend a resolution of 400px width and 250px height.
+
+### Advanced
+
+These properties are relevant when you work with custom views.
+
+* **Force hide content editor** - If you made a custom view that enables you to edit the content part of a block and you are using default editing mode (not inline) you might want to hide the content editor from the block editor overlay.
+
+## Rendering Blocks
+
+To render Blocks in the frontend, you must create Partial Views for each Block.
+
+The Partial Views must be:
+
+* Named by the alias of the Element Type that is being used as the Content Model for the Block.
+* Placed in the folder `Views/Partials/RichText/Components/`.
+
+For example, if the Element Type alias of the Content Model is `myBlockType`, a Partial View must be created at `Views/Partials/RichText/Components/MyBlockType.cshtml`.
+
+The Partial View will receive the model of `Umbraco.Cms.Core.Models.Blocks.RichTextBlockItem`. This gives you the option to access properties of the Content and Settings Models of your Block, as illustrated in the following sample:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+
+@* Output the 'heading' field from the Content Model using the `backgroundColor` field from the Settings Model as background color *@
+
@Model.Content.Value("heading")
+```
+
+If you use ModelsBuilder, you can specify the Content Model (and optionally the Settings Model) in the Partial View model. This allows for type-safe access to the Block data.
+
+The following example shows a Partial View of a Block with `MyBlockType` as Content Model and `MyBlockSettingsType` as Settings Model:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage>
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+
+@* Output the Heading of field with alias 'heading' from the 'MyBlockType' Content Model *@
+
@Model.Content.Heading
+```
+
+## Build a Custom Backoffice View
+
+Building Custom Views for Block representations in Backoffice is the same for all Block Editors. [Read about building a Custom View for Blocks here](../../../../../tutorials/creating-custom-views-for-blocklist.md).
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/configuration.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/configuration.md
new file mode 100644
index 00000000000..3f2464248b7
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/configuration.md
@@ -0,0 +1,69 @@
+# Configuration
+
+{% embed url="" %}
+Rich Text Editor default implementation
+{% endembed %}
+
+In this article, you will learn about different ways to configure the Rich Text Editor (RTE).
+
+## Toolbar
+
+You have full control over which options should be available on the RTE.
+
+
+
+In the example above, all 34 options have been enabled. These options include copy/paste buttons, font styles like bold and italics, bullet lists, and options to embed videos and insert images.
+
+## Stylesheets
+
+It is possible to define specific styles that can be used when editing content using the RTE. You can use as many of these styles with the RTE as you want.
+
+The RTE styles are defined in CSS files which can be created in the **Settings** section. Read the [RTE Styles](styles.md) article to learn more about this feature.
+
+## Dimensions
+
+Define the `height` and `width` of the editor displayed in the Content section.
+
+## Maximum size for inserted images
+
+Define the maximum size for images added through the Rich Text Editor.
+
+If inserted images are larger than the dimensions defined here, the images will be resized automatically.
+
+## Mode
+
+The Rich Text Editor comes in two different modes: Classic and Inline.
+
+### Classic
+
+The default mode which displays the toolbar at the top.
+
+
+
+### Inline
+
+In this mode, the toolbar is hidden and only shows up when content in the editor is highlighted.
+
+
+
+## Blocks
+
+Blocks can be added as elements in the Rich Text Editor. Configuration and rendering of Blocks are described in the [Blocks in Rich Text Editor](blocks.md) article.
+
+## Overlay Size
+
+Select the width of the link picker overlay. The overlay size comes in three sizes: Small, Medium, and Large.
+
+## Hide Label
+
+When this option is checked the label and description for the RTE property will be hidden.
+
+## Ignore User Start Nodes
+
+Some backoffice users might be restricted to specific parts of the Content tree. When the "Ignore User Start Nodes" option is checked, users can pick any piece of content, when adding internal links.
+
+## Image Upload Folder
+
+Images added through the RTE are by default added to the root of the Media library.
+
+Sometimes you might want to add the images to a specific folder. This folder can be configured using the "Image Upload Folder" setting.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/inline-mode-new.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/inline-mode-new.png
new file mode 100644
index 00000000000..6b6ea1f4288
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/inline-mode-new.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/my-rte-button-editor.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/my-rte-button-editor.jpg
new file mode 100644
index 00000000000..8b9a659bf46
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/my-rte-button-editor.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/my-rte-button.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/my-rte-button.jpg
new file mode 100644
index 00000000000..8e43b2a5167
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/my-rte-button.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-choose-stylesheet.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-choose-stylesheet.png
new file mode 100644
index 00000000000..8452a57a36b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-choose-stylesheet.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-code-tab.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-code-tab.png
new file mode 100644
index 00000000000..767739a3f31
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-code-tab.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-content-11.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-content-11.png
new file mode 100644
index 00000000000..ab1e9acf68c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-content-11.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-create-style.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-create-style.png
new file mode 100644
index 00000000000..5d5ca865fdd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-create-style.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-data-type-block-fields.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-data-type-block-fields.jpg
new file mode 100644
index 00000000000..ed0ed6da5d4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-data-type-block-fields.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-data-type-block-type-editor.jpeg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-data-type-block-type-editor.jpeg
new file mode 100644
index 00000000000..dd54171ac52
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-data-type-block-type-editor.jpeg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-datatype-v10.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-datatype-v10.png
new file mode 100644
index 00000000000..a69a02a082d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-datatype-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-datatype.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-datatype.png
new file mode 100644
index 00000000000..0c22f13a5bf
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-datatype.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-mode-classic-11.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-mode-classic-11.png
new file mode 100644
index 00000000000..082f49bdf78
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-mode-classic-11.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-mode-classic-new.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-mode-classic-new.png
new file mode 100644
index 00000000000..ade47ad435a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-mode-classic-new.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-styles.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-styles.png
new file mode 100644
index 00000000000..2d5435266c7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/rte-styles.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/toolbar-all-options.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/toolbar-all-options.png
new file mode 100644
index 00000000000..7c289bd39bd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/toolbar-all-options.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/toolbar-full-11.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/toolbar-full-11.png
new file mode 100644
index 00000000000..7f4d5b84f19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/images/toolbar-full-11.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/plugins.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/plugins.md
new file mode 100644
index 00000000000..fa585b480a3
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/plugins.md
@@ -0,0 +1,200 @@
+---
+description: Information on how to work with TinyMCE plugins in the rich text editor.
+---
+
+# Plugins
+
+The Rich Text Editor (RTE) in Umbraco is based on the open source editor [TinyMCE](https://www.tiny.cloud/). TinyMCE is a highly customizable editor, and it is possible to extend the functionality of the editor by adding plugins.
+
+TinyMCE comes with a lot of plugins out of the box, but it is also possible to create your own plugins. This article will show you how to add a custom plugin to the rich text editor.
+
+## Open-Source Plugins
+
+TinyMCE has a lot of open-source plugins available. You can find a list of these plugins on the [TinyMCE website](https://www.tiny.cloud/docs/tinymce/6/plugins/#open-source-plugins).
+
+## Premium Plugins
+
+TinyMCE also has a number of [premium plugins](https://www.tiny.cloud/docs/tinymce/6/plugins/#premium-plugins) available. These plugins are only available for [paid TinyMCE subscriptions](https://www.tiny.cloud/pricing/). They can be added to the rich text editor by [adding a bit of configuration](#adding-a-premium-plugin).
+
+## Adding a Plugin
+
+To enable plugins in the rich text editor, you need to add an extension type called `tinyMcePlugin` in a manifest file. The manifest file is a JSON file that describes the plugin and how it should be loaded. You can add a plugin such as the open source [Word Count Plugin](https://www.tiny.cloud/docs/tinymce/6/wordcount/) to the rich text editor. You can also define your own custom plugin to extend the functionality of the editor. This way you can add custom buttons, dialogs, or other features to the editor.
+
+{% hint style="info" %}
+The manifest file should be placed in a folder in `App_Plugins/{YourPackageName}`, with the name `umbraco-package.json`.
+{% endhint %}
+
+{% code title="App_Plugins/YourPackageName/umbraco-package.json" lineNumbers="true" %}
+
+```json
+{
+ "name": "My TinyMCE Plugin",
+ "version": "1.0.0",
+ "extensions": [
+ {
+ "type": "tinyMcePlugin",
+ "alias": "mytinymceplugin",
+ "name": "My TinyMCE Plugin",
+ "meta": {
+ "config": {
+ "plugins": ["wordcount"],
+ "statusbar": true
+ }
+ }
+ }
+ ]
+}
+```
+
+{% endcode %}
+
+The example above shows how to add the open-source [Word Count Plugin](https://www.tiny.cloud/docs/tinymce/6/wordcount/) to the rich text editor. The plugin is added to the `Plugins` array in the configuration. The plugin itself will be shown in the statusbar of the rich text editor, so the `statusbar` option is also added to the `config` object.
+
+## Creating a Custom Plugin
+
+If you want to create your own plugin, you should in general follow the [TinyMCE documentation](https://www.tiny.cloud/docs/tinymce/latest/creating-a-plugin/). However, there are a few things you need to be aware of to load the plugin in Umbraco. See the example below.
+
+### Examples
+
+Load a custom plugin that gives you the ability to interact with the global `tinymce` editor object.
+
+Here we are loading a custom plugin called `myrteplugin` and adding a button to the editor called `myrtebutton`. When the button is clicked, it will insert the text `Hello World!` into the editor.
+
+
The text "Hello World!" shows up after clicking the button
+
+1.**Add a manifest file**
+
+First we create an `umbraco-package.json` file which will contain the manifest for the plugin. This adds a button to the toolbar in the rich text editor, which editors can enable on the Data Type. We are also letting the rich text editor know it should load the plugin from the `plugin.js` file.
+
+{% code title="App_Plugins/MyRtePlugin/umbraco-package.json" lineNumbers="true" %}
+
+```json
+{
+ "name": "My TinyMCE Plugin",
+ "version": "1.0.0",
+ "extensions": [
+ {
+ "type": "tinyMcePlugin",
+ "alias": "myrteplugin",
+ "name": "My TinyMCE Plugin",
+ "js": "/App_Plugins/MyRtePlugin/plugin.js",
+ "meta": {
+ "toolbar": [
+ {
+ "alias": "myrtebutton",
+ "label": "My RTE Button",
+ "icon": "code-sample"
+ }
+ ]
+ }
+ }
+ ]
+}
+```
+
+{% endcode %}
+
+2.**Add the plugin.js file**
+
+The `plugin.js` file should contain the JavaScript code for the plugin. The file is loaded as a JavaScript module and must export a default class that extends the `UmbTinyMcePluginBase` class.
+
+{% hint style="info" %}
+The `UmbTinyMcePluginBase` class is a class provided by Umbraco that you can use to create your own plugins. The class is a wrapper around the TinyMCE plugin API. We can use the `args` object on the constructor to access the TinyMCE editor instance and other useful properties.
+{% endhint %}
+
+{% code title="App_Plugins/MyTinyMCEPlugin/plugin.js" lineNumbers="true" %}
+
+```js
+import { UmbTinyMcePluginBase } from '@umbraco-cms/backoffice/tiny-mce';
+
+export default class UmbTinyMceMediaPickerPlugin extends UmbTinyMcePluginBase {
+ /**
+ @param args {import('@umbraco-cms/backoffice/tiny-mce').TinyMcePluginArguments}
+ */
+ constructor(args: TinyMcePluginArguments) {
+ super(args);
+
+ // Add your plugin code here
+ args.editor.ui.registry.addButton('myrtebutton', {
+ text: 'My RTE Button',
+ icon: 'code-sample',
+ onAction: () => {
+ args.editor.insertContent('Hello World!');
+ }
+ });
+ }
+}
+```
+
+{% endcode %}
+
+The button must be added to the toolbar in the rich text editor configuration.
+
+
Enable the button in the rich text editor configuration
+
+You can go to any Document Type that uses the rich text editor and click the button to insert the text `Hello World!` after.
+
+You have full access to the `tinymce` editor object, so you can create any custom functionality you need.
+
+### Learn more
+
+* [TinyMCE documentation](https://www.tiny.cloud/docs/)
+* [TinyMCE tutorial: Creating a plugin](https://www.tiny.cloud/docs/tinymce/latest/creating-a-plugin/)
+
+## Adding a premium plugin
+
+To add a premium plugin, you need to add the plugin name to the `plugins` array in the `config` object of a `tinyMcePlugin` extension. You also need to add a JavaScript module that can load up the cloud-hosted TinyMCE premium plugins bundle.
+
+{% hint style="info" %}
+Premium plugins require a subscription at [TinyMCE Cloud](https://www.tiny.cloud/). You can go there and sign up for a free trial. You will get a Cloud API key that you can use to try out the premium plugins.
+{% endhint %}
+
+1. Declaring the plugin
+
+Let us first add the [powerpaste](https://www.tiny.cloud/docs/tinymce/6/introduction-to-powerpaste/) plugin to the rich text editor. This plugin is a premium plugin that helps you paste content from Word documents and other sources. We will configure the plugin to allow local images and clean the HTML when pasting Word documents.
+
+{% code title="App_Plugins/MyRtePlugin/umbraco-package.json" lineNumbers="true" %}
+
+```json
+{
+ "name": "My TinyMCE Plugin",
+ "version": "1.0.0",
+ "extensions": [
+ {
+ "type": "tinyMcePlugin",
+ "alias": "mytinymceplugin",
+ "name": "My TinyMCE Plugin",
+ "js": "/App_Plugins/MyRtePlugin/plugin.js",
+ "meta": {
+ "config": {
+ "plugins": ["powerpaste"],
+ "powerpaste_allow_local_images": "true",
+ "powerpaste_word_import": "clean"
+ }
+ }
+ }
+ ]
+}
+```
+
+{% endcode %}
+
+2. Creating the plugin.js file
+
+The `plugin.js` file should contain the JavaScript code to load the cloud-hosted TinyMCE premium plugins bundle. You must replace `{Cloud API Key}` with your own Cloud API key.
+
+{% code title="App_Plugins/MyTinyMCEPlugin/plugin.js" lineNumbers="true" %}
+
+```js
+import 'https://cdn.tiny.cloud/1/{Cloud API Key}/tinymce/6/plugins.min.js';
+```
+
+{% endcode %}
+
+We have now enabled the `powerpaste` plugin. We have configured it to allow pasting in local images. It will prompt when pasting Word documents, but for HTML documents it will clean the HTML without prompting.
+
+{% hint style="info" %}
+You can enable as many plugins as you want through the `plugins` array in the `config` object. You can even combine premium, open-source, and your own plugins as you see fit.
+{% endhint %}
+
+See all the [available premium plugins](https://www.tiny.cloud/docs/tinymce/6/plugins/#premium-plugins) on the TinyMCE website.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/styles.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/styles.md
new file mode 100644
index 00000000000..67e925990e4
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor-tinymce/styles.md
@@ -0,0 +1,44 @@
+# Styles
+
+It is possible to define specific styles and fonts for the Rich Text Editor (RTE). Once you have defined the styles, and enabled them on the RTE Data Type, the styles can be accessed directly in the Content section.
+
+
+
+## Creating RTE Styles
+
+The RTE styles are created and managed in the Umbraco backoffice.
+
+* Find the **Stylesheets** folder in the Settings section.
+* Click **...** next to the **Stylesheets** folder and select **Create...**.
+* Choose _New Rich Text Editor style sheet file_.
+* Give the new stylesheet a name and **Save** it.
+
+This will generate an empty CSS file in your project.
+
+At this point, you can start adding specific styles, that your editors can then use in the Content section when creating and writing new content.
+
+
+
+The image above is an example of how an RTE style can be configured. When working with these styles, the **Preview** feature will show you how the style will look when applied.
+
+Every style you add, will automatically be added to the CSS file. The file will be placed in the same location as the rest of your CSS files. It is possible to edit the file directly from the backoffice as well. Access it from the **Code** tab in the top-right corner.
+
+
+
+## Using RTE Styles
+
+In order for your editors to be able to use the styles when working with content, two things needs to be done.
+
+### 1. Enable "Style select"
+
+The styles will be accessed by the editors using the "Formats" dropdown in the toolbar of the RTE. In order the enable the dropdown, the "Style select" toolbar option needs to be checked.
+
+This can be done by accessing the RTE Data Type directly from the "Info" tab on the Content. You can also find the RTE Data Type in the Settings section of the backoffice and make the changes from there. Learn more about the configuration options in the [RTE Config](configuration.md) article.
+
+### 2. Select the styles
+
+You can have as many different styles for your RTEs as you want. You might want to have different styles for different RTE Data Types.
+
+When configuring your RTE Data Types, you can select which stylesheets your content editors should be able to use.
+
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/README.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/README.md
new file mode 100644
index 00000000000..2ec74dbffeb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/README.md
@@ -0,0 +1,115 @@
+# Rich Text Editor
+
+`Schema Alias: Umbraco.RichText` `UI Alias: Umb.PropertyEditorUi.Tiptap`
+
+`Returns: HTML`
+
+{% hint style="warning" %}
+In Umbraco 15, the Rich Text Editor has a new default property editor UI that introduces Tiptap as an alternative.
+
+You can continue to use the [TinyMCE UI for the Rich Text Editor](../rich-text-editor-tinymce/). This UI will be removed in Umbraco 16.
+
+**Current limitations**
+
+The Tiptap UI currently does not support using custom styles for your rich text.
+
+Resizing media images has not been implemented yet.
+
+{% endhint %}
+
+The Rich Text Editor (RTE) Tiptap property editor is highly configurable and based on [Tiptap](https://tiptap.dev/). Depending on the configuration setup, it provides editors a lot of flexibility when working with content.
+
+## [Configuration options](configuration.md)
+
+Customize everything from toolbar options to editor size to where pasted images are saved.
+
+## [Blocks](blocks.md)
+
+Use Blocks to define specific parts that can be added as part of the markup of the Rich Text Editor.
+
+## [Extensions](extensions.md)
+
+Extend the functionality of the Rich Text Editor with extensions.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## MVC View Example
+
+### With Modelsbuilder
+
+```csharp
+@{
+ if (!string.IsNullOrEmpty(Model.RichText.ToString()))
+ {
+
@Model.RichText
+ }
+}
+```
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (Model.HasValue("richText")){
+
@(Model.Value("richText"))
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Create a variable for the desired value
+ var htmlValue = new HtmlString("Add some text here");
+
+ // Set the value of the property with alias 'richText'.
+ content.SetValue("richText", htmlValue);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string.
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'richText'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.RichText).Alias, "Add some text here");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/blocks.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/blocks.md
new file mode 100644
index 00000000000..28ac0dc3565
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/blocks.md
@@ -0,0 +1,104 @@
+# Blocks
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+It is possible to insert Blocks into the markup of the Rich Text Editor. Block can be created directly inside the Rich Text editor when
+
+* You have defined the Block Type as part of the RTE Data Type, and
+* Enabled the Blocks Toolbar Option.
+
+## Configure Blocks
+
+The Block List property editor is configured in the same way as any standard property editor, via the _Data Types_ admin interface.
+
+To set up your Block List Editor property, create a new _Data Type_ and select **Block List** from the list of available property editors.
+
+Then you will see the configuration options for a Block List as shown below.
+
+
+
+The Data Type editor allows you to configure the following properties:
+
+* **Available Blocks** - Here you will define the Block Types to be available for use in the property. Read more on how to set up Block Types below.
+* **Blocks Live editing mode** - Enabling this will edit a Block directly to the Rich Text Editor, making changes appear as you type.
+
+## Setup Block Types
+
+Block Types are **Element Types** that need to be created before you can start configuring them as Block Types. This can be done either directly from the property editor setup process, or you can set them up beforehand. If they are set beforehand then they need to be added to the Rich Text Editor afterward.
+
+Once you add an Element Type as a Block Type on your Rich Text Editor Data Type you will have options to configure it further.
+
+
+
+Each Block has a set of properties that are optional to configure. They are described below.
+
+### Editor Appearance
+
+By configuring the properties in the group you can customize the experience for your editors when they work with blocks in the Content section.
+
+* **Label** - Define a label for the appearance of the Block in the editor. The label can use AngularJS template string syntax to display values of properties.
+* **Display Inline with text** - When turned on the Block Element will be able to stay in line with text or other elements. If not the Block will stay on its own line.
+* **Custom view** - Overwrite the AngularJS view for the block presentation in the Content editor. Use this to make a more visual presentation of the block or even make your own editing experience by adding your own AngularJS controller to the view.
+* **Custom stylesheet** - Pick your own stylesheet to be used for this block in the Content editor. By adding a stylesheet the styling of this block will become scoped. Meaning that backoffice styles are no longer present for the view of this block.
+* **Overlay editor size** - Set the size for the Content editor overlay for editing this block.
+
+### Data Models
+
+It is possible to use two separate Element Types for your Block Types. It's required to have one for Content and optional to add one for Settings.
+
+* **Content model** - This presents the Element Type used as a model for the content section of this Block. This cannot be changed, but you can open the Element Type to perform edits or view the properties available. Useful when writing your Label.
+* **Settings model** - Add a Settings section to your Block based on a given Element Type. When picked you can open the Element Type or choose to remove the settings section again.
+
+### Catalogue appearance
+
+These properties refer to how the Block is presented in the Block catalog when editors choose which Blocks to use for their content.
+
+* **Background color** - Define a background color to be displayed beneath the icon or thumbnail. Eg. `#424242`.
+* **Icon Color** - Change the color of the Element Type icon. Eg. `#242424`.
+* **Thumbnail** - Pick an image or Scalable Vector Graphics (SVG) file to replace the icon of this Block in the catalog.
+
+The thumbnails for the catalog are presented in the format of 16:10, and we recommend a resolution of 400px width and 250px height.
+
+### Advanced
+
+These properties are relevant when you work with custom views.
+
+* **Force hide content editor** - If you made a custom view that enables you to edit the content part of a block and you are using default editing mode (not inline) you might want to hide the content editor from the block editor overlay.
+
+## Rendering Blocks
+
+To render Blocks in the frontend, you must create Partial Views for each Block.
+
+The Partial Views must be:
+
+* Named by the alias of the Element Type that is being used as the Content Model for the Block.
+* Placed in the folder `Views/Partials/RichText/Components/`.
+
+For example, if the Element Type alias of the Content Model is `myBlockType`, a Partial View must be created at `Views/Partials/RichText/Components/MyBlockType.cshtml`.
+
+The Partial View will receive the model of `Umbraco.Cms.Core.Models.Blocks.RichTextBlockItem`. This gives you the option to access properties of the Content and Settings Models of your Block, as illustrated in the following sample:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+
+@* Output the 'heading' field from the Content Model using the `backgroundColor` field from the Settings Model as background color *@
+
@Model.Content.Value("heading")
+```
+
+If you use ModelsBuilder, you can specify the Content Model (and optionally the Settings Model) in the Partial View model. This allows for type-safe access to the Block data.
+
+The following example shows a Partial View of a Block with `MyBlockType` as the Content Model and `MyBlockSettingsType` as the Settings Model:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage>
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+
+@* Output the Heading of field with alias 'heading' from the 'MyBlockType' Content Model *@
+
@Model.Content.Heading
+```
+
+## Build a Custom Backoffice View
+
+Building Custom Views for Block representations in Backoffice is the same for all Block Editors. [Read about building a Custom View for Blocks here](../../../../../tutorials/creating-custom-views-for-blocklist.md).
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/change-rich-text-editor-ui.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/change-rich-text-editor-ui.md
new file mode 100644
index 00000000000..b7a0d938364
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/change-rich-text-editor-ui.md
@@ -0,0 +1,57 @@
+# Change Rich Text Editor UI
+
+{% hint style="info" %}
+Umbraco 15 includes two options for rich text editing: Tiptap and TinyMCE. TinyMCE will eventually be phased out of the CMS.
+
+This article will guide you through switching from TinyMCE UI to the new Tiptap UI.
+{% endhint %}
+
+The following steps will guide you through changing the property editor used for rich text on an existing Document Type.
+
+## Create a new Data Type
+
+The first step in this guide is to create a new Rich Text Editor Data Type using the Tiptap property editor.
+
+As an alternative, you can create a new Data Type using the Tiptap property editor when updating the Document Type.
+
+{% hint style="info" %}
+When swapping the UI used for the Rich Text Editor, you may need to reconfigure the toolbar.
+{% endhint %}
+
+1. Navigate to the **Settings** section of the Umbraco Backoffice.
+2. Select **+** next to the Data Types folder.
+3. Select **New Data Type...**.
+
+
+
+4. Give the new Data Type a name.
+5. Click **Select a property editor**.
+6. Choose **Rich Text Editor [Tiptap]**.
+
+
+
+7. [Configure the Data Type](./configuration.md) to match your needs.
+8. **Save** the Data Type.
+
+## Update the Document Type(s)
+
+Once you have prepared the new Data Type you need to update the Document Types that should use it.
+
+1. Expand the **Document Types** folder.
+2. Select a Document Type that needs to be updated.
+3. Click on the Property used for rich text.
+
+
+
+4. Hover over the selected property editor and click **Change**.
+5. Search for the newly created Data Type and select it.
+
+
+
+6. **Submit** the changes.
+7. **Save** the Document Type.
+8. Repeat steps 2-7 for each Document Type that needs to use the new Data Type.
+
+## Verify your content
+
+When you have updated all the relevant Document Types, it is recommended to verify the content that uses the Rich Text Editor.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/configuration.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/configuration.md
new file mode 100644
index 00000000000..d44ba29d33c
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/configuration.md
@@ -0,0 +1,46 @@
+# Settings
+
+In this article you can learn about the different options you have for configuring the Rich Text Editor (RTE).
+
+## Toolbar
+
+You have full control over which options should be available on the RTE.
+
+
+
+In the example above, all 27 options have been enabled. These options include font styles like bold and italics, bullet lists, and options to embed videos and insert images.
+
+You can customize the look of the toolbar:
+
+* Enhance the capabilities of the toolbar by enabling or disabling extensions.
+* Use the Toolbar designer to group together items and add additional rows if needed.
+
+
+
+## Dimensions
+
+Define `height` and `width` of the editor displayed in the content section.
+
+## Maximum size for inserted images
+
+Define the maximum size for images added through the Rich Text Editor.
+
+If inserted images are larger than the dimensions defined here, the images will be resized automatically.
+
+## Overlay Size
+
+Select the width of the link picker overlay. The overlay size comes in three sizes: Small, Medium, Large, and Full.
+
+## Available Blocks
+
+Blocks can be added as elements in the Rich Text Editor. Configuration and rendering of Blocks are described in the [Blocks in Rich Text Editor](blocks.md) article.
+
+## Image Upload Folder
+
+Images added through the RTE are by default added to the root of the Media library.
+
+Sometimes you might want to add the images to a specific folder. This folder can be configured using the "Image Upload Folder" setting.
+
+## Ignore User Start Nodes
+
+Some of the backoffice users might be restricted to a specific part of the content tree. When the "Ignore User Start Nodes" is checked, the users can pick any piece of content from the content tree, when adding internal links through the RTE.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/extensions.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/extensions.md
new file mode 100644
index 00000000000..3f5ab8cf623
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/extensions.md
@@ -0,0 +1,99 @@
+---
+description: Information on how to work with Tiptap extensions in the rich text editor.
+---
+
+# Extensions
+
+The Rich Text Editor (RTE) in Umbraco is based on the open-source editor [Tiptap](https://tiptap.dev/).
+
+Out of the box, Tiptap has limited capabilities and everything is an extension by design. Basic text formatting features such as bold, italic, and underline are their own extensions. This offers great flexibility, making the rich text editor highly configurable. The implementation in Umbraco offers a wide range of built-in extensions to enhance the Tiptap editor capabilities.
+
+Using the same extension points, this article will show you how to add a custom extension to the rich text editor.
+
+## Native Tiptap extensions
+
+Tiptap has a library of supported native extensions. You can find a list of these extensions on the [Tiptap website](https://tiptap.dev/docs/editor/extensions/overview). While many of these are open source, there are also [pro extensions](https://tiptap.dev/docs/guides/pro-extensions) available for commercial subscriptions.
+
+### Tiptap extension types
+
+There are two types of extension: `tiptapExtension` and `tiptapToolbarExtension`.
+
+The `tiptapExtension` extension is used to register a native [Tiptap Extension](https://tiptap.dev/docs/editor/extensions/). These will enhance the capabilities of the rich text editor itself. For example, to enable text formatting, drag-and-drop functionality and spell-checking.
+
+The `tiptapToolbarExtension` extension adds a toolbar action that interacts with the Tiptap editor (and native Tiptap extensions).
+
+
+## Adding a native extension
+
+{% hint style="info" %}
+This example assumes that you will be creating an Umbraco package using the Vite/Lit/TypeScript setup.
+You can learn how to do this [Vite Package Setup](../../../../../customizing/development-flow/vite-package-setup.md) article.
+{% endhint %}
+
+In this example, you will take the native Tiptap open-source extension [Highlight](https://tiptap.dev/docs/editor/extensions/marks/highlight). Then register it with the rich text editor and add a toolbar button to invoke the Task List action.
+
+1. Install the Highlight extension from the npm registry.
+
+```
+npm install @tiptap/extension-highlight
+```
+
+2. Create the code to register the native Tiptap extensions in the rich text editor.
+
+```js
+import { UmbTiptapExtensionApiBase } from '@umbraco-cms/backoffice/tiptap';
+import { Highlight } from '@tiptap/extension-highlight';
+
+export default class UmbTiptapHighlightExtensionApi extends UmbTiptapExtensionApiBase {
+ getTiptapExtensions = () => [Highlight];
+}
+```
+
+3. Create the toolbar action to invoke the Highlight extension.
+
+```js
+import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
+import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
+
+export default class UmbTiptapToolbarHighlightExtensionApi extends UmbTiptapToolbarElementApiBase {
+ override execute(editor?: Editor) {
+ editor?.chain().focus().toggleHighlight().run();
+ }
+}
+```
+
+Once you have the above code in place, they can be referenced using a [bundle extension type](../../../../../customizing/extending-overview/extension-types/bundle.md).
+
+{% code title="manifests.ts" lineNumbers="true" %}
+```js
+export const manifests: Array = [
+ {
+ type: 'tiptapExtension',
+ kind: 'button',
+ alias: 'My Highlight Tiptap Extension',
+ name: 'My.Tiptap.Highlight',
+ api: () => import('./highlight.tiptap-api.js'),
+ meta:{
+ icon: "icon-thumbnail-list",
+ label: "Highlight",
+ group: "#tiptap_extGroup_formatting"
+ }
+ },
+ {
+ type: 'tiptapToolbarExtension',
+ kind: 'button',
+ alias: 'My.Tiptap.Toolbar.Highlight',
+ name: 'My Highlight Tiptap Toolbar Extension',
+ js: () => import('./highlight.tiptap-toolbar-api.js'),
+ forExtensions: ["My.Tiptap.Highlight"],
+ meta:{
+ alias: "highlight",
+ icon: "icon-brush",
+ label: "Highlight"
+ }
+ }
+]
+```
+{% endcode %}
+
+Upon restarting Umbraco, the new extension and toolbar action will be available in the Tiptap Data Type configuration settings.
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-data-type-block-fields.jpg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-data-type-block-fields.jpg
new file mode 100644
index 00000000000..ed0ed6da5d4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-data-type-block-fields.jpg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-data-type-block-type-editor.jpeg b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-data-type-block-type-editor.jpeg
new file mode 100644
index 00000000000..dd54171ac52
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-data-type-block-type-editor.jpeg differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-change-property.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-change-property.png
new file mode 100644
index 00000000000..5916b405fb9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-change-property.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-new-data-type.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-new-data-type.png
new file mode 100644
index 00000000000..0d5c77819f4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-new-data-type.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-search-and-find-new-ui.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-search-and-find-new-ui.png
new file mode 100644
index 00000000000..f0cc5f36c26
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-search-and-find-new-ui.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-select-ui.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-select-ui.png
new file mode 100644
index 00000000000..a067f1928be
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-swap-select-ui.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-all-toolbar-items.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-all-toolbar-items.png
new file mode 100644
index 00000000000..ce5d1b9e7a0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-all-toolbar-items.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-capabilities-and-toolbar.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-capabilities-and-toolbar.png
new file mode 100644
index 00000000000..0ed995ef81e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-capabilities-and-toolbar.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-contentexample.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-contentexample.png
new file mode 100644
index 00000000000..caed9635fec
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-contentexample.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-datatypedefinition.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-datatypedefinition.png
new file mode 100644
index 00000000000..827504d26e9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/images/rte-tiptap-datatypedefinition.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/slider.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/slider.md
new file mode 100644
index 00000000000..6865dd46b97
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/slider.md
@@ -0,0 +1,140 @@
+# Slider
+
+`Schema Alias: Umbraco.Slider`
+
+`UI Alias: Umb.PropertyEditorUi.Slider`
+
+`Returns: decimal` or `Umbraco.Core.Models.Range`
+
+Pretty much like the name indicates this Data type enables editors to choose a value with a range using a slider.
+
+There are two flavors of the slider. One with a single value picker. One with a minimum and maximum value.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@if (Model.HasValue("singleValueSlider"))
+{
+ var value = Model.Value("singleValueSlider");
+
@value
+}
+
+@if (Model.HasValue("multiValueSlider"))
+{
+ var value = Model.Value>("multiValueSlider");
+
@(value.Minimum) and @(value.Maximum)
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+// with a range off
+@if (Model.SingleValueSlider != null)
+{
+ var value = Model.SingleValueSlider;
+
@value
+}
+
+// with a range on
+@if (Model.MultiValueSlider != null)
+{
+ var minValue = Model.MultiValueSlider.Minimum;
+ var maxValue = Model.MultiValueSlider.Maximum;
+
@minValue and @maxValue
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+### With a range off
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'singleValueSlider'.
+ content.SetValue("singleValueSlider", 10);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+### With a range on
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Create a variable for the desired value of the 'multiValueSlider' property
+ var range = new Range {Minimum = 10, Maximum = 12};
+
+ // Set the value of the property with alias 'multiValueSlider'.
+ content.SetValue("multiValueSlider", range);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'singleValueSlider'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.SingleValueSlider).Alias, 10);
+
+ // Set the value of the property with alias 'multiValueSlider'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.MultiValueSlider).Alias, new Range {Minimum = 10, Maximum = 12});
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/tags.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/tags.md
new file mode 100644
index 00000000000..ea4daff0403
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/tags.md
@@ -0,0 +1,125 @@
+# Tags
+
+`Schema Alias: Umbraco.Tags`
+
+`UI Alias: Umb.PropertyEditorUi.Tags`
+
+`Returns: IEnumerable`
+
+The Tags property editor allows you to add multiple tags to a node.
+
+## Data Type Definition Example
+
+
+
+### Tag group
+
+The **Tag group** setting provides a way to categorize your tags in groups. So for each category you will create a new instance of the Tags property editor and setup the unique category name for each instance. Whenever a tag is added to an instance of the tags property editor it's added to the tag group, which means it will appear in the Typeahead list when you start to add another tag. Only tags that belong to the specified group will be listed. If you have a "Frontend" group and a "Backend" group the tags from the "Frontend" group will only be listed if you're adding a tag to the Tags property editor configured with the "Frontend" group name and vice versa.
+
+### Storage type
+
+Data can be saved in either Comma-Separated Values (CSV) format or in JSON format. By default data is saved in JSON format. The difference between using CSV and JSON is that with JSON you can save a tag, which includes comma separated values.
+
+There are built-in property value converters, which means you don't need to worry about writing them yourself or parse the JSON output when choosing "JSON" in the storage type field. Therefore [the last code example](tags.md#mvc-view-example---displays-a-list-of-tags) on this page will work out of the box without further ado.
+
+## Content Examples
+
+### CSV tags
+
+
+
+### JSON tags
+
+
+
+### Tags typeahead
+
+Whenever a tag has been added it will be visible in the typeahead when you start typing on other pages.
+
+
+
+## MVC View Example - displays a list of tags
+
+### Multiple items - with Modelsbuilder
+
+```csharp
+@if(Model.Tags.Any()){
+
+ @foreach(var tag in Model.Tags){
+
@tag
+ }
+
+}
+```
+
+### Multiple items - without Modelsbuilder
+
+```csharp
+@if(Model.HasValue("tags"))
+{
+ var tags = Model.Value>("tags");
+
+ @foreach(var tag in tags)
+ {
+
@tag
+ }
+
+}
+```
+
+### Setting Tags Programmatically
+
+You can use the ContentService to create and update Umbraco content from c# code, when setting tags there is an extension method (SetTagsValue) on IContentBase that helps you set the value for a Tags property. Remember to add the using statement for `Umbraco.Core.Models` to take advantage of it.
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Serialization
+@using Umbraco.Cms.Core.Services
+@inject IContentService Services;
+@inject IJsonSerializer Serializer;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = Guid.Parse("9daf8585-6ab6-4ac2-98f0-28bf83aeea6e");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'tags'.
+ content.SetValue("tags", Serializer.Serialize(new[] { "News", "Umbraco", "Example", "Setting Tags", "Helper" }));
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled, you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'tags'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Tags).Alias, Serializer.Serialize(new[] { "News", "Umbraco", "Example", "Setting Tags" }));
+}
+```
+
+### More on working with Tags
+
+More on working with Tags (query all of them) can be found at the [UmbracoHelper reference page](../../../../reference/querying/umbracohelper.md#working-with-tags)
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textarea.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textarea.md
new file mode 100644
index 00000000000..e241e536a29
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textarea.md
@@ -0,0 +1,98 @@
+# Textarea
+
+`Schema Alias: Umbraco.TextArea`
+
+`UI Alias: Umb.PropertyEditorUi.TextArea`
+
+`Returns: String`
+
+Textarea is an HTML textarea control for multiple lines of text. It can be configured to have a fixed character limit, as well as define how big the space for writing can be. By default, there is no character limit unless it's specifically set to a specific value like 200 for instance. If you don't specify the number of rows, 10 will be the amount of rows the textarea will be occupying, unless changed to a custom value.
+
+## Data Type Definition Example
+
+
+
+## Settings
+
+## Content Example
+
+### Without a character and rows limit
+
+
+
+### With a character limit and rows limit
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (Model.HasValue("description")){
+
+}
+```
+
+## Add value programmatically
+
+See the example below to learn how a value can be added or changed programmatically to a Textarea property. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of your page
+ var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
+
+ // Get the page using the GUID you've just defined
+ var content = contentService.GetById(guid);
+ // Set the value of the property with alias 'description'
+ content.SetValue("description", "This is some text for the text area!");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+
+ // Set the value of the property with alias 'description'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.Description).Alias, "This is some text for the text area!");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textbox.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textbox.md
new file mode 100644
index 00000000000..84cd4b41978
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/textbox.md
@@ -0,0 +1,106 @@
+---
+description: How to use the TextBox property editors in Umbraco CMS.
+---
+
+# Textbox
+
+`Schema Alias: Umbraco.TextBox`
+
+`UI Alias: Umb.PropertyEditorUi.TextBox`
+
+`Returns: String`
+
+Textbox is an HTML input control for text. It can be configured to have a fixed character limit. The default maximum amount of characters is 512 unless it's specifically changed to a lower amount.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+### Without a character limit
+
+
+
+### With a character limit
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ // Perform an null-check on the field with alias 'pageTitle'
+ if (Model.HasValue("pageTitle")){
+ // Print the value of the field with alias 'pageTitle'
+
@(Model.Value("pageTitle"))
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ // Perform an null-check on the field with alias 'pageTitle'
+ @if (!Model.HasValue(Model.PageTitle))
+ {
+ // Print the value of the field with alias 'pageTitle'
+
@Model.PageTitle
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'pageTitle'
+ content.SetValue("pageTitle", "Umbraco Demo");
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+
+ // Set the value of the property with alias 'pageTitle'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.PageTitle).Alias, "Umbraco Demo");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/true-false.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/true-false.md
new file mode 100644
index 00000000000..0eb89c9a21e
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/true-false.md
@@ -0,0 +1,97 @@
+# Toggle
+
+`Schema Alias: Umbraco.TrueFalse`
+
+`UI Alias: Umb.PropertyEditorUi.Toggle`
+
+`Returns: Boolean`
+
+Toggle is a standard checkbox which saves either 0 or 1, depending on the checkbox being checked or not.
+
+## Data Type Definition Example
+
+
+
+The Toggle property has a setting which allows you to set the default value of the checkbox, either checked (true) or unchecked (false).
+
+It is also possible to define a label, that will be displayed next to the checkbox on the content.
+
+## Content Example
+
+
+
+## MVC View Example
+
+### Without Modelsbuilder
+
+```csharp
+@{
+ if (!Model.Value("myCheckBox"))
+ {
+
The Checkbox is not checked!
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@{
+ if (!Model.MyCheckbox)
+ {
+
The Checkbox is not checked!
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'myCheckBox'
+ content.SetValue("myCheckBox", true);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@using Umbraco.Cms.Core.PublishedCache;
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'myCheckBox'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor,x => x.MyCheckBox).Alias, true);
+
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/user-picker.md b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/user-picker.md
new file mode 100644
index 00000000000..0c8320c1d93
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/user-picker.md
@@ -0,0 +1,108 @@
+# User Picker
+
+`Schema Alias: Umbraco.UserPicker`
+
+`UI Alias: Umb.PropertyEditorUi.UserPicker`
+
+`Returns: IPublishedContent`
+
+The user picker opens a panel to pick a specific user from the Users section. The value saved is of type IPublishedContent.
+
+## Data Type Definition Example
+
+
+
+## Content Example
+
+
+
+## MVC View Example
+
+{% hint style="info" %}
+Getting the Value of the property will return the user ID - properties of the User can be accessed by referencing UserService.
+{% endhint %}
+
+### Without Modelsbuilder
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IUserService UserService;
+@{
+
+ if (Model.Value("userPicker") != null)
+ {
+ var us = UserService;
+ var username = us.GetUserById(Model.Value("userPicker")).Name;
+
+
This is the chosen person: @username
+
This returns the id value of chosen person: @Model.Value("userPicker")
+ }
+}
+```
+
+### With Modelsbuilder
+
+```csharp
+@using Umbraco.Cms.Core.Services;
+@inject IUserService UserService;
+@{
+ if (Model.UserPicker != null)
+ {
+
+ var us = UserService;
+ var user = us.GetUserById((int)Model.UserPicker);
+
+
This is the chosen person: @user.Name
+
This returns the id value of chosen person: @user.Id)
+ }
+}
+```
+
+## Add values programmatically
+
+See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the [Content Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html).
+
+{% hint style="info" %}
+The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.
+{% endhint %}
+
+```csharp
+@inject IContentService Services;
+@{
+ // Get access to ContentService
+ var contentService = Services;
+
+ // Create a variable for the GUID of the page you want to update
+ var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
+
+ // Get the page using the GUID you've defined
+ var content = contentService.GetById(guid); // ID of your page
+
+ // Set the value of the property with alias 'userPicker'. The value is the specific ID of the user
+ content.SetValue("userPicker", -1);
+
+ // Save the change
+ contentService.Save(content);
+}
+```
+
+Although the use of a GUID is preferable, you can also use the numeric ID to get the page:
+
+```csharp
+@{
+ // Get the page using it's id
+ var content = contentService.GetById(1234);
+}
+```
+
+If Modelsbuilder is enabled you can get the alias of the desired property without using a magic string:
+
+{% include "../../../../.gitbook/includes/obsolete-warning-ipublishedsnapshotaccessor.md" %}
+
+```csharp
+@inject IPublishedSnapshotAccessor _publishedSnapshotAccessor;
+@{
+ // Set the value of the property with alias 'userPicker'
+ content.SetValue(Home.GetModelPropertyType(_publishedSnapshotAccessor, x => x.UserPicker).Alias, "Umbraco Demo");
+}
+```
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/Media-picker-dataType-v9.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/Media-picker-dataType-v9.png
new file mode 100644
index 00000000000..36cdbba266d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/Media-picker-dataType-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-column-content-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-column-content-picker.png
new file mode 100644
index 00000000000..f0e664a416b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-column-content-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-property-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-property-picker.png
new file mode 100644
index 00000000000..375af70dc02
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-property-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-view-cards-content-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-view-cards-content-picker.png
new file mode 100644
index 00000000000..cfb2e51eb9f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/collection-view-cards-content-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/content-picker-picked-value.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/content-picker-picked-value.png
new file mode 100644
index 00000000000..9726d5c05ea
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/content-picker-picked-value.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/content-picker-property.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/content-picker-property.png
new file mode 100644
index 00000000000..a20251e8876
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/content-picker-property.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/property-editors/images/media-picker.png b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/media-picker.png
new file mode 100644
index 00000000000..0c52763cd41
Binary files /dev/null and b/16/umbraco-cms/fundamentals/backoffice/property-editors/images/media-picker.png differ
diff --git a/16/umbraco-cms/fundamentals/backoffice/sections.md b/16/umbraco-cms/fundamentals/backoffice/sections.md
new file mode 100644
index 00000000000..53fac242ebc
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/sections.md
@@ -0,0 +1,131 @@
+---
+description: >-
+ In this article you can learn more about the various sections you can find
+ within the Umbraco Backoffice.
+---
+
+# Sections
+
+A section in Umbraco is where you perform specific tasks related to a particular area of Umbraco. For example, Content, Settings, and Users are all sections. You can navigate between the different sections by clicking the corresponding icon in the section menu positioned at the top of the Backoffice.
+
+
+
+Below is a short overview of the default sections in Umbraco CMS:
+
+## Content
+
+The Content section contains the content nodes that make up the website. Content is displayed as nodes in the Content tree.
+
+Nodes in Umbraco can display the following content states:
+
+* Grayed-out nodes are not published yet.
+* Nodes that are currently locked using the Public Access feature.
+* Content nodes that contain a collection of nodes.
+
+To create content, you must define it using Document Types.
+
+For more information, see the [Defining Content](../data/defining-content/) article.
+
+## Media
+
+The Media section contains the media for the website. You can create folders and upload media files, such as images and PDFs. Additionally, you can customize the existing Media Types or define your own from the Settings section.
+
+For more information, see the [Creating Media](../data/creating-media/) article.
+
+## Settings
+
+The Settings section allows you to manage website layout files, languages, media, and content types. It also gives you access to more advanced features such as the Log Viewer and extension insights.
+
+The Settings section consists of:
+
+**Structure**
+
+* Document Types
+* Media Types
+* Member Types
+* Data Types
+* Languages
+* Document Blueprints
+
+**Templating**
+
+* Templates (`.cshtml` files)
+* Partial views (`.cshtml` files)
+* Stylesheets (`.css` files)
+* Scripts (`.js` files)
+
+**Advanced**
+
+* Relations
+* Log Viewer
+* Extension Insights
+* Webhooks
+
+The **Settings** section in the Umbraco backoffice has its own set of default dashboards.
+
+For more information, see the [Settings Dashboards](settings-dashboards.md) article.
+
+## Packages
+
+In this section, you can browse the different packages available for your Umbraco solution. You can also get an overview of all the packages you have installed or created.
+
+For more information, see the [Packages](../../extending/packages/) article.
+
+## Users
+
+The Users section allows administrators to manage user accounts, assign permissions, set user roles, and monitor user activity within the backoffice. It provides control over who can access and modify content, media, and settings in the CMS.
+
+For more information, see the [Users](../data/users/README.md) article.
+
+## Members
+
+The Members section allows to create and manage member profiles, set up member groups, and control Member's access to restricted content on the website.
+
+For more information, see the [Members](../data/members.md) article.
+
+## Dictionary
+
+The Dictionary section is where you create and manage Dictionary Items. By managing these dictionary items, you can ensure consistent and efficient content translation and maintenance across different languages.
+
+For more information, see the [Dictionary Items](../data/dictionary-items.md) article.
+
+## Add-Ons
+
+To enhance Umbraco's functionality, you can integrate plugins and extensions tailored to specific needs. These add-ons expand Umbraco's capabilities, allowing for a more customized and powerful content management experience.
+
+For example, you can start with core Umbraco features and later decide to integrate additional products. Currently, Umbraco supports add-on products like:
+
+* **Forms:** Simplifies the creation and management of Forms.
+* **Deploy:** Facilitates smooth deployment processes.
+* **Workflow:** Enhances content workflows and approval processes.
+* **Commerce:** Adds e-commerce capabilities to your site.
+* **UI Builder:** Helps in designing and customizing the user interface.
+
+When you add an add-on product to Umbraco, it appears in the Backoffice as a new section, seamlessly extending your content management capabilities.
+
+
+
+If you wish to explore the unique features and use cases of Umbraco products, see the [Exploring the Umbraco Products](https://docs.umbraco.com/welcome/getting-started/exploring-the-umbraco-products) article.
+
+For more information about extending the Umbraco platform through packages and integrations, see the [Umbraco DXP](https://docs.umbraco.com/umbraco-dxp) documentation.
+
+## Help Section
+
+The Help section in Umbraco provides documentation and resources to assist in understanding and effectively using the Umbraco CMS. It typically includes the following in the _Getting Started_ Dashboard:
+
+* **Documentation**: Comprehensive guides, tutorials, and references covering different aspects of Umbraco.
+* **Community Forums**: Access to forums where you can ask questions, share knowledge, and seek assistance from other Umbraco community members.
+* **Resources**: Stay updated with the latest news, access documentation, watch free video tutorials, and register for live demos.
+* **Training**: Learn how to effectively use Umbraco through structured courses, webinars, and hands-on tutorials designed to enhance your proficiency with the CMS.
+
+The Help section serves as a valuable resource hub in navigating and leveraging the capabilities of the Umbraco CMS effectively.
+
+## Custom Sections
+
+Along with the default sections that come with Umbraco, you can create your own [Custom Sections](../../customizing/extending-overview/extension-types/sections/section.md).
+
+## Access based on User Group
+
+A User can access a particular section based on the User Group permissions.
+
+Learn more about how to configure the permissions in the article about [backoffice users](../data/users/README.md).
diff --git a/16/umbraco-cms/fundamentals/backoffice/settings-dashboards.md b/16/umbraco-cms/fundamentals/backoffice/settings-dashboards.md
new file mode 100644
index 00000000000..edfc19505c0
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/settings-dashboards.md
@@ -0,0 +1,112 @@
+---
+description: >-
+ A guide displaying the options available in the Settings section in Umbraco
+ CMS backoffice.
+---
+
+# Settings Dashboards
+
+The **Settings** section of the Umbraco backoffice has its own set of default dashboards. In this article, you can get an overview of each dashboard available in the **Settings** section:
+
+
+
+Welcome
+
+The Welcome dashboard is the first dashboard in the Settings section. Like all dashboards, it has a customizable view and links to different resources for developing your Umbraco website.
+
+For more information about creating custom dashboards, see the [Dashboards](../../customizing/extending-overview/extension-types/dashboard.md) article.
+
+
+
+
+
+Examine Management
+
+The Examine Management dashboard provides an overview of the Examine functionality available directly within the Umbraco backoffice. The Umbraco backoffice allows you to view details about your Examine indexes and searchers - all in one place. You can see which fields are being indexed and rebuild the indexes if there's a problem. You can also test keywords to see what results will be returned.
+
+For more information about Examine Management, see the [Examine Management](../../reference/searching/examine/examine-management.md) article.
+
+
+
+
+
+Published Status
+
+The Published Status dashboard displays the status of your site in the Published Cache Status section alongside the Content and Media nodes value. The Caches section provides three options: Memory Cache, Database Cache, and Internals.
+
+* Memory Cache - Reloads the in-memory cache by entirely reloading it from the database cache. Use it when you think that the memory cache has not been properly refreshed.
+* Database Cache - Rebuilds the database cache that is the content of the `cmsContentNu` table. Use it when reloading the Memory Cache is not enough and you think that the database cache has not been properly generated.
+* Internals - Lets you trigger a NuCache snapshots collection.
+
+{% hint style="info"%}
+As of Umbraco 15 `IPublishedSnapshot`, `IPublishedSnapshotAccessor`, and `SnapshotCache` are all obsolete.
+{%endhint%}
+
+
+
+
+
+Models Builder
+
+Models builder is a tool that can generate a complete set of strongly-typed published content models for Umbraco. Models are available in both controllers and views. When using the Models Builder, the content cache does not return `IPublishedContent` objects anymore but returns strongly typed models implementing `IPublishedContent`.
+
+The Models Builder dashboard displays the following information:
+
+* Details on how Models Builder is configured, that is: `InMemoryAuto`, `Nothing`, `SourceCodeAuto`, and `SourceCodeManual`.
+* Provides a button to generate models (if the models mode is `SourceCodeManual` mode only).
+* Reports the last error (if any) that would have prevented models from being properly generated.
+
+For more information about Models Builder, see the [Models Builder](../../reference/templating/modelsbuilder/) article.
+
+
+
+
+
+Health Check
+
+Health Checks are used to determine the status of your Umbraco project. It is a handy list of checks to see if your Umbraco installation is configured according to best practices. It's possible to add your custom-built health checks.
+
+For more information about Health Checks, see the [Health Check](../../extending/health-check/) articles.
+
+
+
+
+
+Profiling
+
+You can use the built-in performance profiler to assess the performance when rendering pages. To activate the profiler for a specific page rendering, add `umbDebug=true` to the querystring when requesting the page.
+
+The Profiling dashboard provides a toggle option - `Activate the profiler by default` to keep the profiler active by default for all page renderings. You can use this option without having to set `umbDebug=true` on each page request. The toggle button sets a cookie named `UMB-DEBUG` in your browser, which then activates the profiler automatically.
+
+For more information about MiniProfiler, see the [MiniProfiler](../code/debugging/#miniprofiler) section in the [Debugging](../code/debugging/) article.
+
+
+
+
+
+Telemetry Data
+
+The Telemetry Data dashboard is a consent screen that is used for collecting system and usage information from your installation. Here, you can see what type of data is being collected and even adjust the level of reporting. Currently, there are three levels available: **Minimal**, **Basic**, and **Detailed**.
+
+**Detailed** is the default option where the data sent contains:
+
+* Anonymized site ID, Umbraco version, and packages installed.
+* Number of: Root nodes, Content nodes, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, and Property Editors in use.
+* System information: Webserver, server OS, server framework, server OS language, and database provider.
+* Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, and if you are in debug mode.
+
+**Basic** contains:
+
+* Anonymized site ID, Umbraco version, and packages installed.
+
+**Minimal** contains:
+
+* Anonymized site ID only
+
+You can see the specific data being sent on each of the levels directly in the **Telemetry Data** Dashboard.
+
+Additionally, Telemetry Data also sends anonymized, analytical data on package usage in Umbraco. Having solid data on package usage is important for both package developers and the Umbraco ecosystem.
+
+For more information about Package Telemetry, see the [Package Telemetry](https://umbraco.com/blog/umbraco-92-release/) section in the Umbraco 9.2 Release Blog Post.
+
+
diff --git a/16/umbraco-cms/fundamentals/backoffice/sidebar.md b/16/umbraco-cms/fundamentals/backoffice/sidebar.md
new file mode 100644
index 00000000000..9afdd23c903
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/sidebar.md
@@ -0,0 +1,23 @@
+---
+description: >-
+ This section explains how the concept of infinite editing using the Sidebar in the Umbraco
+ backoffice works.
+---
+
+# Sidebar
+
+{% hint style="info" %}
+Sidebar was previously called Infinite editor.
+{% endhint %}
+
+This feature enables you to work with your content without losing the context of what you are doing.
+
+Document Types are in different sections than content but the sidebar enables you to make changes to them directly from the content you are editing.
+
+
+
+In the example showcased above, new options are being added to a Data Type, without losing the context of the content. The example also shows how you can edit images, without being sent to the 'Media' section.
+
+## Customize
+
+The sidebar is a feature that comes out of the box with Umbraco. The feature can be customized, which enables you as a developer to improve the workflow for your editors.
diff --git a/16/umbraco-cms/fundamentals/backoffice/variants.md b/16/umbraco-cms/fundamentals/backoffice/variants.md
new file mode 100644
index 00000000000..c908541958a
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/backoffice/variants.md
@@ -0,0 +1,107 @@
+---
+description: >-
+ Learn how to use language variants to output your content in multiple
+ languages.
+---
+
+# Language Variants
+
+Language Variants allows you to vary content by culture, so you can allow a content node to exist in multiple languages.
+
+This article will cover the different aspects of enabling and working with language variants on your Umbraco website.
+
+## Contents
+
+* [Video tutorial](variants.md#video-tutorial)
+* [How to enable Language Variants](variants.md#how-to-enable-language-variants)
+* [Enabling Language Variants on Document Types](variants.md#enabling-language-variants-on-document-types)
+* [Working with Language Variants on content](variants.md#working-with-language-variants-on-content)
+* [Test your language variants](variants.md#test-your-language-variants)
+* [Control User Group permissions on language variants](variants.md#control-user-group-permissions-on-language-variants)
+* [Related Links](variants.md#related-links)
+
+## Video tutorial
+
+{% embed url="https://www.youtube.com/watch?ab_channel=UmbracoLearningBase&v=TWLqt-jVdyQ" %}
+How to use Language Variants in Umbraco
+{% endembed %}
+
+## How to enable Language Variants
+
+To work with Language Variants you need to have more than one language enabled. This can be done from the `Settings` section:
+
+
+
+{% hint style="info" %}
+You will always have one default language but each language can be set to mandatory.
+{% endhint %}
+
+## Enabling Language Variants on Document Types
+
+Now that there are two languages to vary the content with, it needs to be enabled on the Document Types. To do so:
+
+1. Go to the Document Type in the **structure** section.
+2. Open the **settings** page.
+3. Toggle **Allow vary by culture**.
+
+
+
+To allow a property on the Document Type to be varied it will have to be enabled for the property:
+
+
+
+## Working with Language Variants on content
+
+When you return to your content node you will notice two things:
+
+1. At the top of the Content tree there will now be a dropdown so you can show the Content tree in the language of your choice.
+2. To the right of the content name there is now a dropdown where you can select a language. You can also open a split view so you can see two languages at once.
+
+ 
+
+Each Property Editor that does not allow variants (an Invariant Property) will by default need to be unlocked in order to be edited. The lock exists to make it clear that this change will affect more languages. Since the value of the invariant properties are shared between all variants on the website.
+
+
+
+{% hint style="info" %}
+Whether or not the lock is enabled on the invariant properties depends on the `AllowEditInvariantFromNonDefault` setting in the `appsettings.json` file.
+
+For projects created on Umbraco version 10.2 or later, the setting is `true`, by default. If the project is upgraded to version 10.2 or later, the setting will by default be `false`.
+
+Learn more about the `AllowEditInvariantFromNonDefault` setting in the [Security Settings](../../reference/configuration/securitysettings.md) article.
+{% endhint %}
+
+To read about how you render variant content in Templates, check out the [rendering content section](../design/rendering-content.md).
+
+## Test your language variants
+
+Culture and hostnames must be added to your language sites before the content can be tested for variants:
+
+1. Click **...** next to the Home node and select **Culture and Hostnames**.
+2. Add a specific URL per language and save. For eg: An English language variant with English (United States) as the language can be given a specific URL `https://yourwebsite.com/en-us` and a Danish language variant can be given a specific URL `https://yourwebsite.com/dk`.
+
+The Info content app should now show specific URLs for your language variants.
+
+## Control User Group permissions on language variants
+
+{% hint style="info" %}
+This feature is available from Umbraco version 10.2.
+{% endhint %}
+
+When you are working with a multilingual site you might want to control who can edit the different variations of the content on the website.
+
+This can be controlled on a User Group level. All default User Groups, except the Sensitive data group, have access to all languages out of the box.
+
+When "Allow access to all languages" is not checked, languages can be added and/or removed. This is to determine which variants the users in the user group have access to.
+
+
+
+{% hint style="info" %}
+Even though the language permissions have been set, a user will still be able to view and browse all the language variations. The permission setting will ensure that only the added languages are editable by users of the User Group.
+{% endhint %}
+
+## Related Links
+
+* [Umbraco 8: Language Variants (official blog post from Umbraco HQ)](https://umbraco.com/blog/umbraco-8-language-variants/)
+* [Language variations](../../reference/language-variation.md)
+* [Render varied content in Templates](../design/rendering-content.md)
diff --git a/16/umbraco-cms/fundamentals/code/README.md b/16/umbraco-cms/fundamentals/code/README.md
new file mode 100644
index 00000000000..f39d3031a5f
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/README.md
@@ -0,0 +1,21 @@
+# Code
+
+## [Using Umbraco's Service APIs](umbraco-services.md)
+
+Create and update entities in Umbraco from code.
+
+## [Subscribing to Notifications](subscribing-to-notifications.md)
+
+Subscribe to notifications to execute custom code on a number of operations.
+
+## [Creating Forms](creating-forms.md)
+
+Create, submit and handle HTML forms with controllers.
+
+## [Debugging your Umbraco site](debugging/README.md)
+
+Using Tracing and MiniProfiler to debug your code.
+
+## [Source/Version Control](source-control.md)
+
+General advice on source controlling your Umbraco implementation.
diff --git a/16/umbraco-cms/fundamentals/code/creating-forms.md b/16/umbraco-cms/fundamentals/code/creating-forms.md
new file mode 100644
index 00000000000..c7eb94a7728
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/creating-forms.md
@@ -0,0 +1,126 @@
+---
+description: "Information on creating forms in Umbraco"
+---
+
+
+# Creating Forms
+
+Creating forms requires that you know your way around .NET Core MVC. So if you are familiar with adding view models, views and controllers you are ready to make your first form.
+
+{% hint style="info" %}
+You can also use [Umbraco forms](https://umbraco.com/products/umbraco-forms/). It lets you and/or your editors create and handle forms in the backoffice. This includes setting up validation, redirecting and storing and sending form data. Great UI, extendable and supported by Umbraco HQ.
+{% endhint %}
+
+In this example we'll create a basic contact form containing a name, email and message field.
+
+## Creating the view model
+
+First, we're going to create the model for the contact form by adding a new class to the `/Models` folder. If the folder doesn't already exist, create it at the root of your website. Let's call it `ContactFormViewModel.cs`
+
+```csharp
+namespace MyFirstForm.Models;
+
+public class ContactFormViewModel
+{
+ public string Name { get; set; }
+ public string Email { get; set; }
+ public string Message { get; set; }
+}
+```
+
+Build your solution after adding the model.
+
+### Creating the view
+
+Next, we add the view for the form to the `/View/Partials` folder. Because we've added the model and built the solution we can add it as a strongly typed view.
+
+Name your view "ContactForm".
+
+The view can be built with standard MVC helpers:
+
+```csharp
+@using MyFirstForm.Controllers
+@model MyFirstForm.Models.ContactFormViewModel
+
+@using (Html.BeginUmbracoForm(nameof(ContactFormController.Submit)))
+{
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+```
+
+### Adding the controller
+
+Finally, we're going to add the controller. Create a new empty class in the `/Controllers` folder (if the folder doesn't already exist, create it at the root of the website). Name it `ContactFormController` and make it inherit from `SurfaceController`. Inheriting from `SurfaceController` requires that you call its base constructor. If you are using an IDE: Integrated Development Environment, this can be done automatically.
+
+```csharp
+using Microsoft.AspNetCore.Mvc;
+using MyFirstForm.Models;
+using Umbraco.Cms.Core.Cache;
+using Umbraco.Cms.Core.Logging;
+using Umbraco.Cms.Core.Routing;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Web;
+using Umbraco.Cms.Infrastructure.Persistence;
+using Umbraco.Cms.Web.Website.Controllers;
+
+namespace MyFirstForm.Controllers;
+
+public class ContactFormController : SurfaceController
+{
+ public ContactFormController(
+ IUmbracoContextAccessor umbracoContextAccessor,
+ IUmbracoDatabaseFactory databaseFactory,
+ ServiceContext services,
+ AppCaches appCaches,
+ IProfilingLogger profilingLogger,
+ IPublishedUrlProvider publishedUrlProvider)
+ : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
+ {}
+
+ [HttpPost]
+ public IActionResult Submit(ContactFormViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return CurrentUmbracoPage();
+ }
+
+ // Work with form data here
+
+ return RedirectToCurrentUmbracoPage();
+ }
+}
+```
+
+If the model state is invalid, `CurrentUmbracoPage()` will send the user back to the form. If valid, you can work with the form data, for example, sending an email to site admin and then `RedirectToCurrentUmbracoPage();`.
+
+## Adding the form to a template
+
+You can add the form to a template by rendering the partial view:
+
+```csharp
+@using MyFirstForm.Models;
+
+@{
+ Html.RenderPartial("~/Views/Partials/ContactForm.cshtml", new ContactFormViewModel());
+}
+```
+
+### More information
+
+- [Surface Controllers](../../reference/routing/surface-controllers/README.md)
+- [Custom controllers](../../reference/routing/custom-controllers.md)
+- [Routing](../../reference/routing/README.md)
diff --git a/16/umbraco-cms/fundamentals/code/debugging/README.md b/16/umbraco-cms/fundamentals/code/debugging/README.md
new file mode 100644
index 00000000000..317cc2df3dd
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/debugging/README.md
@@ -0,0 +1,128 @@
+# Debugging
+
+During the development of your Umbraco site you can debug and profile the code you have written to analyse and discover bottlenecks in your code.
+
+To perform proper debugging on your site you need to set your application to have debug enabled. This can be done by setting `Umbraco:CMS:Hosting:Debug="true"` for example in the `appsettings.json` file:
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Hosting": {
+ "Debug": true
+ }
+ }
+ }
+}
+```
+
+{% hint style="warning" %}
+Debug should always be set to false in production.
+{% endhint %}
+
+## Tracing
+
+Tracing and trace logging are two names for the same technique. You need to configure which log messages you want to log.
+
+### Enabling Trace Logging
+
+{% hint style="warning" %}
+Do not enable trace logging in your production environment! It reveals an awful lot of (sensitive) information about your production environment.
+{% endhint %}
+
+We recommend at least logging the following namespace at minimum (Verbose) level to enable valuable trace logging. Thereby you will have information about all endpoints that have been executed.
+
+```json
+{
+ "Serilog": {
+ "MinimumLevel": {
+ "Override": {
+ "Microsoft.AspNetCore.Mvc": "Verbose"
+ }
+ }
+ }
+}
+```
+
+The logged messages can as always be monitored in the log viewer in backoffice
+
+## MiniProfiler
+
+Umbraco includes the Mini Profiler project in its core (see [https://miniprofiler.com](https://miniprofiler.com) for more details). The MiniProfiler profiles your code method calls, giving you a greater insight into code duration and query time for (for example) underlying SQL queries. It's great for tracking down performance issues in your site's implementation.
+
+### Displaying the MiniProfiler
+
+To display the profiler ensure that the configuration `Umbraco:CMS:Hosting:Debug` is set to `true` in the appSettings.json file. Thereafter you can add `?umbDebug=true` to the query string of any request.
+
+Also, ensure your template calls `@Html.RenderProfiler()` as one of the last things.
+
+
+
+If you click 'Show Trivial' you can seen the kind of detail the MiniProfiler makes available to you about the execution path of your page:
+
+
+
+and any underlying SQL Statements that are being executed for a part of the execution:
+
+
+
+
+
+### Writing to the MiniProfiler
+
+If you feel like a part of your application is slow you can use the MiniProfiler in your code to test the speed of it.
+
+All you have to do is inject the IProfiler interface and add a step around your logic:
+
+```csharp
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ViewEngines;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Logging;
+using Umbraco.Cms.Core.Web;
+using Umbraco.Cms.Web.Common.Controllers;
+
+namespace MyCustomUmbracoProject;
+
+public class RootController : RenderController
+{
+ private readonly IProfiler _profiler;
+
+ public RootController(
+ IProfiler profiler,
+ ILogger logger,
+ ICompositeViewEngine compositeViewEngine,
+ IUmbracoContextAccessor umbracoContextAccessor)
+ : base(logger, compositeViewEngine, umbracoContextAccessor)
+ {
+ _profiler = profiler;
+ }
+
+ public override IActionResult Index()
+ {
+ // Perform a step
+ using (_profiler.Step("Sleep"))
+ {
+ System.Threading.Thread.Sleep(1000);
+ }
+
+ return base.Index();
+ }
+}
+```
+
+and now in the profiler you can see:
+
+
+
+## Umbraco Productivity Tool - Chrome Extension
+
+If you are using the Google Chrome browser you can install this [Umbraco Productivity Tool Chrome Extension](https://chrome.google.com/webstore/detail/umbraco-productivity/kepkgaeokeknlghbiiipbhgclikjgkdp?hl=en).
+
+This will allow you to quickly switch between debugging with the MiniProfiler, Trace viewer and normal mode.
+
+
+
+## [Logging](logging.md)
+
+Learn how Umbraco writes log files and how you can write to them.
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/application-trace.png b/16/umbraco-cms/fundamentals/code/debugging/images/application-trace.png
new file mode 100644
index 00000000000..45ab8c78f27
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/application-trace.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/chrome-tool.png b/16/umbraco-cms/fundamentals/code/debugging/images/chrome-tool.png
new file mode 100644
index 00000000000..922074898af
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/chrome-tool.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/miniprofile-warning.png b/16/umbraco-cms/fundamentals/code/debugging/images/miniprofile-warning.png
new file mode 100644
index 00000000000..db8db49a1d2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/miniprofile-warning.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/show-trivial.png b/16/umbraco-cms/fundamentals/code/debugging/images/show-trivial.png
new file mode 100644
index 00000000000..44926efa9b1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/show-trivial.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/trace-logs.png b/16/umbraco-cms/fundamentals/code/debugging/images/trace-logs.png
new file mode 100644
index 00000000000..d6795286e4f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/trace-logs.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/trace-request-details.png b/16/umbraco-cms/fundamentals/code/debugging/images/trace-request-details.png
new file mode 100644
index 00000000000..f698d1f2994
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/trace-request-details.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/umb-debug-equals-true.png b/16/umbraco-cms/fundamentals/code/debugging/images/umb-debug-equals-true.png
new file mode 100644
index 00000000000..abd3463ac8b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/umb-debug-equals-true.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/umbraco-productivity-chrome-extension.png b/16/umbraco-cms/fundamentals/code/debugging/images/umbraco-productivity-chrome-extension.png
new file mode 100644
index 00000000000..6eba3609a87
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/umbraco-productivity-chrome-extension.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/underlying-sql-queries.png b/16/umbraco-cms/fundamentals/code/debugging/images/underlying-sql-queries.png
new file mode 100644
index 00000000000..2ca19c19b50
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/underlying-sql-queries.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-sql-details.png b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-sql-details.png
new file mode 100644
index 00000000000..9535949c1e3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-sql-details.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-sql-trigger.png b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-sql-trigger.png
new file mode 100644
index 00000000000..ea1a4c208c1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-sql-trigger.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-trivial.png b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-trivial.png
new file mode 100644
index 00000000000..7b36e615056
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-trivial.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-view.png b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-view.png
new file mode 100644
index 00000000000..db39a3caab1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-view.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-write.png b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-write.png
new file mode 100644
index 00000000000..cd40b9f107c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-miniprofiler-write.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-trace-details.PNG b/16/umbraco-cms/fundamentals/code/debugging/images/v8-trace-details.PNG
new file mode 100644
index 00000000000..245d2be7418
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-trace-details.PNG differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/v8-trace.PNG b/16/umbraco-cms/fundamentals/code/debugging/images/v8-trace.PNG
new file mode 100644
index 00000000000..5b8f095497b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/v8-trace.PNG differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/images/writing-to-miniprofiler.png b/16/umbraco-cms/fundamentals/code/debugging/images/writing-to-miniprofiler.png
new file mode 100644
index 00000000000..7f9cbcfa123
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/debugging/images/writing-to-miniprofiler.png differ
diff --git a/16/umbraco-cms/fundamentals/code/debugging/logging.md b/16/umbraco-cms/fundamentals/code/debugging/logging.md
new file mode 100644
index 00000000000..467cbec5f41
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/debugging/logging.md
@@ -0,0 +1,153 @@
+# Logging
+
+In Umbraco we use the underlying logging framework of [Serilog](https://serilog.net/).
+
+Out of the box, we write a JSON log file that contains a more detailed logfile. This allows tools to perform searches and correlations on log patterns more efficiently.
+
+The default location of this file is written to `umbraco/Logs` and contains the Machine name, along with the date too:
+
+* `umbraco/Logs/UmbracoTraceLog.DELLBOOK.20210809.json`
+
+## Video overview
+
+{% embed url="" %}
+Watch this video to get an overview of how to view and manage logs and logfiles for your Umbraco CMS website.
+{% endembed %}
+
+## Structured logging
+
+Serilog is a logging framework that allows us to do structured logging or write log messages using the message template format. This allows us to have a more detailed log message, rather than the traditional text message in a long txt file.
+
+```cs
+2021-08-10 09:33:23,677 [P25776/D1/T22] INFO Umbraco.Cms.Core.Services.Implement.ContentService - Document Home (id=1062) has been published.
+```
+
+Here is an example of the same log message represented as JSON. More information is available and allows you to search and filter logs based on these properties with an appropriate logging system.
+
+```json
+{
+ "@t":"2021-08-10T08:33:23.6778640Z",
+ "@mt":"Document {ContentName} (id={ContentId}) has been published.",
+ "ContentName":"Home",
+ "ContentId":1062,
+ "SourceContext":"Umbraco.Cms.Core.Services.Implement.ContentService",
+ "ActionId":"7726d745-d502-4b2d-b55e-97731308041b",
+ "ActionName":"Umbraco.Cms.Web.BackOffice.Controllers.ContentController.PostSave (Umbraco.Web.BackOffice)",
+ "RequestId":"8000000c-0012-fb00-b63f-84710c7967bb",
+ "RequestPath":"/umbraco/backoffice/umbracoapi/content/PostSave",
+ "ProcessId":25776,
+ "ProcessName":"iisexpress",
+ "ThreadId":22,
+ "AppDomainId":1,
+ "AppDomainAppId":"2f4961977e5c252fa708f7d83915c269b53a620c",
+ "MachineName":"DELLBOOK",
+ "Log4NetLevel":"INFO ",
+ "HttpRequestId":"318b6dd4-b127-4da3-8339-37701f4d1416",
+ "HttpRequestNumber":4,
+ "HttpSessionId":"0cea7395-ba29-e6c6-93ee-7c08a2fd7219"
+}
+```
+
+To learn more about structured logging and message templates you can read more about it over on the [https://messagetemplates.org](https://messagetemplates.org) website. Alternatively watch this video from the Serilog creator - [https://www.youtube.com/watch?v=OhmNp8UPEEg](https://www.youtube.com/watch?v=OhmNp8UPEEg)
+
+## Writing to the log
+
+Umbraco writes log messages, but you are also able to use the Umbraco logger to write the log file as needed. This allows you to gain further insights and details about your implementation.
+
+Here is an example of using the logger to write an Information message to the log. It will contain one property, **Name**, which will output the name variable that is passed into the method.
+
+```csharp
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace Umbraco.Cms.Web.UI.NetCore;
+
+[ApiController]
+[Route("/umbraco/api/myapi")]
+public class MyApiController : Controller
+{
+ private readonly ILogger _logger;
+
+ public MyApiController(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ /// /umbraco/api/MyApi/SayHello?name=John
+ [HttpGet("sayhello")]
+ public string SayHello(string name)
+ {
+ _logger.LogInformation("We are saying hello to {Name}", name);
+ return $"Hello {name}";
+ }
+}
+```
+
+{% hint style="info" %}
+If you are Logging and using the MiniProfiler, you can inject `IProfilingLogger` that has a reference to both ILogger and IProfiler.
+{% endhint %}
+
+The incorrect way to log the message would be use string interpolation or string concatenation such as
+
+```csharp
+//GOOD - Do use :)
+_logger.LogInformation("We are saying hello to {Name}", name);
+
+//BAD - Do not use :(
+_logger.LogInformation($"We are saying hello to {name}");
+
+//BAD - Do not use :(
+_logger.LogInformation("We are saying hello to " + name);
+```
+
+The bad examples above will write to the log file, but we will not get a separate property logged with the message. This means we can't find them by searching for log messages that use the message template `We are saying hello to {Name}`
+
+## Log Levels
+
+Serilog uses levels as the primary means for assigning importance to log events. The levels in increasing order of importance are:
+
+1. **Verbose** - tracing information and debugging minutiae; generally only switched on in unusual situations
+2. **Debug** - internal control flow and diagnostic state dumps to facilitate pinpointing of recognised problems
+3. **Information** - events of interest or that have relevance to outside observers; the default enabled minimum logging level
+4. **Warning** - indicators of possible issues or service/functionality degradation
+5. **Error** - indicating a failure within the application or connected system
+6. **Fatal** - critical errors causing complete failure of the application
+
+## Configuration
+
+Serilog can be configured and extended by using the .NET Core configuration such as the AppSetting.json files or environment variables. For more information, see the [Serilog config](../../../reference/configuration/serilog.md) article.
+
+## The logviewer dashboard
+
+Learn more about the [logviewer dashboard](../../backoffice/logviewer.md) in the backoffice and how it can be extended.
+
+## The logviewer desktop app
+
+This is a tool for viewing & querying JSON log files from disk in the same way as the built in log viewer dashboard.
+
+[](https://www.microsoft.com/store/apps/9N8RV8LKTXRJ?cid=storebadge\&ocid=badge)
+
+## Serilog project/references shipped
+
+Umbraco ships with the following Serilog projects, where you can find further information & details with the GitHub readme files as needed.
+
+* [Serilog](https://github.com/serilog/serilog)
+* [Serilog.AspNetCore](https://github.com/serilog/serilog-aspnetcore)
+* [Serilog.Enrichers.Process](https://github.com/serilog/serilog-enrichers-process)
+* [Serilog.Enrichers.Thread](https://github.com/serilog/serilog-enrichers-thread)
+* [Serilog.Expressions](https://github.com/serilog/serilog-expressions)
+* [Serilog.Formatting.Compact](https://github.com/serilog/serilog-formatting-compact)
+* [Serilog.Formatting.Compact.Reader](https://github.com/serilog/serilog-formatting-compact-reader)
+* [Serilog.Settings.Configuration](https://github.com/serilog/serilog-settings-configuration)
+* [Serilog.Sinks.Console](https://github.com/serilog/serilog-sinks-console)
+* [Serilog.Sinks.File](https://github.com/serilog/serilog-sinks-file)
+
+## Further Resources
+
+If you are interested in learning more then the following resources will beneficial:
+
+* [Serilog](https://serilog.net/)
+* [Serilog Community Gitter Chatroom](https://gitter.im/serilog/serilog)
+* [Nicholas Blumhardt Blog, creator of Serilog](https://nblumhardt.com/)
+* [Serilog Pluralsight Course](https://www.pluralsight.com/courses/modern-structured-logging-serilog-seq)
+* [Seq](https://getseq.net/) This is **free** for a single machine such as your own local development computer
diff --git a/16/umbraco-cms/fundamentals/code/images/app-data-folders-version8.png b/16/umbraco-cms/fundamentals/code/images/app-data-folders-version8.png
new file mode 100644
index 00000000000..cc29d42414f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/app-data-folders-version8.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/app-data-folders.png b/16/umbraco-cms/fundamentals/code/images/app-data-folders.png
new file mode 100644
index 00000000000..dee62c605f5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/app-data-folders.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/file-structure-v10.png b/16/umbraco-cms/fundamentals/code/images/file-structure-v10.png
new file mode 100644
index 00000000000..afc7495f8a7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/file-structure-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/folder-structure-v9.jpg b/16/umbraco-cms/fundamentals/code/images/folder-structure-v9.jpg
new file mode 100644
index 00000000000..71612ed5203
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/folder-structure-v9.jpg differ
diff --git a/16/umbraco-cms/fundamentals/code/images/log-message.png b/16/umbraco-cms/fundamentals/code/images/log-message.png
new file mode 100644
index 00000000000..a14351f98d1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/log-message.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/log-messages-v14.png b/16/umbraco-cms/fundamentals/code/images/log-messages-v14.png
new file mode 100644
index 00000000000..b1d64325736
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/log-messages-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/log-messages.png b/16/umbraco-cms/fundamentals/code/images/log-messages.png
new file mode 100644
index 00000000000..ce3872a7669
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/log-messages.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/log-viewer-v14.png b/16/umbraco-cms/fundamentals/code/images/log-viewer-v14.png
new file mode 100644
index 00000000000..c0724c980d0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/log-viewer-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/log-viewer.png b/16/umbraco-cms/fundamentals/code/images/log-viewer.png
new file mode 100644
index 00000000000..d2010ec4570
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/log-viewer.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/typical-umbraco-project-folders-version8.png b/16/umbraco-cms/fundamentals/code/images/typical-umbraco-project-folders-version8.png
new file mode 100644
index 00000000000..0ddebc9768e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/typical-umbraco-project-folders-version8.png differ
diff --git a/16/umbraco-cms/fundamentals/code/images/typical-umbraco-project-folders.png b/16/umbraco-cms/fundamentals/code/images/typical-umbraco-project-folders.png
new file mode 100644
index 00000000000..87561e23c53
Binary files /dev/null and b/16/umbraco-cms/fundamentals/code/images/typical-umbraco-project-folders.png differ
diff --git a/16/umbraco-cms/fundamentals/code/source-control.md b/16/umbraco-cms/fundamentals/code/source-control.md
new file mode 100644
index 00000000000..7b78737f58a
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/source-control.md
@@ -0,0 +1,148 @@
+---
+description: >-
+ In this article you can learn more about how to effectively source control
+ your Umbraco site.
+---
+
+# Source Control
+
+## Umbraco Cloud
+
+When you are running your site on Umbraco Cloud, source control is a part of the experience. Have a look at the ['Technical overview of an Umbraco Cloud Environment'](https://docs.umbraco.com/umbraco-cloud/getting-started/environments) and the information on ['Working with your Umbraco Cloud project'](https://docs.umbraco.com/umbraco-cloud/setup/set-up#working-with-your-umbraco-cloud-project) for a steer on Source/Version Control good practices.
+
+## Outside of Umbraco Cloud
+
+If you are hosting your Umbraco implementation outside of Umbraco Cloud, it's generally considered good practice to set up source/version control for your site implementation files. This is especially a good idea when you are working with a team as it can help you track changes and manage conflicts with other developer's work.
+
+So if you've made the decision to try to attempt to source/version control your Umbraco implementation work, perhaps setting up a ['Git Repository'](https://en.wikipedia.org/wiki/Git) - then a frequently asked question is:
+
+### What folders and files should I **exclude** from my source control repository?
+
+There are lots of different possible variations within your working environment that will affect the best way to set up version control. It depends on whether you are:
+
+* Working with a team of developers.
+* How your development environment is set up.
+* Source control repository.
+* And also how you intend to build and deploy your solution to your target production environment (build servers, Web Deploy or good old File Transfer Protocol (FTP), etc).
+
+However, Umbraco ships with a `.gitignore` file with a custom Umbraco section, which will make git ignore the files for you. The Umbraco specific section looks like this:
+
+```
+##
+## Umbraco CMS
+##
+
+# JSON schema file for appsettings.json
+appsettings-schema.json
+
+# Packages created from the backoffice (package.xml/package.zip)
+/umbraco/Data/CreatedPackages/
+
+# Temp folder containing Examine indexes, MediaCache, etc.
+/umbraco/Data/TEMP/
+
+# SQLite database files
+/umbraco/Data/*.sqlite.db
+/umbraco/Data/*.sqlite.db-shm
+/umbraco/Data/*.sqlite.db-wal
+
+# Log files
+/umbraco/Logs/
+
+# Media files
+/wwwroot/media/
+```
+
+For most projects, this gitignore will be enough, and this article will not be an exhaustive list of how to version control Umbraco in all possible scenarios.
+
+However, we will go through the different files in order to give you an insight into the anatomy of an Umbraco website and therefore which parts to include in version control and which parts not to.
+
+
+
+#### The Umbraco Folder
+
+The main folder where the Umbraco CMS resides is the `/umbraco` one inside your project.
+
+Most of the files and folders within the Umbraco folder, is already added to the default gitignore file. As most of the Umbraco CMS core files are embedded, the `/umbraco` folder contains primarily temporary files and log files, which are all added as Umbraco is installed.
+
+We recommend that you follow the structure of the default gitignore file, and do not include any temporary files, log files or cache files to git.
+
+Below are a set of general recommendations regarding the files within the `/umbraco` folder.
+
+* `/umbraco/data/TEMP` - This folder contains examine indexes, NuCache files, and so on, these are temporary and should not be committed.
+* `/umbraco/Logs` - Umbraco currently uses _Serilog_, and a file will be generated in this folder containing trace logs of your application, one JSON file for each day.
+* `/umbraco/mediacache` - _ImageSharp_ ships with Umbraco and when an image is requested via the processor, for example, to be resized or cropped, a cached version of the transformed image will be stored in this folder. (The [Imaging settings section](../../reference/configuration/imagingsettings.md) allows you to determine where this cache is stored)
+
+#### Umbraco Models Builder
+
+The strategy here will depend a little on which mode ['Umbraco Models Builder'](../../reference/templating/modelsbuilder/) you have opted to work with.
+
+* **InMemoryAuto** (default), The models are generated in memory, no source control is required.
+* **SourceCodeManual** and **SourceCodeAuto**, The models are generated in the `/umbraco/models` folder of your project (or can be configured to be in a different folder or project), allowing you to track changes to the models in source/version control.
+
+#### Media
+
+The Media section of Umbraco (unless configured otherwise) stores files in the `/wwwroot/media` folder. These can be updated by editors, in the Umbraco backoffice, so generally speaking, you would not source control these files.
+
+These are by default ignored by git.
+
+#### Packages and Plugins
+
+The **App\_Plugins** folder is the home for all third-party packages installed on your site.
+
+Depending on how you installed the plugin it will affect how you choose to version control a particular third-party plugin:
+
+Since plugins are installed via NuGet the installed files for individual plugins shouldn't need to be source controlled (and your deployment process should pull the packages implementation files from NuGet during the build and deployment process).
+
+{% hint style="info" %}
+Each plugin could be different depending on its implementation and functionality. It may contain files that it would be useful to track via Source control, and also files that should be ignored: check with the plugin's supporting website/developer for more information.
+{% endhint %}
+
+### What folders and files should I **include** in my source control repository?
+
+#### Front-end build
+
+A lot depends on how you maintain the front-end build of your website, e.g. are you using CSS preprocessors such as Sassy Cascading Style Sheets (SCSS)/ Leaner CSS (LESS) etc - gulp/grunt tasks to combine and minify script resources.
+
+But generally, you will need to source control all your website's static assets: JavaScript, CSS, Fonts, Page Furniture Images, etc.
+
+#### Views/Templates/Partials
+
+Umbraco site templates/views can be edited via the Umbraco Backoffice. They also reside in the `/Views` folder on disk. As these views/templates often include code, it can make a lot of sense to have their changes tracked under source/version control.
+
+However, this can pose a problem if the templates are updated via the backoffice outside of source control on the production environment.
+
+This is not an advisable approach since often this will cause breaking changes to your website.
+
+You would need to manually merge these files before considering a deployment.
+
+Umbraco Cloud is a good solution in these scenarios, as changes via the backoffice are tracked in a Git repository automatically.
+
+#### Controllers/Classes/Custom Code
+
+Any supporting custom code for your application should be in version control, eg any of the following files
+
+* C# implementation,
+ * Surface Controllers
+ * API Controllers
+ * ViewModels
+ * Helpers / Extension Methods
+ * Services etc.
+* Supporting class library projects,
+* Models generated by Modelsbuilder in SourceCodeManual or SourceCodeAuto mode.
+
+#### Config
+
+Your site's `appsettings.json` and `appsettings.Development.json` files contain the configuration for your Umbraco site.
+
+In general, it is recommended to add these to source control. When you do this, be sure that the file(s) doesn't contain any secrets, like API keys and connection strings. These can be added as needed, but omitted from any commits made to source control.
+
+#### DocumentType - Backoffice Structure Changes
+
+When you create and edit eg. Document Types, Media Types, and Data Types in the Umbraco Backoffice these values are stored in the Umbraco Database, making them difficult to source control in a 'file based' version control system.
+
+There are a series of add-on packages that can help add source control to these structure changes:
+
+* [_The uSync package (free)_](https://our.umbraco.com/projects/developer-tools/usync/) - which can be configured to serialize these changes to files on disk, in a folder called /uSync - enabling you to source/version control these changes and synchronise them to other environments.
+* [_uSync Snapshots (licensed)_](https://our.umbraco.com/packages/developer-tools/usyncsnapshots/) - an extension to uSync, for taking 'before' and 'after' snapshots of an Umbraco site, for managing a release of a 'set of changes' between environments.
+* [_Umbraco Deploy on Premise_](https://umbraco.com/products/umbraco-deploy/umbraco-deploy-on-premises/) - the on premise version of the package used by Umbraco Cloud.
diff --git a/16/umbraco-cms/fundamentals/code/subscribing-to-notifications.md b/16/umbraco-cms/fundamentals/code/subscribing-to-notifications.md
new file mode 100644
index 00000000000..f2fbfdc8d12
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/subscribing-to-notifications.md
@@ -0,0 +1,213 @@
+---
+description: >-
+ Subscribing to notifications allows you to listen to specific events and run custom code in response.
+---
+
+# Subscribing To Notifications
+
+Subscribing to notifications allows you to run custom code in response to specific events, such as when the content is created, updated, or deleted. This feature enables you to automate tasks, validate data, log actions, and implement other custom functionalities to enhance your content management system.
+
+To follow this guide, ensure you have an Umbraco installation with content, such as the Umbraco starter kit. In this article, we will walk you through the process of logging a message every time a document is published in Umbraco.
+
+## Create a Notification Handler
+
+We will add a string of text to the log whenever a document is published. This log is useful for debugging, as different parts of the Umbraco codebase log key events, warnings, and errors.
+
+1. Add a new C# class file to your project. For example: **~/App_Plugins/Notifications/LogWhenPublishedHandler.cs**.
+2. Implement the `INotificationHandler` interface to identify this class as a handler for content publication events.
+3. Add the following `using` statements at the top of your file:
+
+ ```csharp
+ using Umbraco.Cms.Core.Events;
+ using Umbraco.Cms.Core.Notifications;
+ ```
+
+Your class should now look like this:
+
+{% code title="LogWhenPublishedHandler.cs" overflow="wrap" lineNumbers="true" %}
+
+```csharp
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Notifications;
+
+namespace MyProject;
+
+public class LogWhenPublishedHandler : INotificationHandler
+{
+ // Here we will handle a notification.
+}
+```
+
+{% endcode %}
+
+## Implement the Handle Method
+
+The `INotificationHandler` interface requires a `Handle` method to be implemented.
+
+Use the code snippet below to implement the `Handle` method, which takes a `ContentPublishedNotification` parameter. This method will contain the custom logic that runs after content is published.
+
+{% code title="LogWhenPublishedHandler.cs" overflow="wrap" lineNumbers="true" %}
+
+```csharp
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Notifications;
+
+namespace MyProject;
+
+public class LogWhenPublishedHandler : INotificationHandler
+{
+ public void Handle(ContentPublishedNotification notification)
+ {
+ // The custom code to fire every time content is published goes here!
+ throw new System.NotImplementedException();
+ }
+}
+```
+
+{% endcode %}
+
+## Inject a Logger for Logging
+
+To log messages, we need to inject a `Microsoft ILogger` into the handler.
+
+1. Add a `using` statement for the `Microsoft.Extensions.Logging` namespace to your file.
+2. Add a constructor to the handler class that accepts an `ILogger` instance.
+
+Your updated class should look like this:
+
+{% code title="LogWhenPublishedHandler.cs" overflow="wrap" lineNumbers="true" %}
+
+```csharp
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Notifications;
+
+namespace MyProject;
+
+public class LogWhenPublishedHandler : INotificationHandler
+{
+ private readonly ILogger _logger;
+
+ public LogWhenPublishedHandler(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public void Handle(ContentPublishedNotification notification)
+ {
+ // The custom code to fire every time content is published goes here!
+ throw new System.NotImplementedException();
+ }
+}
+```
+
+{% endcode %}
+
+## Log the Content Publication
+
+Now that we have a logger, let us use it to log a message every time content is published.
+
+Use the code snippet below to replace the `NotImplementedException` with the code that logs the publication event.
+
+{% code title="LogWhenPublishedHandler.cs" overflow="wrap" lineNumbers="true" %}
+
+```csharp
+public void Handle(ContentPublishedNotification notification)
+{
+ // The custom code to fire every time content is published goes here!
+ _logger.LogInformation("Something has been published.");
+ foreach (var publishedItem in notification.PublishedEntities)
+ {
+ _logger.LogInformation("{ContentName} was published", publishedItem.Name);
+ }
+}
+```
+
+{% endcode %}
+
+
+
+See the entire handler class: LogWhenPublishedHandler.cs
+
+{% code title="LogWhenPublishedHandler.cs" overflow="wrap" lineNumbers="true" %}
+
+```csharp
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Notifications;
+
+namespace MyProject;
+
+public class LogWhenPublishedHandler : INotificationHandler
+{
+ private readonly ILogger _logger;
+
+ public LogWhenPublishedHandler(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public void Handle(ContentPublishedNotification notification)
+ {
+ _logger.LogInformation("{ContentName} was published", publishedItem.Name);
+ }
+}
+```
+
+{% endcode %}
+
+
+
+## Register the Notification Handler
+
+Umbraco needs to know that our handler exists and that it handles `ContentPublishedNotification`. We need to register it in the **Program.cs** file.
+
+{% hint style="info" %}
+Registering dependencies and extensions like this can be done using different methods. Which method to use in each situation depends on whether the extension is added to the Umbraco site or a package.
+
+Learn more about registering dependencies in the [Dependency Injection](../../reference/using-ioc.md) article.
+{% endhint %}
+
+1. Open the **Program.cs** file at the root of the project.
+2. Add the `using Umbraco.Cms.Core.Notifications;` statement.
+
+ ```csharp
+ using Umbraco.Cms.Core.Notifications;
+ ```
+
+3. Register the handler in the builder configuration by adding the `.AddNotificationHandler()` method call.
+
+ The registration should look like this:
+
+ ```csharp
+ builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .AddNotificationHandler()
+ .Build();
+ ```
+
+## Publishing Content and Verifying Custom Log Messages
+
+1. Access the Umbraco backoffice and publish a piece of content.
+2. Check the log messages in the **Log Viewer** under the **Settings** section.
+
+ 
+
+3. Search **All Logs**.
+
+If everything is set up correctly you will see your custom log messages.
+
+
+
+## Additional Notes
+
+* The code in this article logs a message after content is published because we subscribed to `ContentPublishedNotification`.
+* If you need to run code before content is published, you can subscribe to `ContentPublishingNotification` instead.
+* This pattern applies to other events as well, such as **Saving**, **Saved**, **Copying**, **Copied** and so on.
+
+## More Information
+
+* For further details on Notifications in Umbraco, see the [Using Notifications](../../reference/notifications/README.md) article.
diff --git a/16/umbraco-cms/fundamentals/code/umbraco-services.md b/16/umbraco-cms/fundamentals/code/umbraco-services.md
new file mode 100644
index 00000000000..9c2535c8b88
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/code/umbraco-services.md
@@ -0,0 +1,224 @@
+# Service APIs
+
+_Whenever you need to modify an entity that Umbraco stores in the database, there are service APIs available to help you. This means that you can create, update and delete any of the core Umbraco entities directly from your custom code._
+
+## Accessing the Umbraco services
+
+Services are typically defined using interfaces. Umbraco has them in the `Umbraco.Cms.Core.Services` namespace, while the specific implementations can be found under the `Umbraco.Cms.Core.Services.Implement` namespace. To use the service APIs you must first access them. Owing to the built-in dependency injection (DI) in ASP.NET Core, configured services are made available throughout Umbraco's codebase. This can be achieved via injecting the specific service you require - the service type or an interface.
+
+### Access via a Controller
+
+If you are accessing Umbraco services inside your own controller class, you can add the Umbraco services that you need as constructor parameters. An instance of every service will be provided at runtime from the service container. By saving each one to a local field, you can make use of them within the scope of your class:
+
+```csharp
+public class CustomController
+{
+ private readonly IContentService _contentService;
+
+
+ public ContentController(IContentService contentService)
+ {
+ _contentService = contentService;
+ }
+
+
+ public ActionResult PerformAction()
+ {
+ var someContent = _contentService.GetById(1234);
+ }
+}
+```
+
+### Access via a Razor View Template
+
+Inside a Razor View template, you can make use of a service injection into a view using the `@inject` directive. It works similarly to adding a property to the view, and populating the property using DI:
+
+```csharp
+@using Umbraco.Cms.Core.Services
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+@inject IPublicAccessService PublicAccessService
+@{
+ Layout = "master.cshtml";
+ bool isPageProtected = PublicAccessService.IsProtected(Model.Path);
+}
+@if (isPageProtected)
+{
+
Secret Page - shhshshsh!
+}
+```
+
+### Access in a Custom Class via dependency injection
+
+If we wish to subscribe to notifications on one of the services, we'd create a Composer C# class, where you will add a custom `NotificationHandler`. In this custom `NotificationHandler` we would inject the service we need into the public constructor of the class and Umbraco's. The underlying dependency injection framework will do the rest.
+
+In this example we will wire up to the ContentService 'Saved' event. We will create a new folder in the Media section whenever a new LandingPage is created in the content section to store associated media. Therefore we will need the MediaService available to create the new folder.
+
+```csharp
+public class CustomComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.AddNotificationHandler();
+ }
+}
+```
+
+```csharp
+using System.Linq;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Notifications;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Core.Events;
+
+public class CustomNotificationHandler : INotificationHandler
+{
+ // access to the MediaService by injection
+ private readonly IMediaService _mediaService;
+ private readonly IRuntimeState _runtimeState;
+
+ public CustomNotificationHandler(IMediaService mediaService, IRuntimeState runtimeState)
+ {
+ _mediaService = mediaService;
+ _runtimeState = runtimeState;
+ }
+
+ public void Handle(ContentSavedNotification notification)
+ {
+ if (_runtimeState.Level != RuntimeLevel.Run)
+ {
+ return;
+ }
+
+ foreach (var contentItem in notification.SavedEntities)
+ {
+ // if this is a new landing page create a folder for associated media in the media section
+ if (contentItem.ContentType.Alias == "landingPage")
+ {
+ // we have injected in the mediaService in the constructor for the component see above.
+ bool hasExistingFolder = _mediaService.GetByLevel(1).Any(f => f.Name == contentItem.Name);
+ if (!hasExistingFolder)
+ {
+ // let's create one (-1 indicates the root of the media section)
+ IMedia newFolder = _mediaService.CreateMedia(contentItem.Name, -1, "Folder");
+ _mediaService.Save(newFolder);
+ }
+ }
+ }
+ }
+}
+```
+
+#### Custom Class example
+
+When you're creating your own class, in order to make use of the dependency injection framework, you need register the `ICustomNewsArticleService` service with the type `CustomNewsArticleService`. The `AddScoped()` method registers the service with the lifetime of a single request.
+
+There are different ways that you can achieve the same outcome:
+
+Register directly into the **Program.cs** class.
+
+```csharp
+builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .Build();
+
+builder.Services.AddScoped();
+```
+
+Another approach is to create an extension method to `IUmbracoBuilder` and add it to the startup pipeline.
+
+```csharp
+using Microsoft.Extensions.DependencyInjection;
+using Umbraco.Cms.Core.DependencyInjection;
+
+namespace DefaultNamespace;
+
+public static class UmbracoBuilderServiceExtensions
+{
+ public static IUmbracoBuilder AddCustomServices(this IUmbracoBuilder builder)
+ {
+ public static IUmbracoBuilder AddCustomServices(this IUmbracoBuilder builder)
+ {
+ builder.Services.AddScoped();
+
+ return builder;
+ }
+ }
+}
+```
+
+```csharp
+builder.CreateUmbracoBuilder()
+ .AddBackOffice()
+ .AddWebsite()
+ .AddDeliveryApi()
+ .AddComposers()
+ .AddCustomServices()
+ .Build();
+```
+
+When creating Umbraco packages you don't have access to the Startup class, therefore it's recommended to use a `IComposer` instead. A Composer gives you access to the `IUmbracoBuilder`.
+
+If you don't have access to the Startup class
+
+```csharp
+public class CustomComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ builder.Services.AddScoped();
+ }
+}
+```
+
+Then your custom class eg. `CustomNewsArticleService` can take advantage of the same injection to access services eg:
+
+```csharp
+using System.Linq;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Models.PublishedContent;
+using Umbraco.Cms.Core.PublishedCache;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Web;
+
+namespace Umbraco.Cms.Infrastructure.Services.Implement;
+
+public class CustomNewsArticleService: ICustomNewsArticleService
+{
+ private readonly IMediaService _mediaService;
+ private readonly ILogger _logger;
+ private readonly IUmbracoContextFactory _contextFactory;
+
+ public CustomNewsArticleService(ILogger logger, IUmbracoContextFactory contextFactory, IMediaService mediaService)
+ {
+ _logger = logger;
+ _contextFactory = contextFactory;
+ _mediaService = mediaService;
+ }
+
+ public void DoSomethingWithNewsArticles()
+ {
+ using (var contextReference = _contextFactory.EnsureUmbracoContext())
+ {
+ IPublishedContentCache contentCache = contextReference.UmbracoContext.Content;
+ IPublishedContent newsSection = contentCache.GetAtRoot().FirstOrDefault().Children().FirstOrDefault(f => f.ContentType.Alias == "newsSection");
+ if (newsSection == null)
+ {
+ _logger.LogDebug("News Section Not Found");
+ }
+ }
+ // etc
+ }
+}
+```
+
+### More information
+
+* [Services in Umbraco](../../reference/management/)
+* [Umbraco Notifications reference](../../reference/notifications/)
+* [Routes and controllers](../../reference/routing/)
diff --git a/16/umbraco-cms/fundamentals/data/README.md b/16/umbraco-cms/fundamentals/data/README.md
new file mode 100644
index 00000000000..b3a0948ea0b
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/README.md
@@ -0,0 +1,55 @@
+---
+description: This section focuses on how to create data using the Umbraco backoffice
+---
+
+# Data
+
+_This section focuses on how to create data using the Umbraco backoffice._
+
+There are three kinds of content in Umbraco:
+
+* Your normal website content exists in the content section.
+* Media content such as images, videos, and PDFs are stored in the Media section.
+* Finally, Members, are used for user profiles and frontend authentication which you can find in the Members section.
+
+A fundamental principle in Umbraco is that all content types have a definition (Document Types, Media Types, Member Types). These definitions are highly customizable, meaning you can add properties and have complete control over how the data is organized.
+
+## [Defining Content](defining-content/)
+
+Defining Document Types, adding properties, and creating content.
+
+## [Creating Media](creating-media/)
+
+Defining Media Types and uploading files to the media section, using upload fields and image cropper.
+
+## [Creating Members](members.md)
+
+Defining Member Types and creating members for authentication and user profiles.
+
+## [Customizing Data Types](data-types/)
+
+Creating and editing Data Types.
+
+## [Scheduled Publishing](scheduled-publishing.md)
+
+Schedule when content should be published / unpublished automatically.
+
+## [Adding Tabs](adding-tabs.md)
+
+Overview of how to add and reorder tabs, convert a group to a tab, and manage the “Generic” tab
+
+## [Users](users/)
+
+Control who has access to the Umbraco backoffice and what permissions they have.
+
+## [Relations](relations.md)
+
+An introduction to Relations and Relation Types, creating, and managing relationships between different entities in Umbraco.
+
+## [Dictionary Items](dictionary-items.md)
+
+Using Dictionary Items, you can store a value for each language. Dictionary Items have a unique key that is used to fetch the value of the Dictionary Item.
+
+## [Content Version Cleanup](content-version-cleanup.md)
+
+How to keep the noise down whilst ensuring your important content versions stick around indefinitely.
diff --git a/16/umbraco-cms/fundamentals/data/adding-tabs.md b/16/umbraco-cms/fundamentals/data/adding-tabs.md
new file mode 100644
index 00000000000..b998fa4e8e6
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/adding-tabs.md
@@ -0,0 +1,64 @@
+# Using Tabs
+
+In this section, an overview is given of how to add and reorder tabs, convert a group to a tab and manage the “Generic” tab.
+
+## Adding a tab
+
+Using tabs, you can organize properties in the backoffice to provide a tailored and efficient workflow for editors creating and maintaining Content, Media and Members.
+
+Tabs allow you to add horizontal organization in your Document Types, Media Types and Member Types. This is handy for types that need a more defined hierarchy or have many properties and groups.
+
+To add a tab, follow these steps:
+
+1. Go to **Settings**.
+2. Create or select a **Document Type/Media Type/Member Type** and click **Add tab**.
+
+ 
+
+{% hint style="info" %}
+When adding the first tab, all existing groups are automatically added to the tab.
+{% endhint %}
+
+## Reordering tabs
+
+To reorder tabs, follow these steps:
+
+1. Go to **Settings**.
+2. Select a **Document Type/Media Type/Member Type**.
+3. Select **Reorder**.
+4. You can drag the tab where you want, manually add a numeric value next to the tab name or use the arrows to set a value.
+
+ This is important when using compositions, as you want to always display a tab/group at a certain position by setting a manual numeric value.
+
+ 
+5. Select **I am done reordering**.
+6. Click **Save**.
+
+## Convert a group to a tab
+
+To convert a group to a tab, follow these steps:
+
+1. Go to **Settings**.
+2. Select a **Document Type/Media Type/Member Type**.
+3. Select **Reorder**.
+4. You can drag the group to the **Convert to tab** option.
+5. Select **I am done reordering**.
+6. Click **Save**.
+
+{% hint style="info" %}
+Converting a tab back into a group is not possible, as tabs can contain groups, and nested groups are unsupported. To overcome this, create a new group and transfer all tab properties into it, then delete the empty tab.
+{% endhint %}
+
+## Managing the “Generic” tab
+
+Once you start adding tabs, you might see a “Generic” tab appear. This is done to hold groups and properties that are not assigned to a tab. For example, a group of properties coming from a composition that has no tab. In order to display the groups and properties correctly and have a solid data structure, they will be displayed under the “Generic” tab.
+
+
+
+To manage the **Generic** tab on a **Document Type/Media Type**:
+
+1. Go to the **Composition** Document Type/Media Type.
+2. Click **Add tab** and enter the **Name** for the tab. All existing groups and properties are added to the tab.
+3. Go to the **Document Type/Media Type**, the **Generic** tab will now be replaced by the tab from the composition.
+
+ 
diff --git a/16/umbraco-cms/fundamentals/data/content-version-cleanup.md b/16/umbraco-cms/fundamentals/data/content-version-cleanup.md
new file mode 100644
index 00000000000..9cd7197359b
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/content-version-cleanup.md
@@ -0,0 +1,64 @@
+# Content Version Cleanup
+
+A new version is created whenever you save and publish a content item in Umbraco. This is how you can roll back to a previous version. Every saved version stores a record in the database, not only for the version but also for each content item property for that version. In a multi-lingual site, further rows are added for every culture variation. Over time this amount of data can build and swallow up the capacity of your SQL Server and slow the performance of the Umbraco backoffice.
+
+## How it works
+
+The default cleanup policy will:
+
+* Not delete any versions created over the previous 4 days. The recent version history is preserved. See the `KeepAllVersionsNewerThanDays` setting.
+* 'Prune' versions 4 days after they are created. The last version of a content item saved on a particular day will be kept but earlier versions from that day will be deleted.
+* Delete all versions older than 90 days. See the `KeepLatestVersionPerDayForDays` setting.
+* Never delete any versions that are currently 'published'.
+* Never delete any specific versions marked as 'Prevent Cleanup' in the Backoffice version history.
+
+{% hint style="info" %}
+
+Based on the default cleanup policy, you can roll back content to the latest version saved on a particular day as long as it was
+
+* Created within the last 90 days, or
+* Marked as "Prevent Cleanup" in the Backoffice version history.
+
+The **History** section, which acts as an audit log, is not cleared out, and will continue to show logs for versions older than 90 days.
+{% endhint %}
+
+The feature can be configured in the `appSettings.json`:
+
+```json
+{
+ "Umbraco": {
+ "CMS": {
+ "Content": {
+ "ContentVersionCleanupPolicy": {
+ "EnableCleanup": true,
+ "KeepLatestVersionPerDayForDays": 90,
+ "KeepAllVersionsNewerThanDays": 4
+ }
+ }
+ }
+ }
+}
+```
+
+For sites with stricter requirements, it is possible to opt-out of both options globally, see [ContentSettings](../../reference/configuration/contentsettings.md#contentversioncleanuppolicy) and by Document Type.
+
+Additionally, it is possible to keep the feature enabled but mark specific versions to keep forever.
+
+It is worth noting that whilst we delete rows, we do not shrink database files or rebuild indexes. For upgraded sites with a lot of history you may wish to perform these tasks. If they are not part of your regular database maintenance plan already.
+
+## Overriding global settings
+
+It is possible to override the global settings per Document Type in the backoffice to prevent unwanted cleanup. This can be managed in the "permissions" Content App for each Document Type.
+
+
Content Version Cleanup - Document Type overrides
+
+## Prevent cleanup of important versions
+
+It is possible to mark important content versions as "prevent cleanup" to ensure they are never removed. This happens via the new and improved rollback modal which can be found on the "info" content app for each document.
+
+1. Open rollback modal.
+
+
+2. Click **Prevent cleanup** button for each important version.
+
+
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/README.md b/16/umbraco-cms/fundamentals/data/creating-media/README.md
new file mode 100644
index 00000000000..0cf0dbdf0e0
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/creating-media/README.md
@@ -0,0 +1,215 @@
+---
+description: >-
+ Learn how to work with different types of Media content on your Umbraco
+ website.
+---
+
+# Creating Media
+
+Media in Umbraco CMS is handled the same way as content. You define **Media Types** that act as a base for media items. The following default Media Types are available:
+
+* Article - used for uploading and storing documents.
+* Audio - used for uploading and storing digital audio files.
+* File - used for uploading and storing different types of files in the Media section.
+* Folder - a container for organizing media items in the Media section tree.
+* Image - used for uploading and storing images.
+* Vector Graphics (SVG) - used for uploading and storing Scalable Vector Graphics (SVG) files which are text files containing source code to draw the desired image.
+* Video - used for uploading and storing video files.
+
+The default Media Types aim to cover most needs for media on a website. You do not need to define your Media Types to start using the Media section. The tools for organizing and uploading the media are already in place.
+
+{% hint style="info" %}
+If you have upgraded from an older version than 8.14 the Media Types listed above are not added automatically. You can add those types manually yourselves by following the steps below ['Creating a new Media Type'](./#creating-a-media-type). On the [default media types page](default-media-types.md), you will find a detailed overview of all Media Types.
+{% endhint %}
+
+## Uploading Media
+
+You can upload media in two different ways:
+
+* [Through the Media section](./#add-media-through-the-media-section) and
+* [Through the Content section](./#add-media-through-the-content-section)
+
+### Add media through the Media section
+
+From the **Media** section in the Umbraco backoffice, you can add new media items by following either of the approaches defined below:
+
+* Use the **Create** dialog to create a new Media item in the Media section
+
+ * The Media item will be created based on the type you choose.
+ * Upload the image or file, give the Media item a name, and click **Save**.
+
+
Upload Media - Create Button
+* Use the Drag and drop feature to add your files to the Media section.
+
+ * Umbraco will automatically detect the Media Type and create the Media item.
+ * You can drop entire folder structures to recreate that same structure in the Media section.
+
+
Upload Media - Media section
+
+### Add media through the Content section
+
+New media items can be added to your site without interrupting the content creation flow. This can be done following either of the two approaches outlined below.
+
+* Drag and drop the image(s) from your file explorer directly into the Media Picker property on the Content page.
+ * Images added this way is automatically added to the user's start node in the Media section of the Umbraco backoffice.
+
+
+
+* Select the "+" icon to open the "Select media" dialog where you can add images from your file explorer directly or using drag and drop.
+
+
+
+## Creating a folder
+
+It is always a good idea to start by creating a folder for your media items. It can be a good idea to align these folders with the content on your website. This will give the editors a better overview of the files and enable them to upload media items in the correct place.
+
+Follow these steps to create a folder in the Media section:
+
+1. Go to the **Media** section.
+2. Select **...** next to **Media**.
+3. Select **Create**.
+4. Select **Folder**.
+5. Enter a name for the folder and select **Save** in the bottom-right corner.
+
+## Media Type properties
+
+The **Image** Media Type has 5 properties: **Upload Image**, **Width**, **Height**, **Size**, and **Type**. These are populated once the image is uploaded. The properties can be viewed in the **Media** section and accessed in your Templates.
+
+Except for the **Folder** Media Type, the other Media Types have 3 properties: **Upload Image**, **Type**, and **Size**.
+
+Learn more about each Media Type in [the article about default Media Types](default-media-types.md).
+
+## Organizing and editing media items
+
+The default view for the Media section is a card view that lets you preview the different files that have been uploaded.
+
+
Media Section - Cardview
+
+By selecting multiple media items it is possible to perform bulk operations like moving or deleting the items.
+
+To edit properties on a single media item, click the name of the item, which you will see once you hover over the item.
+
+
+
+From the top-right corner of the Media section, you can toggle between the list and grid view. There is also an option to search for the items in the Media section.
+
+
+## Using media items in the Content section
+
+By adding a **Media Picker** property to a Document Type the editor will have the ability to select media items when creating content.
+
+## Creating a Media Type
+
+You can create custom Media Types and control the structure of the Media tree as you would with Document Types. This means you can store information that is specific to the media on the item itself.
+
+### Video tutorial
+
+{% embed url="https://youtu.be/aS39zygmJcQ" %}
+Watch this tutorial and learn how to create your own Media Types in Umbraco CMS.
+{% endembed %}
+
+A Media Type is created in the **Settings** section using the Media Type editor.
+
+1. Go to the **Settings** section.
+2. Click **...** next to **Media Types**.
+3. Click **Create** > **New Media Type**.
+4. Name the new Media Type **Employee Image**.
+5. Choose an icon by selecting the icon left of the name field.
+
+You will now see the Media Type editor. It is similar to the editor used for creating Document Types.
+
+
+
+{% hint style="info" %}
+Having different folders for different Media Types makes it possible to restrict where media items can be created and added. Only allowing PDF uploads in a certain folder and employee images in another make it easier to keep the Media section organized.
+{% endhint %}
+
+### Adding groups
+
+Before we start adding properties to the Media Type we need to add a group to put these in.
+
+1. Click on **Add group**.
+2. Call the group _Image_.
+
+### Adding properties
+
+We need to add the same properties as on the default **Image** Media Type. These are:
+
+* `umbracoFile`
+* `umbracoWidth`
+* `umbracoHeight`
+* `umbracoBytes`
+* `umbracoExtension`
+
+Follow the steps outlined below to add the properties to the Media Type:
+
+1. Click **Add property**.
+2. Name it _Upload image_.
+3. Change the alias to _umbracoFile_.
+4. Click **Select property editor**.
+5. Select **Image cropper**.
+6. Rename the editor _Employee Image Cropper_.
+7. Add two new crops called _Thumbnail_ (200px x 350px) and _wideThumbnail_ (350px x 200px).
+
+ 
+8. Click **Save**.
+9. Click **Add**.
+10. Name the remaining four properties _Width_, _Height_, _Size_, and _Type_, and give them the aliases as mentioned above. They should all use the **Label** editor.
+
+As mentioned before these properties will automatically be populated once an image has been uploaded.
+
+
+
+## Defining a Media Type folder
+
+Next up, we will create a folder to hold the employee images. We could use the existing **Folder** Media Type but that would mean editors can upload employee images to any folder of that type. If we create a folder specifically for employee images there is only one place to put them.
+
+1. Go back to the **Settings** section and create a new Media Type.
+2. Name it _Employee Images_.
+3. Select the folder icon by clicking the icon to the left of the name.
+4. Navigate to the **Structure** tab.
+5. Click **Configure as a Collection** under **Presentation.**
+6. Choose **List view - Media.**
+
+ 
+7. Click **Save**.
+
+The new folder is created under the Media Types folder. We also need to only allow the Employee Image Media Type in our new folder. Both of these configurations can be set on the **Structure** tab.
+
+1. Go to the **Structure** tab of the _Employee Images_ folder.
+2. Toggle the **Allow at root**.
+3. Click **Choose** in the **Allowed Child Node Types**.
+4. Select **Employee Image**.
+5. Click **Choose**.
+
+
+
+### Creating the folder and media items
+
+1. Go to the **Media** section.
+2. Select **...** next to Media.
+3. Click **Create** > **Employee Images** folder.
+ 
+4. Name it _Employee Images_.
+5. Click **Save**.
+
+{% hint style="info" %}
+Uncheck the **Allow at root** option on the **Employee Images** Media Type to prevent the creation of multiple folders of this type. This will only disable the creation of new ones and not affect existing folders.
+{% endhint %}
+
+### Cropping the images
+
+If you select an image that has been uploaded to the folder you will see the full image and the two defined crops.
+
+Moving the focal point circle on the image will update the crops to focus accordingly. You can also edit the individual crops by selecting them and moving the image or adjusting the slider to zoom.
+
+
+
+## More information
+
+* [Rendering Media](../../design/rendering-media.md)
+* [Customizing Data Types](../data-types/)
+
+## Related Services
+
+* [MediaService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.MediaService.html)
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/default-media-types.md b/16/umbraco-cms/fundamentals/data/creating-media/default-media-types.md
new file mode 100644
index 00000000000..e2a4d9fd098
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/creating-media/default-media-types.md
@@ -0,0 +1,79 @@
+# Default Data/Media Types
+
+On this page you will find the media types and Data Types in Umbraco. These types are not created automatically after an upgrade. If you want to use the new types, you can create them yourself.
+
+## Data Types
+
+### UploadArticle
+
+The `UploadArticle` Data Type has the following configuration:
+
+* Property editor: `FileUpload`
+* Accepted file extensions: `pdf`, `docx`, `doc`
+
+### UploadAudio
+
+The `UploadAudio` Data Type has the following configuration:
+
+* Property editor: `FileUpload`
+* Accepted file extensions: `mp3`, `weba`, `oga`, `opus`
+
+### UploadVectorGraphics
+
+The `UploadVectorGraphics` Data Type has the following configuration:
+
+* Property editor: `FileUpload`
+* Accepted file extensions: `svg`
+
+### UploadVideo
+
+The `UploadVideo` Data Type has the following configuration:
+
+* Property editor: `FileUpload`
+* Accepted file extensions: `mp4`, `webm`, `ogv`
+
+## Media Types
+
+### UmbracoMediaArticle
+
+The `UmbracoMediaArticle` media type has the following properties:
+
+* `umbracoFile` - Upload File
+* `umbracoExtension` - Label (string)
+* `umbracoBytes` - Label (bigint)
+
+
+
+### UmbracoMediaAudio
+
+The `UmbracoMediaAudio` media type has the following properties:
+
+* `umbracoFile` Upload Audio
+* `umbracoExtension` Label (string)
+* `umbracoBytes` Label (bigint)
+
+
+
+### UmbracoMediaVectorGraphics
+
+The `UmbracoMediaVectorGraphics` media type has the following properties:
+
+* `umbracoFile` - Upload Vector Graphics
+* `umbracoExtension` Label (string)
+* `umbracoBytes` Label (bigint)
+
+
+
+### UmbracoMediaVideo
+
+The `UmbracoMediaVideo` media type has the following properties:
+
+* `umbracoFile` - Upload Video
+* `umbracoExtension` - Label (string)
+* `umbracoBytes` - Label (bigint)
+
+
+
+{% hint style="info" %}
+You can also create localization files for Media Types. You can read more about this in the [Document Type Localization](../defining-content/document-type-localization.md) article.
+{% endhint %}
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cardview.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cardview.jpg
new file mode 100644
index 00000000000..760ac1a7b27
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cardview.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Compositions.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Compositions.jpg
new file mode 100644
index 00000000000..6d0052c270c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Compositions.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Create-740.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Create-740.jpg
new file mode 100644
index 00000000000..9668165f375
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Create-740.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Create.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Create.jpg
new file mode 100644
index 00000000000..ea2f4646669
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Create.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cropping-740.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cropping-740.jpg
new file mode 100644
index 00000000000..325f6d4dab8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cropping-740.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cropping.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cropping.jpg
new file mode 100644
index 00000000000..e277d81d4a2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Cropping.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Crops-740.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Crops-740.jpg
new file mode 100644
index 00000000000..71b27a6d46b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Crops-740.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Crops.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Crops.jpg
new file mode 100644
index 00000000000..8a4a1048d06
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Crops.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Edit.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Edit.jpg
new file mode 100644
index 00000000000..7da4356a08c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Edit.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Icon.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Icon.jpg
new file mode 100644
index 00000000000..fdc42003a05
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Icon.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Individual-Crop.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Individual-Crop.jpg
new file mode 100644
index 00000000000..5f6b3e3e02f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Individual-Crop.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Listview.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Listview.jpg
new file mode 100644
index 00000000000..7ec1eae7dbe
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Listview.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Permissions.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Permissions.jpg
new file mode 100644
index 00000000000..56f272424e2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Permissions.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Properties-740.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Properties-740.jpg
new file mode 100644
index 00000000000..8f4d2600b9c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Properties-740.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Properties.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Properties.jpg
new file mode 100644
index 00000000000..04e5f1c43cb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Properties.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Structure.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Structure.jpg
new file mode 100644
index 00000000000..b8262a0c516
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Structure.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Tabs.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Tabs.jpg
new file mode 100644
index 00000000000..2eae88d1ce0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Tabs.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Upload-740.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Upload-740.jpg
new file mode 100644
index 00000000000..844927c090c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Upload-740.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Upload.jpg b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Upload.jpg
new file mode 100644
index 00000000000..9db5ba2901e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/Creating-Media-Upload.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/add-image-from-dialog.gif b/16/umbraco-cms/fundamentals/data/creating-media/images/add-image-from-dialog.gif
new file mode 100644
index 00000000000..1b44a15a995
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/add-image-from-dialog.gif differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/configure-collection-v14.png b/16/umbraco-cms/fundamentals/data/creating-media/images/configure-collection-v14.png
new file mode 100644
index 00000000000..bdc9ac877de
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/configure-collection-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-employee.png b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-employee.png
new file mode 100644
index 00000000000..0290519affc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-employee.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type-v14.png b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type-v14.png
new file mode 100644
index 00000000000..c553d42cca0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type.png
new file mode 100644
index 00000000000..34f39e79ed6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type_new.png b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type_new.png
new file mode 100644
index 00000000000..26023a71cbd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/create-new-media-type_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/crops-and-focal-point-geo.png b/16/umbraco-cms/fundamentals/data/creating-media/images/crops-and-focal-point-geo.png
new file mode 100644
index 00000000000..ba6a9b601e5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/crops-and-focal-point-geo.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/employee-images-folder.png b/16/umbraco-cms/fundamentals/data/creating-media/images/employee-images-folder.png
new file mode 100644
index 00000000000..f1e09a83d86
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/employee-images-folder.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/employee-images-permissions.png b/16/umbraco-cms/fundamentals/data/creating-media/images/employee-images-permissions.png
new file mode 100644
index 00000000000..fd2bb2ffdb3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/employee-images-permissions.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/enable-listview.png b/16/umbraco-cms/fundamentals/data/creating-media/images/enable-listview.png
new file mode 100644
index 00000000000..790ff9c94ba
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/enable-listview.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type-v14.png b/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type-v14.png
new file mode 100644
index 00000000000..7ae7b5eb115
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type.png
new file mode 100644
index 00000000000..8ae9b33a6bc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type_new.png b/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type_new.png
new file mode 100644
index 00000000000..f90a6f93128
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/finished-new-media-type_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/folder-composition.png b/16/umbraco-cms/fundamentals/data/creating-media/images/folder-composition.png
new file mode 100644
index 00000000000..84dba14eb8c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/folder-composition.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/folder-composition_new.png b/16/umbraco-cms/fundamentals/data/creating-media/images/folder-composition_new.png
new file mode 100644
index 00000000000..e3a64d14060
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/folder-composition_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/four-ways-of-uploading.png b/16/umbraco-cms/fundamentals/data/creating-media/images/four-ways-of-uploading.png
new file mode 100644
index 00000000000..7695490160b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/four-ways-of-uploading.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/hover-over.png b/16/umbraco-cms/fundamentals/data/creating-media/images/hover-over.png
new file mode 100644
index 00000000000..5e5a75ec5d7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/hover-over.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/media-section-11.png b/16/umbraco-cms/fundamentals/data/creating-media/images/media-section-11.png
new file mode 100644
index 00000000000..a2f9502fd60
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/media-section-11.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type-v14.png b/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type-v14.png
new file mode 100644
index 00000000000..f3d1ddd61d8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type.png
new file mode 100644
index 00000000000..33d36cfec27
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type_new.png b/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type_new.png
new file mode 100644
index 00000000000..5a923f881b0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/new-data-type_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/select-child-nodes.png b/16/umbraco-cms/fundamentals/data/creating-media/images/select-child-nodes.png
new file mode 100644
index 00000000000..3ac9bda9788
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/select-child-nodes.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/switch-view-11.png b/16/umbraco-cms/fundamentals/data/creating-media/images/switch-view-11.png
new file mode 100644
index 00000000000..ec998111774
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/switch-view-11.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/switch-view-v14.png b/16/umbraco-cms/fundamentals/data/creating-media/images/switch-view-v14.png
new file mode 100644
index 00000000000..6fbc1af8ed8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/switch-view-v14.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/toggle-listview.png b/16/umbraco-cms/fundamentals/data/creating-media/images/toggle-listview.png
new file mode 100644
index 00000000000..daa898459a7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/toggle-listview.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-article-media-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-article-media-type.png
new file mode 100644
index 00000000000..fff82eeba5b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-article-media-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-audio-media-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-audio-media-type.png
new file mode 100644
index 00000000000..194c4dc201a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-audio-media-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-vector-graphicsmedia-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-vector-graphicsmedia-type.png
new file mode 100644
index 00000000000..e5957f78e79
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-vector-graphicsmedia-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-video-media-type.png b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-video-media-type.png
new file mode 100644
index 00000000000..a0cdd81bcf0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/umbraco-media-video-media-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/upload-images-from-content.gif b/16/umbraco-cms/fundamentals/data/creating-media/images/upload-images-from-content.gif
new file mode 100644
index 00000000000..9ffe47785c5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/upload-images-from-content.gif differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-create1.png b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-create1.png
new file mode 100644
index 00000000000..5ae33eb69c7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-create1.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-media-section.png b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-media-section.png
new file mode 100644
index 00000000000..fc4077de8b6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-media-section.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-upload-media.png b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-upload-media.png
new file mode 100644
index 00000000000..c2f0750f6df
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types-upload-media.png differ
diff --git a/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types.png b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types.png
new file mode 100644
index 00000000000..db993c3f1e7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/creating-media/images/v9-media-types.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/README.md b/16/umbraco-cms/fundamentals/data/data-types/README.md
new file mode 100644
index 00000000000..f9ce2a8d302
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/data-types/README.md
@@ -0,0 +1,69 @@
+---
+description: Learn about the data types in Umbraco.
+---
+
+# Data Types
+
+_A Data Type defines the type of input for a property. So when adding a property (on Document Types, Media Types and Members) and selecting the Type you are selecting a Data Type. There are preconfigured Data Types available in Umbraco and more can be added in the Settings section._
+
+## What is a Data Type?
+
+A Data Type can be something basic such as TextString, Number, True/False and so on. Or it can be more complex such as Multi Node Tree Picker, Image Cropper, Block Grid and so on.
+
+The Data Type references a Property Editor and if the Property Editor has settings these are configured on the Data Type. This means you can have multiple Data Types referencing the same Property Editor.
+
+An example of this could be to have two dropdown Data Types both referencing the same dropdown Property Editor. One configured to show a list of cities, the other a list of countries.
+
+## Creating a new Data Type
+
+Follow these steps to create a new Dropdown Data Type:
+
+1. Go to the **Settings** section within the backoffice.
+2. Select the **+** icon to the right of the **Data Types** folder.
+3. Choose **New Data Type...**.
+4. Name the Data Type.
+5. Click on **Select a property editor**.
+6. Find and click on the **Dropdown** editor.
+7. Click **Select**.
+8. Choose whether to enable multiple selections.
+9. Add **options**.
+10. **Save** the Data Type once you have added the required configuration.
+
+
+
+{% hint style="info" %}
+**Data Type configuration**
+
+**Property Editor** This is where you pick the Property Editor UI that the Data Type will be referencing. By default, Umbraco ships with a wide selection to choose from. Learn more about each of them in the [Default Data Types](default-data-types.md) article.
+
+In the **Settings** box below, the configuration options specific to the chosen Property Editor UI will be available. Some Property Editors have many configuration options while some only have a few.
+{% endhint %}
+
+When you're happy with the list press **Save**. It is now possible to select this Data Type for a property on Document Types, Media Types, and Members. Doing this will then create a dropdown list for the editor to choose from and save the choice as a string.
+
+## Customizing Data Types
+
+To customize an existing Data Type go to the **Settings** section, expand the **Data Types** folder and select the **Data Type** you want to edit.
+
+Besides the Data Types that are available out of the box there are some additional **Property Editors**. For example, think of the **Slider** and **Block List**.
+
+## Viewing Data Type References
+
+To view the Data Type reference, go to the **Settings** section and expand the **Data Types** folder. Select the **Data Type** you wish to view the reference for and click the **Info** tab.
+
+
+
+This gives you an overview of the Types that currently use the Data Type.
+
+Learn more about viewing references or implementing tracking in the [Tracking References](../../../customizing/property-editors/tracking.md) article.
+
+### More information
+
+* [List of available Data Types](default-data-types.md)
+* [Property Editors](../../backoffice/property-editors/)
+
+### Related Services
+
+* [DataTypeService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.IDataTypeService.html)
+
+### Umbraco Learning Base Channel
diff --git a/16/umbraco-cms/fundamentals/data/data-types/default-data-types.md b/16/umbraco-cms/fundamentals/data/data-types/default-data-types.md
new file mode 100644
index 00000000000..8c9678065f3
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/data-types/default-data-types.md
@@ -0,0 +1,132 @@
+---
+description: Learn about the default data types in Umbraco.
+---
+
+# Default Data Types
+
+Here's a list of the default Data Types that come installed with Umbraco. There are plenty more that you can create based on the installed [Property Editors](../../backoffice/property-editors/).
+
+
+
+## Approved Color
+
+Adds a list of approved colors. The approved colors are added as hex values by using the color picker. Optionally, you can enable labels to give the colors different names.
+
+## Checkbox List
+
+Displays a list of preset options as a list of checkbox controls. The preset options are added when configuring a Property Editor using the Data Type. Alternatively, the options can also be updated in the **Settings** section under **Data Types**. The value saved is a comma-separated string of IDs.
+
+## Content Picker
+
+The Content Picker opens a modal to pick a specific page from the content structure. The value saved is the selected page's ID.
+
+## Date Picker
+
+Displays a calendar UI for selecting date and time. The value saved is a standard DateTime value but does not contain time information.
+
+## Date Picker with time
+
+Displays a calendar UI for selecting date and time. The value saved is a standard DateTime value.
+
+## Dropdown
+
+Displays a list of preset options as a list where only a single value can be selected. The default Data Type does not contain any predefined options. The value saved is the selected value as a string.
+
+## Dropdown multiple
+
+Displays a list of preset options as a list where multiple values can be selected. The default Data Type does not contain any predefined options. The value saved is a comma-separated string of IDs.
+
+## Image Cropper
+
+Allows to upload and crop images by using a focal point. Specific crop definitions can also be added. This Data Type is used by default on the Image Media Type.
+
+## Image Media Picker
+
+The Image Media Picker opens a modal to pick images from the **Media** tree or images from your Computer. The value saved is the selected media node UDI.
+
+## Label
+
+Is a non-editable control and can be used to _only_ display the value. It can also be used in the **Media** section to load in values related to the node, such as width, height and file size.
+
+There are six Label Data Types:
+
+* Label (bigint) - Allows to save a big integer value for a Label.
+* Label (datetime) - Allows to set a DateTime value for a Label.
+* Label (decimal) - Allows to set a decimal value for a Label.
+* Label (integer) - Allows to set an integer value for a Label.
+* Label (string) - Allows to set a long string value for a Label.
+* Label (time) - Allows to set time for a Label
+
+## List View - Content
+
+This Data Type is used by **Document Types** that are set to display as a Collection.
+
+## List View - Media
+
+This Data Type is used by **Media Types** that is set to display as a Collection.
+
+## List View - Members
+
+This Data Type is used by **Member Types** that is set to display as a Collection.
+
+## Media Picker
+
+The picker opens a modal to pick a specific media item from the Media tree. The value saved is the selected media node UDI.
+
+## Member Picker
+
+Displays a dropdown with all the available members. A single member can be selected. The value saved is the ID of the member.
+
+## Multi URL Picker
+
+This Data Type allows an editor to add an array of links. These can either be internal Umbraco pages external URLs or links to media in the Media section. The Data Type can be configured by limited number of links it is possible to add.
+
+## Multiple Image Media Picker
+
+The picker opens a modal to pick multiple images from the **Media** tree. The value saved is a comma separated string of media node UDIs.
+
+## Multiple Media Picker
+
+The picker opens a modal to pick multiple media items from the **Media** tree. The value saved is a comma separated string of media node UDIs.
+
+## Numeric
+
+A textbox to input a numeric value.
+
+## Radiobox
+
+This Data type enables editors to choose from a list of radiobuttons.
+
+## Richtext Editor
+
+A TipTap-based What You See Is What You Get (WYSIWYG) editor. This is the standard editor used to edit a larger amount of text. The editor has a lot of settings, which can be changed on the Richtext editor Data Type in the Settings section.
+
+Learn more about the configuration options in the [Rich Text Editor articles](../../backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/README.md).
+
+## Tags
+
+A textbox that allows you to use multiple tags on a **Document Type**. You can specify a Tag Group for the Data Type, if you need to use Tags on different sections of your site.
+
+## Textarea
+
+A textarea provides a multi-line plain-text editing control. You can set the maximum allowed characters for the textarea and the number of rows, if any.
+
+## Textstring
+
+A normal HTML input text field.
+
+## True/False
+
+A checkbox which saves either 0 or 1, depending on the checkbox being checked or not. A common use is to create a property with the 'umbracoNaviHide' alias and the Data Type True/False. This will provide editors with the option to hide nodes in the navigation menu on the website.
+
+## Upload
+
+Adds an upload field, which allows documents or images to be uploaded to Umbraco. This does not add them to the media library, they are added to the document data.
+
+There are five Upload Data Types:
+
+* Upload Article - Used for uploading and storing documents.
+* Upload Audio - Used for uploading and storing digital audio files.
+* Upload File - Used for uploading and storing different types of files in the Media section
+* Upload Vector Graphics - Used for uploading and storing Scalable Vector Graphics (svg) files which are text files containing source code to draw the desired image.
+* Upload Video - Used for uploading and storing video files.
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/Data-Types-Create.jpg b/16/umbraco-cms/fundamentals/data/data-types/images/Data-Types-Create.jpg
new file mode 100644
index 00000000000..13eda36abaf
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/Data-Types-Create.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/creating-a-data-type-v10.png b/16/umbraco-cms/fundamentals/data/data-types/images/creating-a-data-type-v10.png
new file mode 100644
index 00000000000..6223bf77e2f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/creating-a-data-type-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/creating-a-data-type.png b/16/umbraco-cms/fundamentals/data/data-types/images/creating-a-data-type.png
new file mode 100644
index 00000000000..5df8f2bca42
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/creating-a-data-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types-8.png b/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types-8.png
new file mode 100644
index 00000000000..87060cc586a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types-8.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types-9.png b/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types-9.png
new file mode 100644
index 00000000000..f7341191ae5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types-9.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types.png b/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types.png
new file mode 100644
index 00000000000..fa5455cf48a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/default-data-types.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/dropdown-data-type-sample.png b/16/umbraco-cms/fundamentals/data/data-types/images/dropdown-data-type-sample.png
new file mode 100644
index 00000000000..741b15b8d3b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/dropdown-data-type-sample.png differ
diff --git a/16/umbraco-cms/fundamentals/data/data-types/images/viewing-data-type-reference.png b/16/umbraco-cms/fundamentals/data/data-types/images/viewing-data-type-reference.png
new file mode 100644
index 00000000000..e911c377f9f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/data-types/images/viewing-data-type-reference.png differ
diff --git a/16/umbraco-cms/fundamentals/data/defining-content/README.md b/16/umbraco-cms/fundamentals/data/defining-content/README.md
new file mode 100644
index 00000000000..1349348ac35
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/defining-content/README.md
@@ -0,0 +1,315 @@
+---
+description: Here you'll find an explanation of how content is defined in Umbraco
+---
+
+# Defining Content
+
+Before a piece of content can be created in the Umbraco backoffice, first it needs to be defined. That is why, when opening a blank installation of Umbraco, it is not possible to create content in the **Content** section.
+
+All content needs a blueprint that holds information about what kind of data can be stored on the content node or which editors are used.
+
+Additionally, it also needs information on how it is organized, where in the structure it is allowed, and so forth. This blueprint or definition is called a **Document Type**.
+
+## What is a Document Type?
+
+Document Types define what kind of content can be created in the **Content** section and what an end-user sees and can interact with.
+
+It can define entire pages or more limited content that can be reused on other nodes ie. a Search Engine Optimization (SEO) group. This means that you are in complete control of what type of content can be created and where.
+
+Another example is if there is a "`Blog post`" Document Type that has some properties containing a thumbnail, a name, and an author image. Then all blog posts using the "`Blog post`" Document Type, will allow the end user to fill in a thumbnail, author name, and an author image.
+
+A Document Type contains fieldsets (or groups) where you can apply rules about where the content can be created, allowed template(s), backoffice icons, etc.
+
+## 1. Creating a Document Type
+
+A Document Type is created using the Document Type editor in the **Settings** section.
+
+* Go to the **Settings** section in the backoffice.
+* On the **Document Types** node click the menu icon (•••) to bring up the context menu.
+* Here choose **Document Type with Template**. This will create a new Document Type with a template. The Template can be found under **Templates** in the **Settings** section which will be assigned as the default template for the Document Type.
+
+
+
+You can also choose to create a **Document Type** without a template and create **Folders** to organize your Document Types. Other options are to create Compositions and Element types, which you can read more about in the [Default Document Types](default-document-types.md) section.
+
+## 2. Defining the root node
+
+### Name the Document Type
+
+First, we're prompted to give the Document Type a **name**. This first Document Type will be the root node for our content, name it "`Home`".
+
+
+
+{% hint style="info" %}
+The alias of the Document Type is automatically generated based on the property name. If you want to change the auto-generated alias, click the "**lock**" icon. The alias must be in camel case. For example: _`homePage`_.
+{% endhint %}
+
+Having a root node lets you quickly query content as you know everything will be under the root node.
+
+### Adding Icons to the Document Type
+
+Choosing appropriate icons for your content nodes is a good way to give editors a better overview of the content tree.
+
+To set an icon for the Document Type click the document icon in the top left corner. This will open the icon select dialog. Search for "`Home"`and select the icon. This icon will be used in the content tree.
+
+
+
+### Setting Permissions
+
+This will allow this Document Type to be created as the first content in the **Content** section.
+
+* Go to the **Structure** tab
+* Tick the **Allow as root** toggle
+* Save the Document Type by clicking **save** in the bottom right corner.
+
+
+
+## 3. Creating the content
+
+Now that we have the Document Type in place, we can create the content.
+
+* Go to the **Content section**
+* Click on the menu icon next to **Content**
+* Select the "`Home`" Document Type. We'll name it "`Home`"
+* Then click the **Save and Publish** button.
+
+
+
+As we haven't created our properties, all we can see on the "`Home`" node is the Properties tab. This tab contains the default properties that are available on all content nodes in Umbraco.
+
+Let's add some properties of our own.
+
+## 4. Groups and properties
+
+In order to add the option to create different content on the same Document Type, some groups and properties need to be added.
+
+**Groups**
+
+Groups are a way to organize and structure the properties within the content, making it more manageable. It also makes it more user-friendly for content editors when creating or editing content on a website.
+
+A name can be added to the group and after properties can be added.
+
+**Properties**
+
+Each field on a Document Type is called a property. The property is given a **name**, an **alias** (used to output the properties contained in a template), and an **editor**.
+
+The editor determines what type of data the property will store and the input method. There is a wide range of default [property editors available](../../backoffice/property-editors/built-in-umbraco-property-editors/) and you can [customize additional editors](../../../customizing/property-editors/).
+
+Some editors require configuration where a configured editor is saved as a Data Type and can be reused for multiple properties and document types. These can be seen in the **Settings** section under **Data Types**.
+
+* Go to the **Settings section**
+* Expand **Document Types** by clicking the arrow to the left
+* Select the "`Home`" Document Type.
+
+{% hint style="info" %}
+**Keyboard Shortcuts**
+
+Keyboard shortcuts are available when you are working with the Document Type editor. To see which shortcuts are available, click **ALT + SHIFT + K**.
+{% endhint %}
+
+### Adding groups
+
+Before we start adding properties to the Document Type we need to create a group to hold the property.
+
+* Click **Add group** and name the group "`Content`".
+
+
Creating groups
+
+{% hint style="info" %}
+_If you have multiple groups and/or properties you can order them with drag and drop or by entering a numeric sort order value. This is done by clicking **Reorder**._
+{% endhint %}
+
+To convert a group to a tab, see the [Convert a group to a tab](../adding-tabs.md#convert-a-group-to-a-tab) section in the [Using Tabs](../adding-tabs.md) article.
+
+### Adding properties
+
+Now that we have created a group we can start adding properties. Let's add a Rich Text editor to the Content group.
+
+* Click the **Add property** link in the **Content** group. This opens the property settings dialog. Here you can set the metadata for each property (name, alias, description)
+* **Choose** which Data Type/property editor to use, and add validation if needed.
+* Give the property a **name.** The name will be shown to the editor to make it relevant and understandable. Notice the alias is automatically generated based on the name. We'll name this "`Body Text`".
+
+
+
+#### Property Editors
+
+* Clicking **Select Editor** will open the Select Editor dialog. Here, you can choose between all the available editors on the **Create a new Configuration** tab. This will create a new configuration or already configured editors in the **Available Configurations** tab.
+* To make it easier to find what you need use the **search field** to filter by typing "`Rich`". Filtering will display configured properties first (under **Available configurations**) and all available editors under that.
+* Select the **Rich Text editor** under **Create new**. This will let you configure the editor settings - the Rich Text editor for this property.
+
+
+
+{% hint style="info" %}
+The name of the Data Type is based on the name of the Document Type, the name of the property, and the property editor. Flor example: _Home - Body Text - Rich Text editor_.
+{% endhint %}
+
+* Let's **rename** it to "`Basic Rich Text editor`" and only select the most necessary options.
+ * `bold`
+ * `italic`
+ * `alignLeft`
+ * `alignCenter`
+ * `link`
+ * `umbMediaPicker`
+* When you are happy with the settings click **Submit**.
+
+{% hint style="info" %}
+Selecting the **Mandatory** toggle makes the property mandatory and the content cannot be saved if no value is entered (in this case, the Richtext editor).
+
+You have the option to add additional validation by selecting a predefined validation method under the **Custom validation** dropdown (such as email, number, or URL). Or by selecting a custom validation and adding a regular expression.
+{% endhint %}
+
+* **Save** the Document Type.
+* If you go to the **Content section** and click on the `Home node` you will now see the `Content`group with the `Body Text` property.
+
+#### Property descriptions
+
+The description of the property is not necessary, but it´s a best practice as it guides the editor to use the property correctly. The property description supports some markdown and one custom collapse syntax:
+
+
+
+Bold
+
+You can make text in the description bold by wrapping it with `**`
+
+```md
+This is **bold**
+```
+
+
+
+
+
+Italic
+
+You can make text in the description italic by wrapping it with `*`
+
+```md
+This is *italic*
+```
+
+
+
+
+
+Links
+
+You can make links by using the syntax:
+
+```md
+[This is an absolute link](https://google.com)
+[This is a relative link](/umbraco#/media)
+```
+
+**Note**: Links will always have the`target="_blank"` set. This is currently not configurable.
+
+
+
+
+
+Images
+
+You can embed images by using this syntax:
+
+```md
+
+```
+
+
+
+
+
+Collapsible description
+
+You can make the description collapsible by using this syntax:
+
+```md
+
+ This is displayed
+ This is hidden.
+
+```
+
+
+
+Now if we put it all together we get something like this:
+
+```md
+This is **bold**
+This is *italic*
+[This is an absolute link](https://google.com)
+[This is a relative link](/umbraco#/media)
+--
+
+```
+
+
+
+## 5. Defining child nodes
+
+Next up we'll create a text page Document Type that will be used for subpages on the site.
+
+* Go back to the **Settings section**
+* **Create** a new Document Type
+* **Name** it "`Text Page`".
+* Add a **group** called "`Content`"
+* This time we'll add two properties:
+ * First, make a property called "`Summary`" using the **Textarea** editor
+ * Secondly, create a property called "`Body Text`" and reuse the **Rich Text Editor** Data Type.
+
+### Creating child nodes
+
+Before creating a Text Page in **Content** section, allow the Text Page Document Type to be created as a child node to the Home node.
+
+* **Select** the "`Home`" Document Type
+* Go to the **Structure** group.
+* Click **Add child**
+* **Select** "`Text Page`".
+
+
Allow Child page
+
+* Go to the **Content** section
+* Click the menu icon (•••) next to the "`Home`" node
+* **Select** the "`Text page`" Document Type. We'll name the page "`About us`". We now have a basic content structure.
+
+
+
+Document Types are flexible and can be used for defining pieces of reusable content or an entire page, to act as a container or repository.
+
+## 6. Exporting/Importing the Document Type
+
+You can also export document types from an already existing project/installation and import them into another project/installation.
+
+* Go to the **Settings** section
+* Click **...** next to the **Document type**
+* Select **Export**. When you click on the **Export** button, the Document Type is saved as a \*.udt file.
+
+
+
+To import a Document Type:
+
+* Go to the **Settings** section
+* Click **...** next to the **Document type**
+* Select **Import Document Type**
+* Click on the **Import** button and browse to the Document Type you exported. The **Name** and **Alias** of the Document Type are displayed.
+* Click **Import** to complete the process.
+
+
+
+{% hint style="info" %}
+1. If your Document Type contains compositions or inherits from another Document Type, then you need to export/import the Composition/Document Type too.
+2. You cannot export/import document types on Umbraco Cloud.
+{% endhint %}
+
+## More information
+
+* [Rendering Content](../../design/rendering-content.md)
+* [Customizing Data Types](../data-types/)
+
+## Related Services
+
+* [ContentService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentService.html)
+* [ContentTypeService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ContentTypeService.html)
+
+## Tutorials
+
+* [Creating a basic website with Umbraco](../../../tutorials/creating-a-basic-website/)
diff --git a/16/umbraco-cms/fundamentals/data/defining-content/default-document-types.md b/16/umbraco-cms/fundamentals/data/defining-content/default-document-types.md
new file mode 100644
index 00000000000..c35e8106ff4
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/defining-content/default-document-types.md
@@ -0,0 +1,41 @@
+---
+description: >-
+ On this page, you will find the default Document Types in Umbraco. If you want
+ to use these document types, you can create them in the Settings section.
+---
+
+# Default Document Types
+
+On this page, you will find the default Document Types in Umbraco. If you want to use these Document Types, you can create them in the Settings section.
+
+
+
+## Document Type
+
+A Document Type defines the content structure and fields that can be used across different content items. When creating a Document Type without a template, you focus solely on structured content without tying it to a specific design or layout. This is ideal for content that doesn’t require direct front-end rendering, such as reusable blocks or items managed within a headless CMS setup.
+
+Use a Document Type without a template for structured, reusable content like metadata schemas, settings, or components such as product details and author profiles.
+
+## Document Type with Template
+
+A Document Type with a Template combines the content structure with a predefined visual presentation. This approach links your structured content with a specific page design, ensuring a consistent and cohesive look and feel across your site. It allows you to manage content and its appearance separately, which makes updates more efficient.
+
+Use a Document Type with a template for pages like blog posts, landing pages, or services that appear directly on the website.
+
+## Element Type
+
+An Element Type is a Document Type *without a template* designed for reusabale and repeatable set of properties. These are primarily used in editors like the Block List Editor or Block Grid Editor to create structured, nested content.
+
+Element Types are not part of the Content tree and cannot render directly on the front end. When created, the **Is an Element Type** flag in the **Permissions** tab is automatically set to **True**.
+
+
+
+Use an Element Type when defining building blocks for complex page layouts, such as grid blocks or call-to-action sections. They are an essential part of modular content design.
+
+## Folder
+
+The Folder in the Document Types section is used to organize and structure your Document Types within the Settings section. It serves purely as an organizational container, with no impact on the Content section or site functionality.
+
+Use a Folder to create logical groupings, like a folder named **Compositions** to hold all your Composition Document Types. This makes it easier to navigate and manage your Document Types, especially in larger projects.
+
+Folders are a powerful tool to keep your Document Types organized and your backoffice tidy.
diff --git a/16/umbraco-cms/fundamentals/data/defining-content/document-type-localization.md b/16/umbraco-cms/fundamentals/data/defining-content/document-type-localization.md
new file mode 100644
index 00000000000..317b0891eb2
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/defining-content/document-type-localization.md
@@ -0,0 +1,103 @@
+---
+description: Here you will learn how to apply localization for Document Types in Umbraco.
+---
+
+# Document Type Localization
+
+{% hint style="warning" %}
+This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Umbraco backoffice is localized to match the [user's configured language](../users/README.md).
+
+When defining a Document Type, you can apply localization to:
+
+* Document Type name and description.
+* Property names and descriptions.
+* Custom property validation messages.
+* Tab and group names.
+
+Setting up localization for Document Types is a two-step process:
+
+* Create the localizations in [user defined backoffice localization file](../../../customizing/foundation/localization.md).
+* Apply the localizations to the Document Type.
+
+{% hint style="info" %}
+Everything in this article also applies to defining [Media Types](../creating-media/) and Member Types.
+{% endhint %}
+
+## Creating localizations
+
+Once you have [registered a backoffice localization file](../../../customizing/extending-overview/extension-types/localization.md), you can add your localization texts for use in Document Types. The following localizations are used for the samples in this article:
+
+{% code title="doctype-en.js" lineNumbers="true" %}
+```js
+export default {
+ contentTypes: {
+ article: 'Article page',
+ 'article-desc': 'A textual, article-like page on the site. Use this as the main type of content.',
+ landing: 'Landing page',
+ 'landing-desc': 'An inviting, very graphical page. Use this as an entry point for a campaign, and supplement with Articles.'
+ },
+ tabs: {
+ content: 'Page content',
+ seo: 'SEO configuration',
+ },
+ groups: {
+ titles: 'Page titles'
+ },
+ properties: {
+ title: 'Main title',
+ 'title-desc': 'This is the main title of the page.',
+ 'title-message': 'The main title is required for this page.',
+ subTitle: 'Sub title',
+ 'subTitle-desc': 'This is the sub title of the page.',
+ }
+};
+```
+{% endcode %}
+
+{% hint style="info" %}
+Umbraco must be restarted to register the localization manifest. Any subsequent localization text changes will need to be reloaded within the browser.
+{% endhint %}
+
+## Applying localizations
+
+The localizations are applied by using the syntax `#{area alias}_{key alias}`.
+
+1. Create a **Document Type with template** called `#contentTypes_article` with **alias**: `articlePage`.
+2. Under the newly created Document Type follow these steps:
+
+* Name the **description** to `#contentTypes_article-desc`.
+* Create a new **tab** called `#tabs_content`.
+* Add a new **group** called `#groups_titles`.
+* Add a **property** called `#properties_title` with **alias** `title`.
+ * Set description to `{#properties_title-desc}`.
+ * Use a `TextString` editor.
+ * Enable to `Set this field as mandatory`.
+ * Under validation add `#properties_title-message`.
+
+{% hint style="info" %}
+Property descriptions support [Umbraco Flavored Markdown](../../../reference/umbraco-flavored-markdown.md), which uses a different syntax (wrapped in brackets) to avoid conflicts with Markdown headers.
+{% endhint %}
+
+
+
+* Add a **property** called `#properties_subTitle` with **alias** `subTitle`.
+ * Set description to `{#properties_subTitle-desc}`.
+ * Use a `TextString` editor.
+* Enable `Allow at root` in the **Structure** tab.
+
+
+
+3. When creating and editing the content, you will see that the backoffice now uses the configured localizations.
+
+
+
+4. Create a new "Article" content:
+
+
+
+4. When trying to save the content without adding the mandatory content, you will see a warning as expected:
+
+
diff --git a/16/umbraco-cms/fundamentals/data/dictionary-items.md b/16/umbraco-cms/fundamentals/data/dictionary-items.md
new file mode 100644
index 00000000000..a0098c749eb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/dictionary-items.md
@@ -0,0 +1,116 @@
+---
+description: Creating Dictionary Items in Umbraco
+---
+
+# Dictionary Items
+
+Depending on how your site is set up, not all content is edited through the **Content** section. There might be some text in your templates that needs translation. Using Dictionary Items, you can store a value for each language. Dictionary Items have a unique key that is used to fetch the value of the Dictionary Item.
+
+Dictionary Items can be managed from the **Translation** section. Let's take a look at an example. In this example, we will translate "Welcome to Umbraco" from within the template and add it to the dictionary:
+
+
+
+## Adding a Dictionary Item
+
+To add a Dictionary Item:
+
+1. Go to the **Translation** section.
+2. Click on **Dictionary** in the **Translation** tree and select **Create**.
+3. Enter the **Name** for the dictionary item. Let's say _Welcome_.
+4. Enter the values for the different language versions.
+
+
+5. Click **Save**.
+
+### Grouping Dictionary Items
+
+To group dictionary items:
+
+1. Go to the **Translation** section.
+2. Click on **Dictionary** in the **Translation** tree and select **Create**.
+3. Enter the **Name** for the dictionary item. Let's say _Contact_.
+4. Click **Create**.
+5. Click on **Contact** and select **Create**.
+6. Enter the **Name** of the item to be created under the **Contact** group.
+7. Click **Create**.
+8. Enter the values for the different language versions.
+
+
+9. Click **Save**.
+
+## Editing Dictionary Items
+
+To edit a dictionary item, follow these steps:
+
+1. Go to the **Translation** section.
+2. Use the **Dictionary** tree to locate the item you need to update/edit.
+ * Alternatively, you can use the _search field_ in the top-right corner.
+3. Make the edits you need to make.
+4. Click **Save** to save the changes.
+
+{% hint style="info" %}
+It will only be possible to edit the language(s) that the given user has access to. The value of the remaining languages will be _read-only_.
+
+Which language a user has access to is determined by the "Language permissions" set on the User Group. Learn more about this feature in the [Users](users/README.md#creating-a-user-group) article.
+{% endhint %}
+
+## Fetching Dictionary Values in the Template
+
+To fetch dictionary values in the template, replace the text with the following snippet:
+
+```csharp
+@Umbraco.GetDictionaryValue("Welcome")
+```
+
+
+
+Alternatively, you can specify an `altText` which will be returned if the dictionary value is empty.
+
+```csharp
+@Umbraco.GetDictionaryValueOrDefault("Welcome", "Another amazing day in Umbraco")
+```
+
+
+
+## Importing and exporting Dictionary Items
+
+In some cases, you might want to use the same Dictionary Items on multiple Umbraco websites. For this, you can use the export and import functionality to quickly copy the items from one website to another.
+
+### Exporting Dictionary Items
+
+1. Go to the **Translation** section in the Umbraco backoffice.
+2. Locate the Dictionary Item (or group) you want to copy in the section tree.
+3. Click **...** next to the Dictionary item (or group).
+4. Select **Export...**.
+5. Decide whether you want to also include descendants.
+6. Click **Export**.
+
+This will download a `.udt` file which you can use to import the Dictionary items on another Umbraco website.
+
+
+
+### Importing Dictionary Items
+
+1. Go to the **Translation** section in the Umbraco backoffice.
+2. Click **...** next to the **Dictionary** tree.
+3. Select **Import...**.
+4. Click on **Import**.
+5. Find and select the `.udt` file containing the Dictionary Items.
+6. Click **Open** in the file browser.
+7. Review the Dictionary Items for import.
+8. Choose where to import the items.
+9. Click on **Import**.
+
+The Dictionary Items have now been added to your website.
+
+
+
+## Using Dictionary Item in a Multilingual website
+
+To use Dictionary Items in a multilingual website, see the [Creating a Multilingual Site](../../tutorials/multilanguage-setup.md) article.
+
+## Related Links
+
+* [API reference for the DictionaryItem](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Models.DictionaryItem.html)
+* [Localization Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.ILocalizationService.html)
+* [Creating a Multilingual Site](../../tutorials/multilanguage-setup.md)
diff --git a/16/umbraco-cms/fundamentals/data/images/Add-tab.png b/16/umbraco-cms/fundamentals/data/images/Add-tab.png
new file mode 100644
index 00000000000..778cf1f3ea1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Add-tab.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Add-tab.png.png b/16/umbraco-cms/fundamentals/data/images/Add-tab.png.png
new file mode 100644
index 00000000000..73e5077434e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Add-tab.png.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Composition-add-tab.gif b/16/umbraco-cms/fundamentals/data/images/Composition-add-tab.gif
new file mode 100644
index 00000000000..e37c0a3fee9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Composition-add-tab.gif differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Composition-hide-unavailable-options.PNG b/16/umbraco-cms/fundamentals/data/images/Composition-hide-unavailable-options.PNG
new file mode 100644
index 00000000000..a1e0cb68f00
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Composition-hide-unavailable-options.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Create-dictionary-item.png b/16/umbraco-cms/fundamentals/data/images/Create-dictionary-item.png
new file mode 100644
index 00000000000..487c8cce9d3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Create-dictionary-item.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/CreateDoctype.png b/16/umbraco-cms/fundamentals/data/images/CreateDoctype.png
new file mode 100644
index 00000000000..2ff143255d4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/CreateDoctype.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Doc-Type-Composition-Create.png b/16/umbraco-cms/fundamentals/data/images/Doc-Type-Composition-Create.png
new file mode 100644
index 00000000000..01a033a8322
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Doc-Type-Composition-Create.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Adding-Properties.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Adding-Properties.jpg
new file mode 100644
index 00000000000..16877952fce
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Adding-Properties.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Adding-Properties.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Adding-Properties.png
new file mode 100644
index 00000000000..e0dd28eea5d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Adding-Properties.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-At-Root.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-At-Root.jpg
new file mode 100644
index 00000000000..05eab4013e4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-At-Root.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-At-Root.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-At-Root.png
new file mode 100644
index 00000000000..681f8abb02d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-At-Root.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-Child-Node.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-Child-Node.jpg
new file mode 100644
index 00000000000..379bd460cbf
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-Child-Node.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-Child-Node.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-Child-Node.png
new file mode 100644
index 00000000000..5cf0eab4019
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Allow-Child-Node.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Child-Node-Created.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Child-Node-Created.jpg
new file mode 100644
index 00000000000..d4228f79d86
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Child-Node-Created.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Child-Node-Created.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Child-Node-Created.png
new file mode 100644
index 00000000000..1cd102415c7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Child-Node-Created.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Choosing-Icon.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Choosing-Icon.jpg
new file mode 100644
index 00000000000..cbd80fd877c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Choosing-Icon.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Choosing-Icon.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Choosing-Icon.png
new file mode 100644
index 00000000000..78a3a88a926
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Choosing-Icon.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Create-Tab.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create-Tab.jpg
new file mode 100644
index 00000000000..5eeab314605
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create-Tab.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Create-Tab.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create-Tab.png
new file mode 100644
index 00000000000..189c215b561
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create-Tab.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Create.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create.jpg
new file mode 100644
index 00000000000..8ca1e52161d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Create.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create.png
new file mode 100644
index 00000000000..bf04c748479
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Create.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Keyboard-Shortcuts.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Keyboard-Shortcuts.jpg
new file mode 100644
index 00000000000..f02269a61d7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Keyboard-Shortcuts.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Name.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Name.jpg
new file mode 100644
index 00000000000..3c97dcee728
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Name.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Rich-Text-Property.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Rich-Text-Property.jpg
new file mode 100644
index 00000000000..a7df64bc69f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Rich-Text-Property.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Root-Node-Created.jpg b/16/umbraco-cms/fundamentals/data/images/Document-Type-Root-Node-Created.jpg
new file mode 100644
index 00000000000..0132dcbf489
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Root-Node-Created.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Document-Type-Root-Node-Created.png b/16/umbraco-cms/fundamentals/data/images/Document-Type-Root-Node-Created.png
new file mode 100644
index 00000000000..1ce4b43996c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Document-Type-Root-Node-Created.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Element-Type.png b/16/umbraco-cms/fundamentals/data/images/Element-Type.png
new file mode 100644
index 00000000000..e568ea61e17
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Element-Type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Generic-tab.png b/16/umbraco-cms/fundamentals/data/images/Generic-tab.png
new file mode 100644
index 00000000000..8f0056f27c5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Generic-tab.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-Groups-Assign.jpg b/16/umbraco-cms/fundamentals/data/images/Member-Groups-Assign.jpg
new file mode 100644
index 00000000000..7b8256d2b9c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-Groups-Assign.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-Groups-Create.jpg b/16/umbraco-cms/fundamentals/data/images/Member-Groups-Create.jpg
new file mode 100644
index 00000000000..46ae9ab3f19
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-Groups-Create.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor.png b/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor.png
new file mode 100644
index 00000000000..720997b7c7b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor_new.png b/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor_new.png
new file mode 100644
index 00000000000..023273e0715
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor_new1.PNG b/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor_new1.PNG
new file mode 100644
index 00000000000..a255cb732fc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-Type-Editor_new1.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-group.png b/16/umbraco-cms/fundamentals/data/images/Member-group.png
new file mode 100644
index 00000000000..4605e90f13f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-group.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Member-group1.PNG b/16/umbraco-cms/fundamentals/data/images/Member-group1.PNG
new file mode 100644
index 00000000000..f52e963f14a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Member-group1.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Members-Generic-Properties.jpg b/16/umbraco-cms/fundamentals/data/images/Members-Generic-Properties.jpg
new file mode 100644
index 00000000000..df6a94a37ac
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Members-Generic-Properties.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Members-Info.jpg b/16/umbraco-cms/fundamentals/data/images/Members-Info.jpg
new file mode 100644
index 00000000000..e1ca5323694
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Members-Info.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Members-Tabs.jpg b/16/umbraco-cms/fundamentals/data/images/Members-Tabs.jpg
new file mode 100644
index 00000000000..f9d254a230d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Members-Tabs.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Publish-Timezone-Difference.jpg b/16/umbraco-cms/fundamentals/data/images/Publish-Timezone-Difference.jpg
new file mode 100644
index 00000000000..49bac0b0d90
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Publish-Timezone-Difference.jpg differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Relations-in-the-backoffice.png b/16/umbraco-cms/fundamentals/data/images/Relations-in-the-backoffice.png
new file mode 100644
index 00000000000..2a55e85f9b0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Relations-in-the-backoffice.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Reorder-tabs.gif b/16/umbraco-cms/fundamentals/data/images/Reorder-tabs.gif
new file mode 100644
index 00000000000..f72d6585209
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Reorder-tabs.gif differ
diff --git a/16/umbraco-cms/fundamentals/data/images/Scheduled-publishing.PNG b/16/umbraco-cms/fundamentals/data/images/Scheduled-publishing.PNG
new file mode 100644
index 00000000000..2d459b614d5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/Scheduled-publishing.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/User-Permissions.png b/16/umbraco-cms/fundamentals/data/images/User-Permissions.png
new file mode 100644
index 00000000000..80b66e7080c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/User-Permissions.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/User-Type-Info.png b/16/umbraco-cms/fundamentals/data/images/User-Type-Info.png
new file mode 100644
index 00000000000..44f415daa9a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/User-Type-Info.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/addproperty.png b/16/umbraco-cms/fundamentals/data/images/addproperty.png
new file mode 100644
index 00000000000..0fa9fd96537
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/addproperty.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/api-user.png b/16/umbraco-cms/fundamentals/data/images/api-user.png
new file mode 100644
index 00000000000..7f4be5d1379
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/api-user.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/assign-member-group.png b/16/umbraco-cms/fundamentals/data/images/assign-member-group.png
new file mode 100644
index 00000000000..81ee0a8f6c3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/assign-member-group.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/assign-member-group1.PNG b/16/umbraco-cms/fundamentals/data/images/assign-member-group1.PNG
new file mode 100644
index 00000000000..f7341617c77
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/assign-member-group1.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/composition.png b/16/umbraco-cms/fundamentals/data/images/composition.png
new file mode 100644
index 00000000000..9f82add0c8a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/composition.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/create-relation-type.png b/16/umbraco-cms/fundamentals/data/images/create-relation-type.png
new file mode 100644
index 00000000000..c41346ce89c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/create-relation-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/create-user-group.png b/16/umbraco-cms/fundamentals/data/images/create-user-group.png
new file mode 100644
index 00000000000..67e2004a8b6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/create-user-group.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/createGroup_new.png b/16/umbraco-cms/fundamentals/data/images/createGroup_new.png
new file mode 100644
index 00000000000..25b40cc09d7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/createGroup_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/createHomepage.png b/16/umbraco-cms/fundamentals/data/images/createHomepage.png
new file mode 100644
index 00000000000..d02e29e9be1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/createHomepage.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/default-permissions.png b/16/umbraco-cms/fundamentals/data/images/default-permissions.png
new file mode 100644
index 00000000000..4caefbc30b9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/default-permissions.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/default-relation-types.png b/16/umbraco-cms/fundamentals/data/images/default-relation-types.png
new file mode 100644
index 00000000000..d8e4fc4628f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/default-relation-types.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/dictionary-item-values.png b/16/umbraco-cms/fundamentals/data/images/dictionary-item-values.png
new file mode 100644
index 00000000000..bea50d97f4e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/dictionary-item-values.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/dictionary-item.png b/16/umbraco-cms/fundamentals/data/images/dictionary-item.png
new file mode 100644
index 00000000000..b69dbefae0e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/dictionary-item.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/display-dictionary-item.png b/16/umbraco-cms/fundamentals/data/images/display-dictionary-item.png
new file mode 100644
index 00000000000..d9e5f2f259f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/display-dictionary-item.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/docTypeIcon.png b/16/umbraco-cms/fundamentals/data/images/docTypeIcon.png
new file mode 100644
index 00000000000..9383f25f90e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/docTypeIcon.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/docTypePermissions.png b/16/umbraco-cms/fundamentals/data/images/docTypePermissions.png
new file mode 100644
index 00000000000..03fcaca6107
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/docTypePermissions.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/export.png b/16/umbraco-cms/fundamentals/data/images/export.png
new file mode 100644
index 00000000000..c9c209d1ce5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/export.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/homePage.png b/16/umbraco-cms/fundamentals/data/images/homePage.png
new file mode 100644
index 00000000000..7c3e05f31d5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/homePage.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/import-document-type.png b/16/umbraco-cms/fundamentals/data/images/import-document-type.png
new file mode 100644
index 00000000000..3450fc8287d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/import-document-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/import.png b/16/umbraco-cms/fundamentals/data/images/import.png
new file mode 100644
index 00000000000..97c5508a8f8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/import.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-editor-create.png b/16/umbraco-cms/fundamentals/data/images/localization-document-editor-create.png
new file mode 100644
index 00000000000..58b02eb6b1c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-editor-create.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-editor-v15.png b/16/umbraco-cms/fundamentals/data/images/localization-document-editor-v15.png
new file mode 100644
index 00000000000..47ed19ed881
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-editor-v15.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-editor-validation.png b/16/umbraco-cms/fundamentals/data/images/localization-document-editor-validation.png
new file mode 100644
index 00000000000..a81ce080608
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-editor-validation.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-editor.png b/16/umbraco-cms/fundamentals/data/images/localization-document-editor.png
new file mode 100644
index 00000000000..c47f8f8bc71
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-editor.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-v15.png b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-v15.png
new file mode 100644
index 00000000000..9f3533c9eab
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-v15.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-validation-v15.png b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-validation-v15.png
new file mode 100644
index 00000000000..c14a6bb5ca3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-validation-v15.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-validation.png b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-validation.png
new file mode 100644
index 00000000000..4ce31a3eea8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor-validation.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor.png b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor.png
new file mode 100644
index 00000000000..2b70a040459
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/localization-document-type-editor.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/md-description.gif b/16/umbraco-cms/fundamentals/data/images/md-description.gif
new file mode 100644
index 00000000000..0c5f23159df
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/md-description.gif differ
diff --git a/16/umbraco-cms/fundamentals/data/images/member-images.png b/16/umbraco-cms/fundamentals/data/images/member-images.png
new file mode 100644
index 00000000000..0ebfc085e8e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/member-images.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/member-type-composition-setting.PNG b/16/umbraco-cms/fundamentals/data/images/member-type-composition-setting.PNG
new file mode 100644
index 00000000000..c5f7e34b07d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/member-type-composition-setting.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/member-type-composition.PNG b/16/umbraco-cms/fundamentals/data/images/member-type-composition.PNG
new file mode 100644
index 00000000000..ed681f1bc84
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/member-type-composition.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/member-type-property-settings.png b/16/umbraco-cms/fundamentals/data/images/member-type-property-settings.png
new file mode 100644
index 00000000000..13c489b587d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/member-type-property-settings.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/member-type-property-settings_new.png b/16/umbraco-cms/fundamentals/data/images/member-type-property-settings_new.png
new file mode 100644
index 00000000000..7be01dded3e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/member-type-property-settings_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/member-type-property-settings_new1.PNG b/16/umbraco-cms/fundamentals/data/images/member-type-property-settings_new1.PNG
new file mode 100644
index 00000000000..268d377ea3c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/member-type-property-settings_new1.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/parent-siblings-children.png b/16/umbraco-cms/fundamentals/data/images/parent-siblings-children.png
new file mode 100644
index 00000000000..1ace04fdb61
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/parent-siblings-children.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/per-doctype-override.png b/16/umbraco-cms/fundamentals/data/images/per-doctype-override.png
new file mode 100644
index 00000000000..33d9c68ad6b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/per-doctype-override.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/prevent-cleanup-part-1.png b/16/umbraco-cms/fundamentals/data/images/prevent-cleanup-part-1.png
new file mode 100644
index 00000000000..e50e559391b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/prevent-cleanup-part-1.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/prevent-cleanup-part-2.png b/16/umbraco-cms/fundamentals/data/images/prevent-cleanup-part-2.png
new file mode 100644
index 00000000000..55051c7c9ac
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/prevent-cleanup-part-2.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/relation-alias.png b/16/umbraco-cms/fundamentals/data/images/relation-alias.png
new file mode 100644
index 00000000000..adb3724f63e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/relation-alias.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/relation-types-tree.png b/16/umbraco-cms/fundamentals/data/images/relation-types-tree.png
new file mode 100644
index 00000000000..99f780d3cb6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/relation-types-tree.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/rendering-altvalue-dictionary-item.png b/16/umbraco-cms/fundamentals/data/images/rendering-altvalue-dictionary-item.png
new file mode 100644
index 00000000000..e43fc16234c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/rendering-altvalue-dictionary-item.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/rendering-dictionary-item.png b/16/umbraco-cms/fundamentals/data/images/rendering-dictionary-item.png
new file mode 100644
index 00000000000..0e03646e5a2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/rendering-dictionary-item.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/schedule.png b/16/umbraco-cms/fundamentals/data/images/schedule.png
new file mode 100644
index 00000000000..0ecf9270a25
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/schedule.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/scheduled-publishing-8.png b/16/umbraco-cms/fundamentals/data/images/scheduled-publishing-8.png
new file mode 100644
index 00000000000..d27a20c238f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/scheduled-publishing-8.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/selectEditor.png b/16/umbraco-cms/fundamentals/data/images/selectEditor.png
new file mode 100644
index 00000000000..92e375529fc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/selectEditor.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/user-groups.png b/16/umbraco-cms/fundamentals/data/images/user-groups.png
new file mode 100644
index 00000000000..0bee87e6a5e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/user-groups.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/addproperty.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/addproperty.PNG
new file mode 100644
index 00000000000..e1bea9ab123
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/addproperty.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/addproperty_new.png b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/addproperty_new.png
new file mode 100644
index 00000000000..90b6811430f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/addproperty_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/compositions.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/compositions.PNG
new file mode 100644
index 00000000000..f7659939395
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/compositions.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createAboutUs.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createAboutUs.PNG
new file mode 100644
index 00000000000..1a3dcaa872b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createAboutUs.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createDoctype.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createDoctype.PNG
new file mode 100644
index 00000000000..38a1fc35656
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createDoctype.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createGroup.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createGroup.PNG
new file mode 100644
index 00000000000..0296832fb4c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createGroup.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createGroup_new.png b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createGroup_new.png
new file mode 100644
index 00000000000..d472b03643a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createGroup_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createHomepage.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createHomepage.PNG
new file mode 100644
index 00000000000..f81f9f46f2b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/createHomepage.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/docTypeIcon.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/docTypeIcon.PNG
new file mode 100644
index 00000000000..8e69be56ee0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/docTypeIcon.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/docTypePermissions.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/docTypePermissions.PNG
new file mode 100644
index 00000000000..f7db0099d66
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/docTypePermissions.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/export-document-type.png b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/export-document-type.png
new file mode 100644
index 00000000000..6aab567e14f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/export-document-type.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/homePage.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/homePage.PNG
new file mode 100644
index 00000000000..09f09c4a42a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/homePage.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/selectEditor.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/selectEditor.PNG
new file mode 100644
index 00000000000..8243f86002a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/selectEditor.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/selectEditor_new.png b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/selectEditor_new.png
new file mode 100644
index 00000000000..e9535792256
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/selectEditor_new.png differ
diff --git a/16/umbraco-cms/fundamentals/data/images/v8Screenshots/setPagePermissions.PNG b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/setPagePermissions.PNG
new file mode 100644
index 00000000000..6468e326822
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/v8Screenshots/setPagePermissions.PNG differ
diff --git a/16/umbraco-cms/fundamentals/data/images/view-relations.png b/16/umbraco-cms/fundamentals/data/images/view-relations.png
new file mode 100644
index 00000000000..5dcd9ce63a0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/data/images/view-relations.png differ
diff --git a/16/umbraco-cms/fundamentals/data/members.md b/16/umbraco-cms/fundamentals/data/members.md
new file mode 100644
index 00000000000..be68820eda1
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/members.md
@@ -0,0 +1,119 @@
+---
+description: >-
+ Members are used for registering and authentication external / frontend users
+ of an Umbraco installation. This could be Forum members and Intranet members.
+---
+
+# Members
+
+Members are used for registering and authenticating external users of an Umbraco installation (ie. forum members, intranet users and so forth).
+
+This guide will explain how to define and create members in the backoffice. If you want to work with members using the service APIs, links can be found at the end of the document.
+
+There is a default Member Type that can be used to create members. You can customize this to fit your needs or create your own Member Type from scratch.
+
+## Creating a Member
+
+Go to the **Members** section and click **Create**.
+
+Members have a number of mandatory properties that need to be filled in before a member can be saved. Some of the properties are **Username**, **Email**, two **Password fields** and so on.
+
+There are also a number of default properties which are stored in the database in the tables `Member` and`TwoFactorLogin`:
+
+* `umbracoMemberFailedPasswordAttempts`
+* `umbracoMemberApproved`
+* `umbracoMemberLockedOut`
+* `umbracoTwoFactorLogin`
+* `umbracoMemberLastLockoutDate`
+* `umbracoMemberLastLogin`
+* `umbracoMemberLastPasswordChangeDate`
+
+Once the Member is created and saved you can access it by expanding the Members tree and clicking **All Members** to get a collection. You can also view members of a specific type by selecting the member type in the Members tree.
+
+## [Sensitive data](../../reference/security/sensitive-data-on-members.md)
+
+Sensitive properties on a members data will not be displayed to backoffice users unless they have appropriate permissions. In order to see the values of the default properties in the **Member** tab you need to have the Sensitive data User Group. By having this group added to a user they will also have the option to mark member type properties as sensitive.
+
+More information can be found under [security](../../reference/security/sensitive-data-on-members.md).
+
+## Creating a Member Type
+
+You can create your own Member Types and add tabs, groups and properties as you would with Document Types.
+
+Go to the **Settings** section, click **...** next to **Member Types** and select **Create**. You will now be taken to the Member Type editor that is used to define and edit the Member Type. Name the new Member Type and click **Save**.
+
+
+
+Once created, the Member Type will have no properties, so you have the freedom to add your own properties or compositions.
+
+### Assigning a Member Composition
+
+When creating a Member Type you can assign compositions. Compositions allow you to inherit tabs and properties from existing member types instead of creating them from scratch.
+
+For example on the member type that you have created, click on **Composition**. Then you can choose the existing **Member** type which then you will inherit its tabs, groups, and properties.
+
+
Composition Member Type
+
+The default **Member** type has a **Membership** group which includes `umbracoMemberComments` property along with the other default properties. The other properties can be seen only in the **Member** tab when creating a member.
+
+It is possible to add more groups and more properties to each of the Member Types you create, as well as the default Member Type.
+
+## Creating Member Groups
+
+Member Groups define roles for your members that can be used for role-based protection. A member can be in multiple groups.
+
+
+
+To create a new Member Group click the menu icon next to the **Member Groups** node in the Members section. Choose **Create**, name the group, and save the group.
+
+### Assigning a Member Group
+
+To assign a member to a specific group find the member you wish to assign and find the **Properties** group. Here you can see which groups the member is already part of. You can also add the member to more groups or remove the member from already assigned groups:
+
+
+
+## Technical
+
+As a developer you are able to leverage your website when you build on the Members section of Umbraco. The member's section is by default in the Umbraco backoffice, but you can still use it to implement some work on your front end. Members are created using ASP.NET Core Identity, so there are some provider settings that can be set in appsettings.json - here are the defaults:
+
+```json
+{
+ "$schema": "appsettings-schema.json",
+ "Umbraco": {
+ "CMS": {
+ "Security": {
+ "AllowPasswordReset": true,
+ "AuthCookieDomain": "(No default, but takes a string)",
+ "AuthCookieName": "UMB_UCONTEXT",
+ "KeepUserLoggedIn": false,
+ "UsernameIsEmail": true,
+ "HideDisabledUsersInBackoffice": false,
+ "AllowedUserNameCharacters": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+\\",
+ "MemberPassword": {
+ "RequiredLength": 10,
+ "RequireNonLetterOrDigit": false,
+ "RequireDigit": false,
+ "RequireLowercase": false,
+ "RequireUppercase": false,
+ "MaxFailedAccessAttemptsBeforeLockout": 5,
+ "HashAlgorithmType": "HMACSHA256"
+ }
+ }
+ }
+ }
+}
+```
+
+You can find out more about the services methods in the reference section of the documentation by following the links below.
+
+## References
+
+* Video: [Adding a member](https://www.youtube.com/watch?v=gdvfrqQcAGY)
+* Video: [Member Type Properties](https://www.youtube.com/watch?v=E_es3x_H5oU)
+* Video: [Role-Based Protection](https://www.youtube.com/watch?v=wVR9OBnaNZQ)
+
+### Related Services
+
+* [MemberService](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.MemberService.html)
+* [MemberType Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.MemberTypeService.html)
+* [MemberGroup Service](https://apidocs.umbraco.com/v15/csharp/api/Umbraco.Cms.Core.Services.IMemberGroupService.html)
diff --git a/16/umbraco-cms/fundamentals/data/relations.md b/16/umbraco-cms/fundamentals/data/relations.md
new file mode 100644
index 00000000000..1c09107870e
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/relations.md
@@ -0,0 +1,67 @@
+---
+description: Learn about relations and how to create and manage them.
+---
+
+# Relations
+
+Umbraco sections are built around the concept of 'trees' and there is an implicit relationship between items in a section tree.
+
+
+
+We refer to these relationships in the manner of a 'Family Tree'. One content item might be the 'Parent' of some content items, and those items would be referred to as the 'Children' of that parent. Items within the same branch of the tree can also be described as 'Ancestors' or 'Descendants' of an item.
+
+There are methods available to support querying content items by their relative position to the current page. This is possible using the following concepts: `Model.Ancestors()`, `Model.Children()`, or `Model.Descendants()`.
+
+In some cases there are no direct relationships between two items in a tree, but they are still somehow 'related'. This could be the alternate language translation pages of a content page.
+
+In other cases there is a 'relation' between different types of entities. This could be a relation between Content and Member, or Member and MediaFolder. You might need to be able to retrieve and display the uploaded images from a specific logged-in Member.
+
+These are the scenarios where the concept of **Umbraco Relations** provides a solution.
+
+## The Concept of Umbraco Relations
+
+Umbraco Relations allow you to relate almost any object in Umbraco to almost any other Umbraco object. This is done by defining a new _Relation Type_.
+
+### How is this different to pickers?
+
+With a Content, Member, or Media picker the relationship only works as a 1-way street. The content item knows it has 'picked' another content item but that other content item does not know where it has been picked.
+
+Umbraco Relations works as a 2-way street. When creating a relation between two different types of entities, it will be possible to find one entity from the other and vice versa. As an example this provides the option to list out all the pages that a content banner had been picked on.
+
+## Relation Types
+
+A Relation Type specifies how two types of entities are related. Two items might be related under multiple Relation Types, and you might only be interested in your 'Related Language Page' Relation Type.
+
+## Viewing Relations
+
+It is possible to view the existing Relation Types from the Umbraco backoffice:
+
+1. Access the Umbraco Backoffice.
+2. Navigate to the **Settings** section.
+3. Locate the **Advanced** group in the sidebar.
+4. Select **Relations**.
+
+
+
+On the dashboard all defined relations will be listed. Select a Relation to view a list of all the objects that have been related for that specific Relation Type.
+
+## Creating Relations
+
+You can create Relations using the RelationService API via code.
+
+[Some examples are provided here in the RelationService Documentation Page](../../reference/management/using-services/relationservice.md)
+
+## Use cases
+
+You might want to create a 'Relation' between two objects either as:
+
+* A response to a backoffice event. For example, a content item being published that has picked other content items. Storing a relationship between these items would make querying between them easier. Perhaps show all the pages on which a particular 'banner' has been picked.
+* A logged-in member on the front end of an Umbraco website might have the facility to upload images. In response, the implementation could store the photos programmatically in the Media Section and at the same time, create a Relation to record the relationship between the member and their uploaded pictures. On an image gallery page, it would be possible to display all the gallery images for the current logged-in Member using the relations.
+
+## Community Packages
+
+Some of the community packages that use Relations are listed below:
+
+* ['Relations Picker'](https://our.umbraco.com/packages/backoffice-extensions/relations-picker/) - a content picker that automatically creates Relations.
+* ['ContentRelations'](https://our.umbraco.com/packages/backoffice-extensions/contentrelations/) - allows you to relate two items via the Backoffice.
+* ['LinkedPages'](https://our.umbraco.com/packages/backoffice-extensions/linked-pages/) - Provides a LinkedPages context item to show, edit, and add relations between content pages.
diff --git a/16/umbraco-cms/fundamentals/data/scheduled-publishing.md b/16/umbraco-cms/fundamentals/data/scheduled-publishing.md
new file mode 100644
index 00000000000..485aaf1e881
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/scheduled-publishing.md
@@ -0,0 +1,62 @@
+---
+description: >-
+ Each document in Umbraco can be scheduled for publishing and unpublishing on a
+ pre-defined date and time.
+---
+
+# Scheduled Publishing
+
+Each document in Umbraco can be scheduled for publishing and unpublishing on a pre-defined date and time.
+
+You can find the options to do this click on the arrow next to the **Save and publish** button and pick **Schedule...**
+
+
+
+
Scheduled publishing
+
+This will open a **Schedule Publishing** dialog where you can specify dates and time.
+
+
+
+## Timezones
+
+Your server may be in a different timezone than where you are located. You are able to select a date and time in your timezone and Umbraco will make sure that the item gets published at that time. So, if you select 12 PM then the item will be published at 12PM in the timezone you are in. This may be 8 PM on the server, which is indicated when you select the date and time.
+
+
Scheduled publishing
+
+If you are in the same timezone as the server, this message will not appear under the date picker.
+
+{% hint style="info" %}
+In Umbraco versions lower than 7.5, the time you select has to be the time on the server. These older versions of Umbraco do not detect your local time zone.
+{% endhint %}
+
+## Permissions
+
+All users with access to the Content section in the Umbraco backoffice are able to schedule content for publishing/unpublish.
+
+## Configuration
+
+In some cases you will need to adjust your configuration to ensure that scheduled publishing/unpublishing works. The schedule works by the server sending an HTTP(S) request to itself.
+
+If you are in a load balanced environment special care must be given to ensure you've configured this correctly, [see the docs here](../setup/server-setup/load-balancing/file-system-replication.md)
+
+If you are not load balancing, the way that Umbraco determines the base URL to send the scheduled HTTP(S) request to is as follows:
+
+* umbracoSettings:settings/web.routing/@umbracoApplicationUrl if it exists _(see_ [_these docs_](../../reference/configuration/webroutingsettings.md) _for details)_
+* Else umbracoSettings:settings/scheduledTasks/@baseUrl if it exits _(deprecated)_
+* Else umbracoSettings:distributedCall/servers if we have the server in there _(deprecated, see load balance docs)_
+* Else it's based on the first request that the website receives and uses the base URL of this request _(default)_
+
+If the `umbracoApplicationUrl` is used, the value also specifies the scheme (either HTTP or HTTPS). The request for scheduled publishing will always be sent over HTTPS if the appSettings `umbracoUseSSL` is set to `true`.
+
+## Troubleshooting
+
+If your scheduled publishing/unpublishing is not working as expected it is probably an issue that your server cannot communicate with the scheduled publishing endpoint. This can be caused by a number of reasons such as:
+
+* Url rewrites in place that prevent the endpoint from being reached
+* DNS misconfiguration not allowing the server to communicate to the base URL used in the first request that the website receives - which could be directly affected by a firewall/Network Address Translation (NAT)/load balancer that your server sites behind
+* Secure Sockets Layer (SSL) and/or umbracoUseSSL misconfiguration not allowing the server to communicate to the scheduled publishing endpoint on the correct http/https scheme
+
+To better diagnose the issue you can temporarily change your log4net config settings to be `DEBUG` instead of `INFO`. This will give you all sorts of information including being able to see whether or not the scheduled publishing endpoint is being reached or not.
+
+In some cases it might be easiest to specify the [umbracoSettings:settings/web.routing/@umbracoApplicationUrl](../../reference/configuration/webroutingsettings.md) setting. This is to ensure that your server is communicating to itself on the correct URL.
diff --git a/16/umbraco-cms/fundamentals/data/users/README.md b/16/umbraco-cms/fundamentals/data/users/README.md
new file mode 100644
index 00000000000..7e4f27b75ff
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/users/README.md
@@ -0,0 +1,84 @@
+---
+description: >-
+ This guide will explain how to define, create, and manage users in the
+ backoffice
+---
+
+# Users
+
+Users (not to be confused with [Members](../members.md)) are people who have access to the Umbraco backoffice. These could include Content Editors, Translators, Web Designers, and Developers.
+
+This guide will explain how to define, create, and manage users in the backoffice.
+
+## Creating a user
+
+Go to the **Users** section. Here, you will see an overview of all the current backoffice users.
+
+To create a new user select the **Invite user** button. You will be prompted to add a **Name** and an **Email** for the new user. You will also need to select which **User group** the new user should be added to and enter a **Message** for the invitation.
+
+Once you have created the user, an autogenerated password will be provided. This password needs to be used to access the account.
+
+### User profiles
+
+There are default properties on every user that can be defined:
+
+* Change/Remove photo.
+* Change Password (provides an option to set a new password).
+* Disable (allows one to disable service access).
+* Update the email for the user.
+* Language (sets the backoffice language of the user account).
+* User Group (determines the scope of access in the backoffice)
+* Start nodes for both Content and Media sections to limit access
+
+## Default User Groups
+
+By default, the User Groups available to new users are **Administrators**, **Writers**, **Editors**, **Translators,** and **Sensitive Data**.
+
+* **Administrator**: Can do anything when editing nodes in the content section (has all permissions).
+* **Editor**: Allowed to create and publish content items or nodes on the website without approval from others or restrictions (has permissions to **Public Access**, **Rollback**, **Browse Node**, **Create Content Template**, **Delete**, **Create**, **Publish**, **Unpublish**, **Update**, **Copy**, **Move** and **Sort**).
+* **Writer**: Allowed to browse nodes, create nodes, and request for publication of items. Not allowed to publish directly without someone else's approval like an Editor (has permissions to **Browse Node**, **Create**, **Send to Publish,** and **Update**).
+* **Translator**: These are used for translating your website. Translators are allowed to browse and update nodes as well as grant dashboard access. Translations of site pages must be reviewed by others before publication (has permissions to **Browse Node** and **Update**).
+* **Sensitive data**: Any users added to this User group will have access to view any data marked as sensitive. Learn more about this feature in the [Sensitive Data](../../../reference/security/sensitive-data-on-members.md) article.
+
+## Creating a User Group
+
+You can also create your own custom User Groups and add properties and tabs as you would with Document Types and Member Types.
+
+Go to the **Users** section and select the **Groups** tab in the top-right corner.
+
+
+
+Select **Create Group** and you will be taken to the **User Group** editor. Here you can define and edit the User Group through custom settings and properties.
+
+### User Group Parameters
+
+
+
+Shows basic information about the User Group and settings for custom properties.
+
+* **Name**: The name of the User Group is shown in the User Group tab.
+* **Alias**: Used to reference the User Group in code - the alias will be auto-generated based on the name.
+* **Assign access**: Define which sections and languages the users will have access to, and if the users should have access to only some or all content and media.
+* **Default Permissions**: Select the default permissions granted to users of the User Group.
+* **Granular permissions**: Define a specific node the users in the group should have access to.
+* **Users**: Add users to the new group.
+
+## User Permissions
+
+Depending on which User Group a user is added to, each user has a set of permissions associated with their accounts. These permissions either enable or disable a user's ability to perform its associated function.
+
+The available user permissions are defined under **Default Permissions** in the User group.
+
+
+
+### Setting User Permissions
+
+When a new user is created, you can set specific permissions for that user on different domains and subdomains. You can also set permissions on different User Groups, even for the default types.
+
+## Technical
+
+As a developer, you are only able to leverage your website from the backoffice when you build on the Users section of Umbraco. This is because the Users section is restricted to the Umbraco backoffice.
+
+## [Managing Forms Security](https://docs.umbraco.com/umbraco-forms/developer/security)
+
+Umbraco Forms has a backoffice security model integrated with Umbraco Users. You can manage the details in the **Users** section of the backoffice, within a tree named **Forms Security**.
diff --git a/16/umbraco-cms/fundamentals/data/users/api-users.md b/16/umbraco-cms/fundamentals/data/users/api-users.md
new file mode 100644
index 00000000000..4de28c8af13
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/data/users/api-users.md
@@ -0,0 +1,19 @@
+---
+description: This guide will explain the API Users concept and how they differ from regular Users how to define
+---
+
+# API Users
+
+API Users allow for authorizing [external access](../../../reference/management-api/external-access.md) to the Management API.
+
+An API User is identical to a [regular User](README.md) except for one thing: It has no password. In fact, API Users are not allowed to log into the backoffice like regular Users.
+
+Instead, API Users hold the Client Credentials used to authorize against the Management API. When an external source authorizes using Client Credentials, it effectively assumes the identity of the API User.
+
+Since API Users are identical to regular Users their backoffice access can be controlled in the same way. This allows for imposing detailed access control on the external sources connected to the Management API.
+
+
+
+{% hint style="info" %}
+Client IDs for API Users are explicitly prefixed with `umbraco-back-office-`. This guards against API Users accidentally taking over one of the Client IDs used by the Umbraco core.
+{% endhint %}
diff --git a/16/umbraco-cms/fundamentals/design/README.md b/16/umbraco-cms/fundamentals/design/README.md
new file mode 100644
index 00000000000..9855ffb0c57
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/README.md
@@ -0,0 +1,21 @@
+# Design
+
+## [Templates](templates/README.md)
+
+Creating, managing, and reusing templates in Umbraco.
+
+## [Rendering content](rendering-content.md)
+
+Querying and rendering published content.
+
+## [Rendering media](rendering-media.md)
+
+Querying and rendering media items.
+
+## [Partial Views](partial-views.md)
+
+Working with partial views in Umbraco's templates.
+
+## [Stylesheets and JavaScript](stylesheets-javascript.md)
+
+Working with CSS and JavaScript in Umbraco's templates.
diff --git a/16/umbraco-cms/fundamentals/design/images/1-creating-stylesheet.png b/16/umbraco-cms/fundamentals/design/images/1-creating-stylesheet.png
new file mode 100644
index 00000000000..46a9328fea0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/1-creating-stylesheet.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/10-reference-script-v9.png b/16/umbraco-cms/fundamentals/design/images/10-reference-script-v9.png
new file mode 100644
index 00000000000..14202a63874
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/10-reference-script-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/10-reference-script.png b/16/umbraco-cms/fundamentals/design/images/10-reference-script.png
new file mode 100644
index 00000000000..4aabb9cd603
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/10-reference-script.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/2-rte-editor.png b/16/umbraco-cms/fundamentals/design/images/2-rte-editor.png
new file mode 100644
index 00000000000..c09094a7d33
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/2-rte-editor.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/3-rte-editor-p2.png b/16/umbraco-cms/fundamentals/design/images/3-rte-editor-p2.png
new file mode 100644
index 00000000000..2e2c1713de4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/3-rte-editor-p2.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/3-rte-editor-p3.png b/16/umbraco-cms/fundamentals/design/images/3-rte-editor-p3.png
new file mode 100644
index 00000000000..55f70239042
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/3-rte-editor-p3.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/4-link-css-v9.png b/16/umbraco-cms/fundamentals/design/images/4-link-css-v9.png
new file mode 100644
index 00000000000..9a9a2d7f9d2
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/4-link-css-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/4-link-css.png b/16/umbraco-cms/fundamentals/design/images/4-link-css.png
new file mode 100644
index 00000000000..ffdf9a237fa
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/4-link-css.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/5-rtesheet.png b/16/umbraco-cms/fundamentals/design/images/5-rtesheet.png
new file mode 100644
index 00000000000..8abfe1a78c1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/5-rtesheet.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/6-rte-connect-sheet.png b/16/umbraco-cms/fundamentals/design/images/6-rte-connect-sheet.png
new file mode 100644
index 00000000000..ef4e6e1c09c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/6-rte-connect-sheet.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/7-content-rte.png b/16/umbraco-cms/fundamentals/design/images/7-content-rte.png
new file mode 100644
index 00000000000..db8e18048d0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/7-content-rte.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/8-create-js.png b/16/umbraco-cms/fundamentals/design/images/8-create-js.png
new file mode 100644
index 00000000000..1290096e6e6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/8-create-js.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/9-myscript.png b/16/umbraco-cms/fundamentals/design/images/9-myscript.png
new file mode 100644
index 00000000000..000ee142a1b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/9-myscript.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/Partial-Views-folder.png b/16/umbraco-cms/fundamentals/design/images/Partial-Views-folder.png
new file mode 100644
index 00000000000..fb64d9dc65f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/Partial-Views-folder.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/button-v8.png b/16/umbraco-cms/fundamentals/design/images/button-v8.png
new file mode 100644
index 00000000000..2d4e00f98b8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/button-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/button.png b/16/umbraco-cms/fundamentals/design/images/button.png
new file mode 100644
index 00000000000..bb6de535ee1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/button.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/created-partial-view-from-snippet.png b/16/umbraco-cms/fundamentals/design/images/created-partial-view-from-snippet.png
new file mode 100644
index 00000000000..55f96243d65
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/created-partial-view-from-snippet.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file-from-snippet.png b/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file-from-snippet.png
new file mode 100644
index 00000000000..c8a3bb9a69a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file-from-snippet.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file-without-macro.png b/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file-without-macro.png
new file mode 100644
index 00000000000..9c8a77f8ee4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file-without-macro.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file.png b/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file.png
new file mode 100644
index 00000000000..d7486429b06
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/created-partial-view-macro-file.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/created-partial-view.png b/16/umbraco-cms/fundamentals/design/images/created-partial-view.png
new file mode 100644
index 00000000000..9f38a626f45
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/created-partial-view.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/creating-partial-view-macro-files.png b/16/umbraco-cms/fundamentals/design/images/creating-partial-view-macro-files.png
new file mode 100644
index 00000000000..38d0eddacd0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/creating-partial-view-macro-files.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/creating-partial-view.png b/16/umbraco-cms/fundamentals/design/images/creating-partial-view.png
new file mode 100644
index 00000000000..d81a6916a5d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/creating-partial-view.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/dialog.png b/16/umbraco-cms/fundamentals/design/images/dialog.png
new file mode 100644
index 00000000000..d79cecce0b7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/dialog.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/folder.png b/16/umbraco-cms/fundamentals/design/images/folder.png
new file mode 100644
index 00000000000..6832f2efa93
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/folder.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/language-fallback.png b/16/umbraco-cms/fundamentals/design/images/language-fallback.png
new file mode 100644
index 00000000000..bb48e169036
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/language-fallback.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/partial-views-in-directory.png b/16/umbraco-cms/fundamentals/design/images/partial-views-in-directory.png
new file mode 100644
index 00000000000..df2e5682b03
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/partial-views-in-directory.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/query-button.png b/16/umbraco-cms/fundamentals/design/images/query-button.png
new file mode 100644
index 00000000000..373fbe4391b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/query-button.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/query-v8.png b/16/umbraco-cms/fundamentals/design/images/query-v8.png
new file mode 100644
index 00000000000..d3074f19d3a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/query-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/query-v9.png b/16/umbraco-cms/fundamentals/design/images/query-v9.png
new file mode 100644
index 00000000000..53dd76262eb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/query-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/design/images/query.png b/16/umbraco-cms/fundamentals/design/images/query.png
new file mode 100644
index 00000000000..cc517bf09bc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/images/query.png differ
diff --git a/16/umbraco-cms/fundamentals/design/partial-views.md b/16/umbraco-cms/fundamentals/design/partial-views.md
new file mode 100644
index 00000000000..c363e80d7cb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/partial-views.md
@@ -0,0 +1,115 @@
+---
+description: Information on working with partial views in Umbraco
+---
+
+# Partial Views
+
+A Partial View (`.cshtml` file) is a regular view that can be used multiple times throughout your site. A Partial View is used to break up large markup files into smaller components such as header, footer, navigation menu, etc. It helps to reduce the duplication of code. A partial view renders a view within the parent view.
+
+## Partial Views in the Backoffice
+
+You can create and edit partial views in the **Partial Views** folder from the **Settings** section of the Backoffice.
+
+
+
+In the **Create** menu, there are three options available:
+
+* New empty partial view
+* New partial view from snippet
+* Folder (for keeping the partial views organized)
+
+## Creating a Partial View
+
+To create a partial view:
+
+1. Go to the **Settings** section in the Umbraco backoffice.
+2. Click **...** next to the **Partial Views** folder.
+3. Choose **Create**.
+4. Select **New empty partial view**.
+5. Enter a partial view name.
+6. Click the **Save** button. You will now see the partial view markup in the backoffice editor.
+
+
Created partial view
+
+By default, the partial views are saved in the `Views/Partials` folder in the solution.
+
+
+
+## Creating a Partial View from Snippet
+
+To create a partial view from the snippet:
+
+1. Go to the **Settings** section in the Umbraco backoffice.
+2. Click **...** next to the **Partial Views** folder.
+3. Choose **Create**.
+4. Select **New empty partial view from snippet**.
+5. Select the snippet you want to create a partial view for and enter a partial view name. The code snippet you selected is displayed in the backoffice editor.
+6. Click the **Save** button.
+
+
Created partial view from snippet
+
+Umbraco provides the following partial view snippets:
+
+* Empty - Creates an empty partial view file.
+* Breadcrumb - Creates a breadcrumb of parents using the `Ancestors()` method to generate links in an unordered HTML list. It displays the name of the current page without a link.
+* Edit Profile - Creates a Member profile model that can be edited.
+* List Ancestors From Current Page - Displays a list of links to the parents of the current page using the `Ancestors()` method to generate links in an unordered HTML list. It displays the name of the current page without a link.
+* List Child Pages From Current Page - Displays a list of links to the children of the current page using the `Children()` method to generate links in an unordered HTML list.
+* List Child Pages Ordered By Date - Displays a list of links to the children of the current page using the `Children()` method to generate links in an unordered HTML list. The pages are sorted by the creation date in a descending order using the `OrderByDescending()` method.
+* List Child Pages Ordered By Name - Displays a list of links to the children of the current page using the `Children()` method to generate links in an unordered HTML list. The pages are sorted by the page name using the `OrderBy()` method.
+* List Child Pages With DocType - Displays only the children of a certain Document Type.
+* List Descendants From Current Page - Displays a list of links for every page below the current page in an unordered HTML list.
+* Login - Displays a login form.
+* Login Status - Displays the user name if the user is logged in.
+* Multinode Tree-picker - Lists the items from a Multinode tree picker using the picker's default settings.
+* Navigation - Displays a list of links of the pages under the top-most page in the Content tree. It also highlights the currently active page/section in the navigation menu.
+* Register Member - Displays a Member registration form. It will only display the properties marked as **Member can edit** on the **Info** tab of the Member Type.
+* Site Map - Displays a list of links of all the visible pages of the site using the `Traverse()` method to select and display the markup and links as nested unordered HTML lists.
+
+## Creating a Folder
+
+To create a folder:
+
+1. Go to the **Settings** section in the Umbraco backoffice.
+2. Click **...** next to the **Partial Views** folder.
+3. Choose **Create**.
+4. Select **Folder**.
+5. Enter a folder name.
+6. Click the **Create** button.
+
+
+
+
Created folder
+
+
+
+## Rendering a Partial View
+
+To render the created partial view into any template, use any of these helper methods: `@Html.PartialAsync`, `@Html.Partial()`, or `@Html.RenderPartial()`
+
+```csharp
+@using Umbraco.Cms.Web.Common.PublishedModels;
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
+@{
+ Layout = null;
+}
+
+@await Html.PartialAsync("Login")
+
+@Html.Partial("Login")
+
+@{
+ Html.RenderPartial("Login");
+}
+```
+
+### Related Articles
+
+* [Using MVC Partial Views in Umbraco](../../reference/templating/mvc/partial-views.md)
+
+### Video Materials
+
+{% embed url="https://www.youtube.com/watch?ab_channel=UmbracoLearningBase&v=RcYM_DJ-JnQ" %}
+Getting started with Umbraco: Partial Views
+{% endembed %}
diff --git a/16/umbraco-cms/fundamentals/design/rendering-content.md b/16/umbraco-cms/fundamentals/design/rendering-content.md
new file mode 100644
index 00000000000..c76382ca502
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/rendering-content.md
@@ -0,0 +1,110 @@
+# Rendering Content
+
+_The primary task of any template is to render the values of the current page or the result of a query against the content cache._
+
+## Display a value in your template view
+
+Each property in your [Document Type](../data/defining-content/#what-is-a-document-type) has an alias, this is used to specify where in the template view to display the value.
+
+```html
+
@Model.Value("pageTitle")
+
@Model.Value("bodyContent")
+
+```
+
+### Specifying types of data
+
+You can specify the type of data being returned to help you format the value for display.
+
+In our example, we have a string, a date and some rich text:
+
+```html
+
@(Model.Value("pageTitle"))
+
@(Model.Value("bodyContent"))
+
Article date:
+```
+
+{% hint style="info" %}
+To use `IHtmlEncodedString` as the typed value, add the `@using Umbraco.Cms.Core.Strings;` directive.
+{% endhint %}
+
+### Using ModelsBuilder
+
+```html
+
@Model.PageTitle
+
@Model.BodyContent
+
+```
+
+### Using fall-back methods
+
+The `.Value()` method has a number of optional parameters that support scenarios where we want to "fall-back" to some other content.
+
+To use the `fallback` type, add the `@using Umbraco.Cms.Core.Models.PublishedContent;` directive.
+
+* To display a static, default value when a property value is not populated on the current content item:
+
+ ```csharp
+ @Model.Value("pageTitle", fallback: Fallback.ToDefaultValue, defaultValue: new HtmlString("Default page title"))
+ ```
+* A second supported method is to traverse up the tree ancestors to try to find a value. If the current content item isn't populated for a property, we can retrieve the value from the parent, grand-parent, or a higher ancestor in the tree. The first ancestor encountered that has a value will be the one returned.
+
+ ```csharp
+ @Model.Value("pageTitle", fallback: Fallback.ToAncestors)
+ ```
+* If developing a multi-lingual site and fall-back languages\* have been configured, the third method available is to retrieve a value for a different language, if the language we are requesting does not have content populated. In this way, we could render a field containing French content for a property if it's populated in that language, and if not, default to English.
+
+ ```csharp
+ @Model.Value("pageTitle", "fr", fallback: Fallback.ToLanguage)
+ ```
+* We can also combine these options to create some more sophisticated scenarios. For example, we might want to fall-back via language first, and if that doesn't find any populated content, then try to find a value by traversing through the ancestors of the tree. We can do that using the following syntax, with the order of the fall-back options provided determining the order that content will be attempted to be retrieved:
+
+ ```csharp
+ @Model.Value("pageTitle", "fr", fallback: Fallback.To(Fallback.Language, Fallback.Ancestors))
+ ```
+* In this example, we are looking for content firstly on the current node for the default language, and if not found we'll search through the ancestors. If failing to find any populated value from them, we'll use the provided default:
+
+ ```csharp
+ @Model.Value("pageTitle", fallback: Fallback.To(Fallback.Ancestors, Fallback.DefaultValue), defaultValue: new HtmlString("Default page title"))
+ ```
+* We can use similar overloads when working with ModelsBuilder, for example:
+
+ ```csharp
+ // For projects created before January 2020
+ @Model.Value(x => x.PageTitle, "fr", fallback: Fallback.ToLanguage)
+ @Model.Value(x => x.PageTitle, fallback: Fallback.To(Fallback.Ancestors, Fallback.DefaultValue), defaultValue: new HtmlString("Default page title"))
+
+ // For projects created after January 2020
+ @Model.ValueFor(x => x.PageTitle, "fr", fallback: Fallback.ToLanguage)
+ @Model.ValueFor(x => x.PageTitle, fallback: Fallback.To(Fallback.Ancestors, Fallback.DefaultValue), defaultValue: new HtmlString("Default page title"))
+ ```
+
+ * Fall-back languages can be configured via the **Languages** tree within the **Settings** section.
+ * Each language can optionally be provided with a fall-back language, that will be used when content is not populated for the language requested and the appropriate overload parameters are provided.
+ * It is possible to chain these language fall-backs, so requesting content for Portuguese, could fall-back to Spanish and then on to English.
+
+ 
+
+## Query content
+
+In many cases, you want to do more than display values from the current page, like creating a list of pages in the navigation. You can access content relative to the current page using methods such as `Children()`, `Descendants()` & `Ancestors()`. Explore the [full list of methods](../../reference/templating/mvc/querying.md#traversing).
+
+You can do this by querying content relative to your current page in template views:
+
+```csharp
+
+```
+
+You can use the Query Builder in the template editor to build more advanced queries. 
+
+
+
+### More information
+
+* [Razor examples](../../reference/templating/mvc/examples.md)
+* [Querying](../../reference/templating/mvc/querying.md)
diff --git a/16/umbraco-cms/fundamentals/design/rendering-media.md b/16/umbraco-cms/fundamentals/design/rendering-media.md
new file mode 100644
index 00000000000..e5adb5bcc58
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/rendering-media.md
@@ -0,0 +1,113 @@
+---
+description: "Info on rendering media items and imaging cropping"
+---
+
+# Rendering media
+
+_Templates (Views) can access items in the_ [_Media library_](../data/creating-media/) _to assist in displaying rich content like galleries_.
+
+In the following examples, we will be looking at rendering an `Image`.
+
+Image is only one of the 'types' of Media in Umbraco. The same principles apply to all Media Types. The properties available to render will be different from Media Type to Media Type. For example, a `File` will not have a Width property.
+
+## Rendering a media item
+
+A media item is not only a reference to a static file. Like content, it is a collection of fields, such as width, height, and file path. This means that accessing and rendering media in a Template is similar to rendering content.
+
+### Example 1: Accessing a Media Image IPublishedContent item based on the ID
+
+An uploaded image in the Media library is based on the Media Type `Image` which has a number of standard properties:
+
+* Name
+* Width & Height
+* Size
+* Type (based on file extension)
+* UmbracoFile (the path to the file or JSON data containing crop information)
+
+These standard properties are pre-populated and set during the upload process. For example, this means that the width and height are calculated for you.
+
+If you want to add further properties to use with your Media Item, edit the Image Media Type under **Settings**. In this example, we are going to retrieve an image from the Media section. Then we will render out an `img` tag using the URL of the media item and use the Name as the value for the `alt` attribute.
+
+{% hint style="info" %}
+The Media item in the following sample will use a sample Guid (`55240594-b265-4fc2-b1c1-feffc5cf9571`). This example is **not using Models Builder**.
+{% endhint %}
+
+```csharp
+@{
+ // The Umbraco Helper has a Media method that will retrieve a Media Item by Guid in the form of IPublishedContent. In this example, the Media Item has a Guid of 55240594-b265-4fc2-b1c1-feffc5cf9571
+
+ var mediaItem = Umbraco.Media(Guid.Parse("55240594-b265-4fc2-b1c1-feffc5cf9571"));
+
+ if (mediaItem != null)
+ {
+ // To get the URL for your media item, you use the Url method:
+ var url = mediaItem.Url();
+ // to read a property by alias
+ var imageHeight = mediaItem.Value("umbracoHeight");
+ var imageWidth = mediaItem.Value("umbracoWidth");
+ var orientationCssClass = imageWidth > imageHeight ? "img-landscape" : "img-portrait";
+
+
+ }
+}
+```
+
+But wait a second, Umbraco comes with [Models Builder](../../reference/templating/modelsbuilder/). This means that you can use strongly typed models for your media items if Models Builder is enabled (which it is by default).
+
+### Example 2: Accessing a Media Image ModelsBuilder item based on the ID
+
+As with example one, we are accessing a MediaType `image` using the same Guid assumption.
+
+```csharp
+@{
+ // Since the Image Model generated by Modelsbuilder is a compatible type to IPublishedContent we can use the 'as' operator to convert it into the ModelsBuilder Umbraco.Cms.Web.Common.PublishedModels.Image class
+ var mediaItemAsImage = Umbraco.Media(Guid.Parse("55240594-b265-4fc2-b1c1-feffc5cf9571")) as Image;
+ if (mediaItemAsImage != null)
+ {
+ // you could add this as an extension method to the Umbraco.Cms.Web.Common.PublishedModels.Image class
+ var orientationCssClass = mediaItemAsImage.UmbracoWidth > mediaItemAsImage.UmbracoHeight ? "img-landscape" : "img-portrait";
+
+
+ }
+}
+```
+
+{% hint style="info" %}
+It is always worth having null-checks around your code when retrieving media in case the conversion fails or Media() returns null. This makes your code more robust.
+{% endhint %}
+
+### Other Media Items such as `File`
+
+Accessing other media items can be performed in the same way. The techniques are not limited to the `Image` type, but it is one of the most common use cases.
+
+## Image Cropper
+
+The Image Cropper can be used with `Image` Media Types and is the default option for the `umbracoFile` property on an `Image` Media Type.
+
+When working with the Image Cropper for an image the `GetCropUrl` extension method is used to retrieve cropped versions of the image. Details of the Image Cropper property editor and other examples of using it can be found in the [Image Cropper article](../backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md). The following is an example to help you get started with the Image Cropper.
+
+### Example of using Image Cropper
+
+```csharp
+@{
+ var mediaItemToCrop = Umbraco.Media(Guid.Parse("55240594-b265-4fc2-b1c1-feffc5cf9571"));
+ if (mediaItemToCrop != null)
+ {
+
+ }
+}
+```
+
+This example assumes that you have set up a crop called **square** on your Image Cropper Data Type.
+
+If you want the original, uncropped image, you can ignore the GetCropUrl extension method and use one of the previously discussed approaches as shown below.
+
+```csharp
+
+```
+
+### More information
+
+* [Media Picker](../backoffice/property-editors/built-in-umbraco-property-editors/media-picker-3.md)
+* [Image Cropper](../backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md)
+* [Creating a Media Type](../data/creating-media/#creating-a-media-type)
diff --git a/16/umbraco-cms/fundamentals/design/stylesheets-javascript.md b/16/umbraco-cms/fundamentals/design/stylesheets-javascript.md
new file mode 100644
index 00000000000..5d58387f0af
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/stylesheets-javascript.md
@@ -0,0 +1,81 @@
+---
+description: >-
+ Information on working with stylesheets and JavaScript in Umbraco, including
+ bundling & minification.
+---
+
+# Stylesheets And JavaScript
+
+## Stylesheets in the Backoffice
+
+You can create and edit stylesheets in the Stylesheets folder in the Settings section of the Backoffice.
+
+
Creating a new stylesheet
+
+In the Create menu, these options are available:
+
+* Stylesheet file (for use in templates/views)
+* Rich Text Editor stylesheet file (for use in [Rich Text Editor](../backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/))
+* Folder (for keeping stylesheets organized)
+
+{% hint style="info" %}
+It is currently not possible to use any CSS preprocessor (such as Syntactically Awesome Style Sheets (SASS)) in the backoffice.
+{% endhint %}
+
+After creating a new stylesheet, you would work with it as you would with templates or JavaScript files - using the built-in backoffice text editor. When you're working with stylesheets, you also have access to the Rich Text Editor, which allows you to create CSS styles and get a real-time preview.
+
+
+
+The rules you create in the Rich Text Editor section will carry over to the Code tab.
+
+ 
+
+To reference your newly included stylesheet in a template file, navigate to Templates, pick the template you like (css files are usually referenced in the layout or home templates) and link to it with the `link` tag.
+
+
+
+By default, the stylesheets will be saved in the `wwwroot/css` folder in the solution. To reference them you can use either of the methods used in the above screenshot.
+
+```html
+
+```
+
+or
+
+```html
+
+```
+
+With the stylesheet referenced, you will be able to style the template file with the rules and classes defined in the stylesheet.
+
+Your stylesheets can be used in Rich Text Editors (datatype) as well - please see the [Rich Text Editor](../backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/#rte-styles) documentation for more information.
+
+{% hint style="info" %}
+If your RTE is styled differently on the frontend of the site, the backoffice styling might be getting overwritten by other stylesheets you have included.
+{% endhint %}
+
+## JavaScript files in the Backoffice
+
+To create and edit JavaScript files in the Backoffice, head on over to the Scripts folder in the Settings section of the Backoffice.
+
+
Creating a new JavaScript
+
+From here you can add a new JavaScript file, or a new folder.
+
+Add a new JavaScript file and write your code:
+
+
+
+Then, navigate to the template where you would like to include your JS file.
+
+```html
+
+```
+
+
+
+By default all JavaScript files will be stored in the `wwwroot/scripts` folder in the solution.
+
+{% hint style="info" %}
+If you are working locally, you can create CSS and JS files outside of the Backoffice - as long as they are placed in appropriate folders (`css` and `scripts`), they will show up in the Backoffice when you click **...** next to the **Stylesheets** folder and then select **Reload**.
+{% endhint %}
diff --git a/16/umbraco-cms/fundamentals/design/templates/README.md b/16/umbraco-cms/fundamentals/design/templates/README.md
new file mode 100644
index 00000000000..01d90a986a0
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/templates/README.md
@@ -0,0 +1,193 @@
+---
+description: Templating in Umbraco builds on the concept of Razor Views from ASP.NET MVC.
+---
+
+# Templates
+
+Templates are the files that control the look and feel of the frontend of your Umbraco websites. Building on the concept of MVC Razor Views, template files enable you to structure your websites using HTML, CSS, and JavaScript. When tied to a Document Type, templates are used to render your Umbraco content on the frontend.
+
+You can manage and work with your templates directly from the Settings section in the Umbraco backoffice. Each Template can also be found as a `cshtml` file in the `Views` folder in your project directory.
+
+## Creating Templates
+
+When building an Umbraco website you can automatically generate Templates when you create a new Document Type. This will ensure the connection between the two and you can jump straight from defining the content to structuring it.
+
+Choose the option called **[Document Type with Template](../../data/defining-content/README.md)** when you create a new Document Type to automatically create a Template as well.
+
+In some cases, you might want to create independent Templates that don't have a direct connection to a Document Type. You can follow the steps below to create a new blank Template:
+
+1. Go to the **Settings** section inside the Umbraco backoffice.
+2. Click **...** next to the **Templates** folder.
+3. Choose **Create**.
+4. Enter a template name.
+5. Click the **Save** button.
+
+You will now see the default template markup in the backoffice template editor.
+
+
+
+## Allowing a Template on a Document Type
+
+To use a Template on your content, you must first allow it on the content Document Type.
+
+1. Open the Document Type you want to use the template.
+2. Open the **Templates** Workspace View.
+3. Select your Template under the **Allowed Templates** section.
+
+
+
+## Inheriting a Template
+
+A Template can inherit content from a "Master Template". This is done by using the ASP.NET views Layout feature.
+
+Let's say you have a Template called **MainView**, containing the following HTML:
+
+```csharp
+@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
+@{
+ Layout = null;
+}
+
+
+
+
Hello world
+ @RenderBody()
+
+
+```
+
+This file contains the structural HTML tags for your website.
+
+By using the Template as the "Master Template" on your other Templates, you can ensure that they inherit the same structural HTML.
+
+Follow these steps to use a Template file as a Master Template:
+
+1. Open one of your Template files.
+2. Select the **Master template: No master** button above the editor.
+3. Select the Template that should be defined as the Master Template.
+4. Click **Choose**.
+
+
+
+Alternatively, you can manually change the value of the `Layout` variable in the Template using the name of the Template file.
+
+The updated markup will look something like the snippet below and the Template is now referred to as a *Child Template*:
+
+```csharp
+@inherits Umbraco.Web.Mvc.UmbracoViewPage
+@{
+ Layout = "MainView.cshtml";
+}
+
My content
+```
+
+When a page that uses a Template with a Master Template defined is rendered, the HTML of the two templates is merged.
+
+The code from the Template replaces the `@RenderBody()` tag in the Master Template. Following the examples above, the final HTML will look like the code in the snippet below:
+
+```csharp
+@inherits Umbraco.Web.Mvc.UmbracoViewPage
+@{
+ Layout = null;
+}
+
+
+
+
Hello world
+
My content
+
+
+```
+
+## Named Sections
+
+Template Sections give you added flexibility when building your templates. Use the Template Section together with a Master Template setup, to decide where sections of content are placed.
+
+If a Child Template needs to add code to the `` tag a Section must be defined and then used in the Master Template. This is made possible by [Named Sections](https://www.youtube.com/watch?v=lrnJwglbGUA).
+
+The following steps will guide you through defining and using a Named Section:
+
+1. Open your Template.
+2. Select the **Sections** option.
+3. Choose **Define a named section**.
+4. Give the section a name and click **Submit**.
+
+
+
+The following code will be added to your Template:
+
+```csharp
+@section SectionName {
+
+}
+```
+
+5. Add your code between the curly brackets.
+6. Save the changes.
+7. Open the Master Template.
+8. Choose a spot for the section and set the cursor there.
+9. Select the **Sections** option.
+10. Choose **Render a named section**.
+11. Enter the name of the section you want to add.
+12. Click **Submit**.
+
+For instance, if you want to be able to add HTML to your `` tags, you would add the tag there:
+
+```csharp
+@inherits Umbraco.Web.Mvc.UmbracoViewPage
+@{
+ Layout = null;
+}
+
+
+
+ Title
+ @RenderSection("SectionName", false)
+
+
+
+
+
+```
+
+You can decide whether a section should be mandatory or not. Making a section mandatory means that any template using the Master Template is required to have the section defined.
+
+{% hint style="info" %}
+Keep in mind that whenever a mandatory named section is missing, it will result in errors on your website.
+{% endhint %}
+
+To make the section mandatory, you have two options:
+
+* Add `true` to the code tag: `@RenderSection("SectionName", true)`.
+* Check the **Section is mandatory** field when using the **Sections** dialog in the backoffice.
+
+
+
+## Injecting Partial Views
+
+Another way to reuse HTML is to use partial views - which are small reusable views that can be injected into another view.
+
+Like templates, you can create a partial view, by clicking **...** next to the **Partial Views** folder and selecting **Create**. You can then either create an empty partial view or a partial view from a snippet.
+
+
+
+The created partial view can now be injected into any template by using the `@Html.Partial()` method like so:
+
+```csharp
+@inherits Umbraco.Web.Mvc.UmbracoViewPage
+@{
+ Layout = "MasterView.cshtml";
+}
+
+
My new page
+@Html.Partial("a-new-view")
+```
+
+### Related Articles
+
+* [Basic Razor syntax](basic-razor-syntax.md)
+* [Rendering content](../rendering-content.md)
+
+### Tutorials
+
+* [Creating a basic website with Umbraco](../../../tutorials/creating-a-basic-website/)
diff --git a/16/umbraco-cms/fundamentals/design/templates/basic-razor-syntax.md b/16/umbraco-cms/fundamentals/design/templates/basic-razor-syntax.md
new file mode 100644
index 00000000000..0d886804f75
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/templates/basic-razor-syntax.md
@@ -0,0 +1,107 @@
+---
+description: "How to perform common logical tasks in Razor like if/else, foreach loops, switch statements and using the @ character to separate code and markup"
+---
+
+# Basic Razor Syntax
+
+_Shows how to perform common logical tasks in Razor like if/else, foreach loops, switch statements and using the @ character to separate code and markup._
+
+## The @ symbol
+
+The @ symbol is used in Razor to initiate code, and tell the compiler where to start interpreting code, instead of returning the content of the file as text. Using a single character for this separation, results in cleaner, compact code which is easier to read.
+
+```csharp
+@* Writing a value inside a html element *@
+
+
@Model.Name
+
+@* Inside an attribute *@
+@Model.Name
+
+@* Using it to start logical structures *@
+@if (selection?.Length > 0)
+{
+
+}
+```
+
+## Embedding comments in razor
+
+Commenting your code is important, use comments to explain what the code does. `@* *@` indicates a comment, which will not be visible in the rendered output.
+
+```csharp
+@* Here we check if the name is equal to foobar *@
+@if (Model.Name == "foobar")
+{
+ @foreach (var child in Model.Children())
+ {
+ @* here we write stuff for each child page *@
+
write stuff
+ }
+}
+```
+
+## If/else
+
+If/else statements perform one task if a condition is true, and another if the condition is not true
+
+```csharp
+@if (Model.Name == "home")
+{
+
+}
+```
+
+## Foreach loops
+
+A foreach loop goes through a collection of items, typically a collection of pages and performs an action for each item
+
+```csharp
+@foreach (var item in Model.Children())
+{
+
The item name is: @Item.Name
+}
+```
+
+## Switch block
+
+A Switch block is used when testing a large number of conditions
+
+```csharp
+@switch (Model.WeekDay)
+{
+ case "Monday":
+ "
It is Monday
";
+ break;
+ case "Tuesday":
+ "
It is Tuesday
";
+ break;
+ case "Wednesday":
+ "
It is Wednesday
";
+ break;
+ default:
+ "
It's some day of the week
";
+ break;
+}
+```
+
+### More information
+
+- [More examples](../../../reference/templating/mvc/examples.md)
+- [Querying](../../../reference/querying/README.md)
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/Sections-option.png b/16/umbraco-cms/fundamentals/design/templates/images/Sections-option.png
new file mode 100644
index 00000000000..cbff077027e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/Sections-option.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/allow-template-v8.png b/16/umbraco-cms/fundamentals/design/templates/images/allow-template-v8.png
new file mode 100644
index 00000000000..a18945a38da
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/allow-template-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/allow-template.png b/16/umbraco-cms/fundamentals/design/templates/images/allow-template.png
new file mode 100644
index 00000000000..d35ea803f7b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/allow-template.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/create-partial-v8.png b/16/umbraco-cms/fundamentals/design/templates/images/create-partial-v8.png
new file mode 100644
index 00000000000..3f51d809f52
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/create-partial-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/create-partial.png b/16/umbraco-cms/fundamentals/design/templates/images/create-partial.png
new file mode 100644
index 00000000000..f2db936d658
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/create-partial.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/create-template-v8.png b/16/umbraco-cms/fundamentals/design/templates/images/create-template-v8.png
new file mode 100644
index 00000000000..47fa57416a0
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/create-template-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/create-template.png b/16/umbraco-cms/fundamentals/design/templates/images/create-template.png
new file mode 100644
index 00000000000..7a4805ff22a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/create-template.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/defined-named-section.png b/16/umbraco-cms/fundamentals/design/templates/images/defined-named-section.png
new file mode 100644
index 00000000000..082b4b1ce31
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/defined-named-section.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/inherit-template-v8.png b/16/umbraco-cms/fundamentals/design/templates/images/inherit-template-v8.png
new file mode 100644
index 00000000000..cdefa5b56bf
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/inherit-template-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/inherit-template.png b/16/umbraco-cms/fundamentals/design/templates/images/inherit-template.png
new file mode 100644
index 00000000000..1ebcecc4986
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/inherit-template.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/render-named-section-mandatory.png b/16/umbraco-cms/fundamentals/design/templates/images/render-named-section-mandatory.png
new file mode 100644
index 00000000000..2c7edf033ea
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/render-named-section-mandatory.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/template-sections-v8.png b/16/umbraco-cms/fundamentals/design/templates/images/template-sections-v8.png
new file mode 100644
index 00000000000..d8ce4c1268e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/template-sections-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/images/template-sections.png b/16/umbraco-cms/fundamentals/design/templates/images/template-sections.png
new file mode 100644
index 00000000000..d8ce4c1268e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/design/templates/images/template-sections.png differ
diff --git a/16/umbraco-cms/fundamentals/design/templates/razor-cheatsheet.md b/16/umbraco-cms/fundamentals/design/templates/razor-cheatsheet.md
new file mode 100644
index 00000000000..991507fe1eb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/design/templates/razor-cheatsheet.md
@@ -0,0 +1,20 @@
+---
+description: "All the code snippets you need to get a jump start on building templates with Razor in Umbraco CMS."
+---
+
+# Razor Cheatsheet
+
+The Razor Cheatsheet is a collection of common methods used for building templates and views in Umbraco CMS.
+
+Get the Umbraco 11 Cheatsheet: [https://umbra.co/razorCheatsheet](https://umbra.co/razorCheatsheet)
+
+You can also find the [cheatsheet on GitHub](https://github.com/umbraco/UmbracoDocs/tree/RazorCheatSheet) where you can give feedback, contribute, or download the template used to _generate_ the sheet.
+
+Use the cheatsheet if you:
+
+* Use Models Builder on your project and
+* Use Umbraco 11.
+
+{% hint style="info" %}
+Most of the methods in the Umbraco 11 version of the cheatsheet will also work in Umbraco 10 and 9.
+{% endhint %}
diff --git a/16/umbraco-cms/fundamentals/get-to-know-umbraco.md b/16/umbraco-cms/fundamentals/get-to-know-umbraco.md
new file mode 100644
index 00000000000..f24a8db91ab
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/get-to-know-umbraco.md
@@ -0,0 +1,11 @@
+---
+description: >-
+ All the fundamentals of using Umbraco - from making a local installation to
+ extending the backend.
+---
+
+# Get to know Umbraco
+
+In this part of the Umbraco CMS documentation, you can get to know the product and the default functionality. It is here you start your Umbraco journey with the installation, setup, and basics of working with the CMS.
+
+
Setup
Find requirements for both local development and hosting as well as guides for installing and upgrading Umbraco CMS.
diff --git a/16/umbraco-cms/fundamentals/setup/README.md b/16/umbraco-cms/fundamentals/setup/README.md
new file mode 100644
index 00000000000..c04f0fc4329
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/setup/README.md
@@ -0,0 +1,31 @@
+---
+description: "Information on the requirements to setup, install & upgrade Umbraco"
+---
+
+# Setup
+
+How to install and configure your Umbraco installation.
+
+## [Requirements](requirements.md)
+
+Defines the system requirements to run Umbraco.
+
+## [Installation](install/README.md)
+
+Umbraco installation steps and guidelines.
+
+## [Upgrade your project](upgrading/README.md)
+
+Covers the steps to upgrade your copy of Umbraco to a newer version.
+
+## [Server setup](server-setup/README.md)
+
+Information about server setup for Umbraco including information about permissions and load balancing.
+
+## [Configuration](../../reference/configuration/README.md)
+
+How to configure your Umbraco installation. Includes information about all of Umbraco's configuration files and options.
+
+## [Installing Nightly Builds](install/installing-nightly-builds.md)
+
+How to install the latest nightly builds.
diff --git a/16/umbraco-cms/fundamentals/setup/install/README.md b/16/umbraco-cms/fundamentals/setup/install/README.md
new file mode 100644
index 00000000000..a184166a46b
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/setup/install/README.md
@@ -0,0 +1,83 @@
+---
+description: Instructions on installing Umbraco on various platforms using various tools.
+---
+
+# Installation
+
+## Install Umbraco using CLI
+
+The fastest way to get the latest version of Umbraco up and running is using the command line (CLI).
+
+1. Open your command line.
+2. Install the Umbraco templates:
+
+```bash
+dotnet new install Umbraco.Templates
+```
+
+3. Create a new project:
+
+```bash
+dotnet new umbraco --name MyProject
+```
+
+4. Navigate to the newly created project folder. It will be the folder containing the `.csproj` file:
+
+```bash
+cd MyProject
+```
+
+5. Build and run the newly created Umbraco site:
+
+```bash
+dotnet run
+```
+
+6. The console will output a message similar to: `[10:57:39 INF] Now listening on: https://localhost:44388`
+
+{% hint style="info" %}
+We recommend setting up a developer certificate and running the website under HTTPS. If that has not yet been configured, run the following command:
+
+```console
+dotnet dev-certs https --trust
+```
+{% endhint %}
+
+7. Open your browser and navigate to that URL.
+8. Follow the instructions to finish up the installation of Umbraco.
+
+{% hint style="info" %}
+Members of the Umbraco Community have created a website that makes the installation of Umbraco a lot easier for you. You can find the website at [https://psw.codeshare.co.uk](https://psw.codeshare.co.uk). On the website, you can configure your options to generate the required script to run. Click on the Install Script tab to get the commands you need to paste into the terminal. This tab also includes the commands for adding a starter kit or unattended install which creates the database for you.
+{% endhint %}
+
+## Alternative Methods for Installing Umbraco
+
+There are numerous ways to install Umbraco. Below, you can find links to different installation methods that will help you easily install and set up Umbraco projects.
+
+### [.NET CLI installation](install-umbraco-with-templates.md)
+
+.NET CLI, included with the .NET Software Development Kit (SDK), can be used to install or uninstall .NET templates from NuGet. This can be done by using the `dotnet new` command on any OS. The underlying Template Engine enables the creation of custom templates which make new project bootstrapping much faster. With a few steps you can have an Umbraco project running without the need for a code editor.
+
+### [Visual Studio installation](visual-studio.md)
+
+Visual Studio is used to write native code and managed code supported by .NET and many others. Its built-in tools provide the ability to develop and execute applications for any platform. Developers will be able to install Umbraco without ever having to leave Visual Studio.
+
+### [Run Umbraco on IIS](iis.md)
+
+Learn how to run an already installed local installation of Umbraco.
+
+### [VS Code installation](install-umbraco-with-vs-code.md)
+
+Visual Studio Code is an editor with an embedded webserver (through the IIS Express extension). A fast way to get you up and running with Umbraco.
+
+### [Installing Nightly Builds](installing-nightly-builds.md)
+
+From Umbraco v9 and above you can use the Nightly Builds to get the latest version to use and test before it is released. Learn how to install the Nightly builds to get started.
+
+### [Running Umbraco on Linux/macOS](running-umbraco-on-linux-macos.md)
+
+Since Umbraco 9 it has been possible to run Umbraco CMS natively on Linux or macOS High Sierra. To get Umbraco running you will need to follow some steps.
+
+### [Install Umbraco unattended](unattended-install.md)
+
+Use the Unattended installs when spinning up Umbraco instances on something like Azure Web Apps to avoid having to run through the installation wizard.
diff --git a/16/umbraco-cms/fundamentals/setup/install/iis.md b/16/umbraco-cms/fundamentals/setup/install/iis.md
new file mode 100644
index 00000000000..c6ce71b85c1
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/setup/install/iis.md
@@ -0,0 +1,113 @@
+---
+description: This article describes how to run an Umbraco 9 site on a local IIS server.
+---
+
+# Local IIS With Umbraco
+
+This is a quick guide on getting your Umbraco website running locally on IIS.
+
+The guide will assume you already have IIS configured and know your way around it, as well as having a local website you wish to host.
+
+## Setting up prerequisites
+
+First, you need to ensure you have "Development time IIS support installed". To check this, go to the Visual Studio installer, click modify and check on the right side under "ASP.NET and web development":
+
+
+
+Once that is installed you should set up a new IIS site - and make sure to add the hostname to your hosts file as well. Here is my setup for an example:
+
+
+
+{% hint style="info" %}
+For the path you want to point it at the root of your site - where the `.csproj` file is.
+{% endhint %}
+
+## Add permissions to NuGet cache folder
+
+You might need to change permissions for the NuGet cache folder - `C:\users\\.nuget\packages`. The user or group (IIS\_IUSRS) that the IIS site is running on requires Read permissions on this folder because this is where some of the files for Umbraco and Umbraco packages are being served from during development. If the IIS user or group does not have permission to read from the NuGet cache folder, you could run into a `DirectoryNotFoundException` while running the site.
+
+When the site is published these files are copied from the NuGet cache folder to `wwwroot/umbraco` and `wwwroot/App_Plugins` and these folders will typically have the correct permissions. For more information on setting permissions, see the [File and folder permissions](../server-setup/permissions.md) article.
+
+## Add new launch profile
+
+At this point you can go to your Visual Studio solution of the site and in the `Properties` folder there is a `launchSettings.json` file, that looks like this:
+
+```json
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:40264",
+ "sslPort": 44360
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Umbraco.Web.UI.NetCore": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:44360;http://localhost:40264"
+ }
+ }
+}
+```
+
+You can add a new profile called IIS, and point it at your local domain. Here it is with my example domain:
+
+```json
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iis": {
+ "applicationUrl": "https://testsite.local",
+ "sslPort": 0
+ },
+ "iisExpress": {
+ "applicationUrl": "http://localhost:40264",
+ "sslPort": 44360
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS": {
+ "commandName": "IIS",
+ "launchBrowser": true,
+ "launchUrl": "https://testsite.local",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Umbraco.Web.UI.NetCore": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:44360;http://localhost:40264"
+ }
+ }
+}
+```
+
+At this point IIS will be added to the launch profiles, and you can run the site from Visual Studio by choosing IIS in the dropdown:
+
+
+
+And finally the site is running from your local IIS:
+
+
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204006.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204006.png
new file mode 100644
index 00000000000..1d3c945c2a9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204006.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204144.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204144.png
new file mode 100644
index 00000000000..c7c600948b3
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204144.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204429.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204429.png
new file mode 100644
index 00000000000..52dbb612873
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204429.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204433.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204433.png
new file mode 100644
index 00000000000..efe194d3e53
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_204433.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_223022.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_223022.png
new file mode 100644
index 00000000000..b7dceace3c4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-12_223022.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-17_164508.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-17_164508.png
new file mode 100644
index 00000000000..a1e8f9856b9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-17_164508.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-17_173822.png b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-17_173822.png
new file mode 100644
index 00000000000..78b3a4db373
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Manual/2012-03-17_173822.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Latest_nightly_build_version.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Latest_nightly_build_version.jpg
new file mode 100644
index 00000000000..341da76534c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Latest_nightly_build_version.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Manage_NuGet_Pkgs.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Manage_NuGet_Pkgs.jpg
new file mode 100644
index 00000000000..68138f7e4b6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Manage_NuGet_Pkgs.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Manage_Packages.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Manage_Packages.jpg
new file mode 100644
index 00000000000..9ff2c8538dc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Manage_Packages.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/NewFeed_Details.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/NewFeed_Details.jpg
new file mode 100644
index 00000000000..5ce96af75da
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/NewFeed_Details.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/NuGet_NewFeed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/NuGet_NewFeed.jpg
new file mode 100644
index 00000000000..e17dee522b9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/NuGet_NewFeed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Register_Nightly_Feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Register_Nightly_Feed.jpg
new file mode 100644
index 00000000000..bd549030ecc
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Register_Nightly_Feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Rider_Nightly_Feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Rider_Nightly_Feed.jpg
new file mode 100644
index 00000000000..68701876301
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Rider_Nightly_Feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Rider_Nightly_Feed_version.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Rider_Nightly_Feed_version.jpg
new file mode 100644
index 00000000000..9b60bb59f21
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Nightly/Rider_Nightly_Feed_version.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/enable-package-manager-console-v8.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/enable-package-manager-console-v8.png
new file mode 100644
index 00000000000..9b0a1ade255
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/enable-package-manager-console-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/enable-package-manager-console.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/enable-package-manager-console.png
new file mode 100644
index 00000000000..b04913257fe
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/enable-package-manager-console.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/manage-nuget-packages-v8.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/manage-nuget-packages-v8.png
new file mode 100644
index 00000000000..7cb2bc648ed
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/manage-nuget-packages-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/manage-nuget-packages.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/manage-nuget-packages.png
new file mode 100644
index 00000000000..758cdb3f246
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/manage-nuget-packages.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-dotnet4.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-dotnet4.png
new file mode 100644
index 00000000000..18cc5e95e3c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-dotnet4.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2012.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2012.png
new file mode 100644
index 00000000000..8278146c95b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2012.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-1.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-1.png
new file mode 100644
index 00000000000..e336c5e672c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-1.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-2.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-2.png
new file mode 100644
index 00000000000..166878fd19c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-2.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-3.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-3.png
new file mode 100644
index 00000000000..0a9ccb0e8f4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2013-3.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2017-1-v8.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2017-1-v8.png
new file mode 100644
index 00000000000..e745a23ac68
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2017-1-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2017-2-v8.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2017-2-v8.png
new file mode 100644
index 00000000000..0129e11fa81
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/new-project-vs2017-2-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-overwrite-dialog.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-overwrite-dialog.png
new file mode 100644
index 00000000000..9b8dd02ba54
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-overwrite-dialog.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-search-v8.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-search-v8.png
new file mode 100644
index 00000000000..e0edef36004
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-search-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-search.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-search.png
new file mode 100644
index 00000000000..71dd8c30c5d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-search.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-update.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-update.png
new file mode 100644
index 00000000000..1a50a023a0c
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/nuget-update.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/package-manager-console-overwrite.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/package-manager-console-overwrite.png
new file mode 100644
index 00000000000..267d5c0e5d1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/package-manager-console-overwrite.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/package-manager-console.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/package-manager-console.png
new file mode 100644
index 00000000000..2a2b89de938
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/package-manager-console.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/NuGet/visual-studio-version-v8.png b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/visual-studio-version-v8.png
new file mode 100644
index 00000000000..efba7ce0289
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/NuGet/visual-studio-version-v8.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Rider/add-the-feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Rider/add-the-feed.jpg
new file mode 100644
index 00000000000..818aea631f8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Rider/add-the-feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Rider/choose-the-feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Rider/choose-the-feed.jpg
new file mode 100644
index 00000000000..03ad0197afe
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Rider/choose-the-feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Rider/find-the-version.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Rider/find-the-version.jpg
new file mode 100644
index 00000000000..a9a7e2aba07
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Rider/find-the-version.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/Rider/open-add-feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/Rider/open-add-feed.jpg
new file mode 100644
index 00000000000..9212394b306
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/Rider/open-add-feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/Umbraco10_install.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/Umbraco10_install.png
new file mode 100644
index 00000000000..b1005b76548
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/Umbraco10_install.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/additional-info.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/additional-info.png
new file mode 100644
index 00000000000..9429fc52c81
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/additional-info.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/configure-project.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/configure-project.png
new file mode 100644
index 00000000000..b5882efaab7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/configure-project.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/create-project.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/create-project.png
new file mode 100644
index 00000000000..a75a86267b1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/create-project.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/find-the-version.jpg b/16/umbraco-cms/fundamentals/setup/install/images/VS/find-the-version.jpg
new file mode 100644
index 00000000000..7e82fe6ee2b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/find-the-version.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/open-nuget-package-manager.jpg b/16/umbraco-cms/fundamentals/setup/install/images/VS/open-nuget-package-manager.jpg
new file mode 100644
index 00000000000..b671b595c7a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/open-nuget-package-manager.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/open-nuget-setttings.jpg b/16/umbraco-cms/fundamentals/setup/install/images/VS/open-nuget-setttings.jpg
new file mode 100644
index 00000000000..bf51a558012
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/open-nuget-setttings.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/ready-solution.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/ready-solution.png
new file mode 100644
index 00000000000..9059c79ec2f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/ready-solution.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/registering-nightly-feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/VS/registering-nightly-feed.jpg
new file mode 100644
index 00000000000..468f63a7e1e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/registering-nightly-feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/select-nuget-feed.jpg b/16/umbraco-cms/fundamentals/setup/install/images/VS/select-nuget-feed.jpg
new file mode 100644
index 00000000000..2479463ebbd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/select-nuget-feed.jpg differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/visual-studio-version-v10.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/visual-studio-version-v10.png
new file mode 100644
index 00000000000..16638b8c2a9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/visual-studio-version-v10.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VS/visual-studio-version-v9.png b/16/umbraco-cms/fundamentals/setup/install/images/VS/visual-studio-version-v9.png
new file mode 100644
index 00000000000..e7aea38b466
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VS/visual-studio-version-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/1.PNG b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/1.PNG
new file mode 100644
index 00000000000..f279c232dde
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/1.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/2.PNG b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/2.PNG
new file mode 100644
index 00000000000..cb5d150d76a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/2.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/3.PNG b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/3.PNG
new file mode 100644
index 00000000000..e5759f35f58
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/3.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/4.PNG b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/4.PNG
new file mode 100644
index 00000000000..364fe1c4a3f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/4.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/ConfigureTask.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/ConfigureTask.png
new file mode 100644
index 00000000000..880a0e3e594
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/ConfigureTask.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/Installer-v8.PNG b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/Installer-v8.PNG
new file mode 100644
index 00000000000..3b9d2a263a6
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/Installer-v8.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/Installer-v9.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/Installer-v9.png
new file mode 100644
index 00000000000..30036fadebb
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/Installer-v9.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/NetcoreTask.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/NetcoreTask.png
new file mode 100644
index 00000000000..41d2f75c4b4
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/NetcoreTask.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/NetcoreTemplate.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/NetcoreTemplate.png
new file mode 100644
index 00000000000..f8f28bc4d02
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/NetcoreTemplate.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/TaskJsonFromTemplate.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/TaskJsonFromTemplate.png
new file mode 100644
index 00000000000..8c11cb849b1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/TaskJsonFromTemplate.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/VsCodeExtension.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/VsCodeExtension.png
new file mode 100644
index 00000000000..8cdb2030c56
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/VsCodeExtension.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/creatingLaunchFile.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/creatingLaunchFile.png
new file mode 100644
index 00000000000..3f4d7881f43
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/creatingLaunchFile.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/dashboard-v8.PNG b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/dashboard-v8.PNG
new file mode 100644
index 00000000000..1855ef73dac
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/dashboard-v8.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/VsCode/netcoreStructure.png b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/netcoreStructure.png
new file mode 100644
index 00000000000..2080f1f70a9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/VsCode/netcoreStructure.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-db-CE.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-db-CE.png
new file mode 100644
index 00000000000..b0554e526b1
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-db-CE.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-db-install.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-db-install.png
new file mode 100644
index 00000000000..f19b1d36b03
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-db-install.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-finish.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-finish.png
new file mode 100644
index 00000000000..e2d51d1801b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-finish.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-start.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-start.png
new file mode 100644
index 00000000000..e16b4d6e776
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-start.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-starter-kit.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-starter-kit.png
new file mode 100644
index 00000000000..a3cea2b6991
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-starter-kit.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-user.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-user.png
new file mode 100644
index 00000000000..a92f5250986
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/web-user.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-license.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-license.png
new file mode 100644
index 00000000000..49dffdfbe4e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-license.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-search.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-search.png
new file mode 100644
index 00000000000..97d50abf896
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-search.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-start.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-start.png
new file mode 100644
index 00000000000..5e2c73592d5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix-start.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-database.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-database.png
new file mode 100644
index 00000000000..62b51b346e9
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-database.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-install-complete.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-install-complete.png
new file mode 100644
index 00000000000..6d11719b8be
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-install-complete.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-localhost.png b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-localhost.png
new file mode 100644
index 00000000000..0f913f58c8a
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-localhost.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-start.PNG b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-start.PNG
new file mode 100644
index 00000000000..9c11306027f
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebMatrix/webmatrix3-start.PNG differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/add-from-gallery.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/add-from-gallery.png
new file mode 100644
index 00000000000..eeadc0a3d48
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/add-from-gallery.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/complete.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/complete.png
new file mode 100644
index 00000000000..71b4bb4bbbd
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/complete.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-step1.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-step1.png
new file mode 100644
index 00000000000..1c01b42223b
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-step1.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-step2.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-step2.png
new file mode 100644
index 00000000000..19fe74b991d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-step2.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-type.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-type.png
new file mode 100644
index 00000000000..44f2d5eabf8
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/db-type.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/download-files.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/download-files.png
new file mode 100644
index 00000000000..680395ed6f7
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/download-files.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/search-umbraco.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/search-umbraco.png
new file mode 100644
index 00000000000..e24d4ab579e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/search-umbraco.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/warning.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/warning.png
new file mode 100644
index 00000000000..72f22d11b5d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/warning.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-db.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-db.png
new file mode 100644
index 00000000000..be216c66262
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-db.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-done.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-done.png
new file mode 100644
index 00000000000..5df0672bfca
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-done.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-install.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-install.png
new file mode 100644
index 00000000000..170c569fb26
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-install.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-start.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-start.png
new file mode 100644
index 00000000000..3326f300736
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-start.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-starter.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-starter.png
new file mode 100644
index 00000000000..a32e55d9d4d
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-starter.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-user.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-user.png
new file mode 100644
index 00000000000..16e19cf1d93
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/web-user.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/WebPl/website.png b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/website.png
new file mode 100644
index 00000000000..b578ff608be
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/WebPl/website.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/iis-module.png b/16/umbraco-cms/fundamentals/setup/install/images/iis-module.png
new file mode 100644
index 00000000000..b139dcb4804
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/iis-module.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/iis-site.png b/16/umbraco-cms/fundamentals/setup/install/images/iis-site.png
new file mode 100644
index 00000000000..dd07e16fb94
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/iis-site.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/installer.png b/16/umbraco-cms/fundamentals/setup/install/images/installer.png
new file mode 100644
index 00000000000..2c109064317
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/installer.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/launchprofiles.png b/16/umbraco-cms/fundamentals/setup/install/images/launchprofiles.png
new file mode 100644
index 00000000000..7cc99dd19c5
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/launchprofiles.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/unattended/VS-unattended-install.png b/16/umbraco-cms/fundamentals/setup/install/images/unattended/VS-unattended-install.png
new file mode 100644
index 00000000000..058af6bad78
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/unattended/VS-unattended-install.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/unattended/final-screen.png b/16/umbraco-cms/fundamentals/setup/install/images/unattended/final-screen.png
new file mode 100644
index 00000000000..f20cd2a606e
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/unattended/final-screen.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/images/voila.png b/16/umbraco-cms/fundamentals/setup/install/images/voila.png
new file mode 100644
index 00000000000..1b094bdb556
Binary files /dev/null and b/16/umbraco-cms/fundamentals/setup/install/images/voila.png differ
diff --git a/16/umbraco-cms/fundamentals/setup/install/install-umbraco-with-templates.md b/16/umbraco-cms/fundamentals/setup/install/install-umbraco-with-templates.md
new file mode 100644
index 00000000000..c17d00ba4eb
--- /dev/null
+++ b/16/umbraco-cms/fundamentals/setup/install/install-umbraco-with-templates.md
@@ -0,0 +1,156 @@
+# Install using .NET CLI
+
+We have made custom Umbraco templates that are available for use with `dotnet new`. The steps below will demonstrate the minimum amount of actions required to get you going and set up an Umbraco project from the command line using .NET templates.
+
+## Video Tutorial
+
+{% embed url="https://www.youtube-nocookie.com/embed/ZByL3qILNnI" %}
+Video Tutorial
+{% endembed %}
+
+## Install the template
+
+1. Install the latest [.NET SDK](https://dotnet.microsoft.com/download).
+2. Run `dotnet new install Umbraco.Templates` to install the project templates.
+ _The solution is packaged up into the NuGet package [Umbraco.Templates](https://www.nuget.org/packages/Umbraco.Templates) and can be installed into the dotnet CLI_.
+
+```cli
+Templates Short Name Language Tags
+------------------------------------------------------------------------------------------------------
+Umbraco Project umbraco [C#] Web/CMS/Umbraco
+Umbraco Extension umbraco-extension [C#] Web/CMS/Umbraco/Extension/Plugin/Razor Class Library
+Umbraco Docker Compose umbraco-compose Web/CMS/Umbraco
+```
+
+{% hint style="info" %}
+In some cases the templates may silently fail to install (usually this is an issue with NuGet sources). If this occurs you can try specifying the NuGet source in the command by running `dotnet new install Umbraco.Templates --nuget-source "https://api.nuget.org/v3/index.json"`.
+{% endhint %}
+
+To get **help** on a project template with `dotnet new` run the following command:
+
+`dotnet new umbraco -h`
+
+From that command's output, you will get a better understanding of what are the default template options, as well as those command-line flags specific to Umbraco that you can use (as seen below):
+
+```
+Umbraco Project (C#)
+Author: Umbraco HQ
+Description: An empty Umbraco project ready to get started.
+
+Usage:
+ dotnet new umbraco [options] [template options]
+
+Options:
+ -n, --name The name for the output being created. If no name is specified, the name of the output directory is used.
+ -o, --output