Skip to content

Conversation

@bszyman
Copy link
Contributor

@bszyman bszyman commented Oct 5, 2025

πŸ“‹ Description

The original article seemed like it was written by AI maybe? It was mostly correct, just a few changes and clarifications to make.

πŸ“Ž Related Issues (if applicable)

#7425

βœ… Contributor Checklist

I've followed the Umbraco Documentation Style Guide and can confirm that:

  • Code blocks are correctly formatted.
  • Sentences are short and clear (preferably under 25 words).
  • Passive voice and first-person language (β€œwe”, β€œI”) are avoided.
  • Relevant pages are linked.
  • All links work and point to the correct resources.
  • Screenshots or diagrams are included if useful.
  • Any code examples or instructions have been tested.
  • Typos, broken links, and broken images are fixed.

Product & Version (if relevant)

v16

Deadline (if relevant)

N/A

πŸ“š Helpful Resources

… for consistency, removed outdated warnings, and refined TypeScript integration details.
@bszyman bszyman requested a review from sofietoft October 7, 2025 03:42
Copy link
Contributor

@AndyButland AndyButland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very good to me @bszyman. I made a couple of suggestions you can consider for improvements.

Regarding the one about using UmbExtensionManifestKind, you'll need to verify that, but it is what I see in the source code so even if the syntax you have works, if what I've suggested does too then I think it's better to align with what people might see if they look into the CMS source code.

@nielslyngsoe
Copy link
Member

Hi @bszyman

Looks good, Ive added comments to Andy's comments above, just to confirm his perspectives.

I would like to add for a Kind to show up correctly in TypeScript. Especially relevant if your kinds are to be available for others. Then it is important also to define Types for the Kind.

For the particular example, it would look like this:

export interface CustomManifestHeaderAppButtonKind extends ManifestHeaderApp {
	type: 'customHeaderAppButton';
	kind: 'button';
	meta: MetaHeaderAppButtonKind;
}

export interface CustomMetaHeaderAppButtonKind {
	href: string;
	label: string;
	icon: string;
}

declare global {
	interface UmbExtensionManifestMap {
		CustomManifestHeaderAppButtonKind: CustomManifestHeaderAppButtonKind;
	}
}

This will give Intellisense when writing a Manifest of that Type and Kind.

For it to be available for others, as in if you are doing a package, that would be a bigger story, properly requiring some article describing how you need to publish your package on NPM and make an export of the package types. So the above 'Global' types can be declared in the tsconfig for the customizatin using CMS & the fictive package.

So similar to how we export extension-types, a package would need to do similar. See TSConfig of this part: https://docs.umbraco.com/umbraco-cms/customizing/development-flow#typescript-setup

Using a package that you like to utilize the Types of β€” would result in a tsconfig looking something like this:

{
    "compilerOptions": {
        ...
        "types": [
            "@umbraco-cms/backoffice/extension-types"
            "@custom-umbraco-package/extension-types"
        ]
    }
}

I hope that perspective makes sense, so that does invite for a Article on exporting types of your package, but the initial hint on how to declare Kind Types, just for internal use could be documented here :-)

@bszyman
Copy link
Contributor Author

bszyman commented Oct 22, 2025

@nielslyngsoe - Appreciate your suggestions!

What I've done in my sample project is added a file types.ts for my sample kind extension and added it adjacent to the manifests.ts file with all the kind manifest definitions.

image

And this is my code, mostly copying what you provided.

import type {
  ManifestHeaderApp,
  MetaHeaderAppButtonKind,
} from "@umbraco-cms/backoffice/extension-registry";

export interface CustomManifestHeaderAppButtonKind extends ManifestHeaderApp {
  type: "customHeaderAppButton";
  kind: "button";
  meta: MetaHeaderAppButtonKind;
}

export interface CustomMetaHeaderAppButtonKind {
  href: string;
  label: string;
  icon: string;
}

declare global {
  interface UmbExtensionManifestMap {
    CustomManifestHeaderAppButtonKind: CustomManifestHeaderAppButtonKind;
  }
}

TS doesn't like the "customHeaderAppButton" value. It seems like it wants either the type property to not be re-defined, or to be defined only as "headerApp".

image

I want to make sure I'm clear/not misunderstanding:

  1. These types will only be useful to other people who might be interested in using them, they're not needed to or useful for defining/implementing the manifests?

  2. The intent of "customHeaderAppButton". Is this supposed to match the name/alias of an extension in the manifest? Or would it be better to omit or use the suggested "headerApp"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants