diff --git a/.changeset/chilly-emus-roll.md b/.changeset/chilly-emus-roll.md
new file mode 100644
index 0000000000..1569820980
--- /dev/null
+++ b/.changeset/chilly-emus-roll.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-home': patch
+---
+
+Add name option to `createCardExtension` to remove deprecation warnings for extensions without name. Name will be required for extensions in a future release of `core-plugin-api` and therefore also in `createCardExtension`.
diff --git a/.changeset/mighty-gifts-visit.md b/.changeset/mighty-gifts-visit.md
new file mode 100644
index 0000000000..8ceab2906e
--- /dev/null
+++ b/.changeset/mighty-gifts-visit.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-bazaar': patch
+---
+
+Name extension to remove deprecation warning
diff --git a/.changeset/quiet-clocks-push.md b/.changeset/quiet-clocks-push.md
new file mode 100644
index 0000000000..2b469a5fc5
--- /dev/null
+++ b/.changeset/quiet-clocks-push.md
@@ -0,0 +1,5 @@
+---
+'@backstage/core-plugin-api': patch
+---
+
+Deprecate use of extensions without name. Adds a warning to the developer console to prompt integrators to provide names for extensions.
diff --git a/docs/features/software-catalog/catalog-customization.md b/docs/features/software-catalog/catalog-customization.md
index 8f855776a0..e80e8a1842 100644
--- a/docs/features/software-catalog/catalog-customization.md
+++ b/docs/features/software-catalog/catalog-customization.md
@@ -172,6 +172,7 @@ This page itself can be exported as a routable extension in the plugin:
```ts
export const CustomCatalogIndexPage = myPlugin.provide(
createRoutableExtension({
+ name: 'CustomCatalogIndexPage',
component: () =>
import('./components/CustomCatalogPage').then(m => m.CustomCatalogPage),
mountPoint: catalogRouteRef,
diff --git a/docs/plugins/composability.md b/docs/plugins/composability.md
index 8d22c05a79..33568ac561 100644
--- a/docs/plugins/composability.md
+++ b/docs/plugins/composability.md
@@ -136,6 +136,7 @@ a component:
```ts
export const FooPage = plugin.provide(
createRoutableExtension({
+ name: 'FooPage',
component: () => import('./components/FooPage').then(m => m.FooPage),
mountPoint: fooPageRouteRef,
}),
@@ -417,6 +418,7 @@ export const myPlugin = createPlugin({
export const MyPage = myPlugin.provide(
createRoutableExtension({
+ name: 'MyPage',
component: () => import('./components/MyPage').then(m => m.MyPage),
mountPoint: rootRouteRef,
}),
diff --git a/docs/plugins/plugin-development.md b/docs/plugins/plugin-development.md
index f61fae0968..362ecc5d5a 100644
--- a/docs/plugins/plugin-development.md
+++ b/docs/plugins/plugin-development.md
@@ -65,6 +65,7 @@ export const examplePlugin = createPlugin({
// Each extension should also be exported from your plugin package.
export const ExamplePage = examplePlugin.provide(
createRoutableExtension({
+ name: 'ExamplePage',
// The component needs to be lazy-loaded. It's what will actually be rendered in the end.
component: () =>
import('./components/ExampleComponent').then(m => m.ExampleComponent),
diff --git a/docs/plugins/structure-of-a-plugin.md b/docs/plugins/structure-of-a-plugin.md
index 83fcfbddba..9e8b67710a 100644
--- a/docs/plugins/structure-of-a-plugin.md
+++ b/docs/plugins/structure-of-a-plugin.md
@@ -73,6 +73,7 @@ export const examplePlugin = createPlugin({
export const ExamplePage = examplePlugin.provide(
createRoutableExtension({
+ name: 'ExamplePage',
component: () =>
import('./components/ExampleComponent').then(m => m.ExampleComponent),
mountPoint: rootRouteRef,
diff --git a/packages/core-app-api/src/app/App.test.tsx b/packages/core-app-api/src/app/App.test.tsx
index ab287a3ece..6ed5d45b86 100644
--- a/packages/core-app-api/src/app/App.test.tsx
+++ b/packages/core-app-api/src/app/App.test.tsx
@@ -169,6 +169,7 @@ describe('Integration Test', () => {
const NavigateComponent = plugin1.provide(
createRoutableExtension({
+ name: 'NavigateComponent',
component: () =>
Promise.resolve((_: PropsWithChildren<{ path?: string }>) => {
return ;
diff --git a/packages/core-plugin-api/src/extensions/extensions.test.tsx b/packages/core-plugin-api/src/extensions/extensions.test.tsx
index 29c696c71f..dcc92d9d47 100644
--- a/packages/core-plugin-api/src/extensions/extensions.test.tsx
+++ b/packages/core-plugin-api/src/extensions/extensions.test.tsx
@@ -41,6 +41,7 @@ describe('extensions', () => {
const Component = () =>
;
const extension = createReactExtension({
+ name: 'Extension',
component: {
sync: Component,
},
@@ -67,6 +68,7 @@ describe('extensions', () => {
});
const extension2 = createRoutableExtension({
+ name: 'Extension2',
component: () => Promise.resolve(Component),
mountPoint: routeRef,
});
diff --git a/packages/core-plugin-api/src/extensions/extensions.tsx b/packages/core-plugin-api/src/extensions/extensions.tsx
index f85570a35b..ca5ada8478 100644
--- a/packages/core-plugin-api/src/extensions/extensions.tsx
+++ b/packages/core-plugin-api/src/extensions/extensions.tsx
@@ -55,7 +55,7 @@ export function createRoutableExtension<
mountPoint: RouteRef;
name?: string;
}): Extension {
- const { component, mountPoint } = options;
+ const { component, mountPoint, name } = options;
return createReactExtension({
component: {
lazy: () =>
@@ -85,7 +85,7 @@ export function createRoutableExtension<
};
const componentName =
- options.name ||
+ name ||
(InnerComponent as { displayName?: string }).displayName ||
InnerComponent.name ||
'LazyComponent';
@@ -108,7 +108,7 @@ export function createRoutableExtension<
data: {
'core.mountPoint': mountPoint,
},
- name: options.name,
+ name,
});
}
@@ -152,7 +152,14 @@ export function createReactExtension<
data?: Record;
name?: string;
}): Extension {
- const { data = {} } = options;
+ const { data = {}, name } = options;
+ if (!name) {
+ // eslint-disable-next-line no-console
+ console.warn(
+ 'Declaring extensions without name is DEPRECATED. ' +
+ 'Make sure that all usages of createReactExtension, createComponentExtension and createRoutableExtension provide a name.',
+ );
+ }
let Component: T;
if ('lazy' in options.component) {
@@ -164,7 +171,7 @@ export function createReactExtension<
Component = options.component.sync;
}
const componentName =
- options.name ||
+ name ||
(Component as { displayName?: string }).displayName ||
Component.name ||
'Component';
@@ -186,7 +193,7 @@ export function createReactExtension<
diff --git a/plugins/bazaar/src/plugin.ts b/plugins/bazaar/src/plugin.ts
index f96eaf522d..5eb5e2aacd 100644
--- a/plugins/bazaar/src/plugin.ts
+++ b/plugins/bazaar/src/plugin.ts
@@ -44,6 +44,7 @@ export const bazaarPlugin = createPlugin({
export const BazaarPage = bazaarPlugin.provide(
createRoutableExtension({
+ name: 'BazaarPage',
component: () => import('./components/HomePage').then(m => m.HomePage),
mountPoint: rootRouteRef,
}),
diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md
index 57b0b899e2..99d88fa4b5 100644
--- a/plugins/home/api-report.md
+++ b/plugins/home/api-report.md
@@ -71,9 +71,11 @@ export const ComponentTabs: ({
export function createCardExtension({
title,
components,
+ name,
}: {
title: string;
components: () => Promise;
+ name?: string;
}): Extension<
({
Renderer,
diff --git a/plugins/home/src/extensions.tsx b/plugins/home/src/extensions.tsx
index 93fe4ceb4f..82394cf1ea 100644
--- a/plugins/home/src/extensions.tsx
+++ b/plugins/home/src/extensions.tsx
@@ -37,11 +37,14 @@ type RendererProps = { title: string } & ComponentParts;
export function createCardExtension({
title,
components,
+ name,
}: {
title: string;
components: () => Promise;
+ name?: string;
}) {
return createReactExtension({
+ name,
component: {
lazy: () =>
components().then(({ Content, Actions, Settings, ContextProvider }) => {
diff --git a/plugins/home/src/plugin.ts b/plugins/home/src/plugin.ts
index d67ea846a5..b4b9f9b6ee 100644
--- a/plugins/home/src/plugin.ts
+++ b/plugins/home/src/plugin.ts
@@ -71,6 +71,7 @@ export const ComponentTab = homePlugin.provide(
*/
export const WelcomeTitle = homePlugin.provide(
createComponentExtension({
+ name: 'WelcomeTitle',
component: {
lazy: () =>
import('./homePageComponents/WelcomeTitle').then(m => m.WelcomeTitle),
@@ -80,6 +81,7 @@ export const WelcomeTitle = homePlugin.provide(
export const HomePageRandomJoke = homePlugin.provide(
createCardExtension<{ defaultCategory?: 'any' | 'programming' }>({
+ name: 'HomePageRandomJoke',
title: 'Random Joke',
components: () => import('./homePageComponents/RandomJoke'),
}),