diff --git a/.changeset/quick-pumpkins-shave.md b/.changeset/quick-pumpkins-shave.md
new file mode 100644
index 0000000000..cbb4c48dce
--- /dev/null
+++ b/.changeset/quick-pumpkins-shave.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-home': patch
+---
+
+Added experimental support for declarative integration via the `/alpha` subpath.
diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx
index 92d71fee89..d64c4dbb15 100644
--- a/packages/app-next/src/App.tsx
+++ b/packages/app-next/src/App.tsx
@@ -20,13 +20,20 @@ import { pagesPlugin } from './examples/pagesPlugin';
import graphiqlPlugin from '@backstage/plugin-graphiql/alpha';
import techRadarPlugin from '@backstage/plugin-tech-radar/alpha';
import userSettingsPlugin from '@backstage/plugin-user-settings/alpha';
+import homePlugin, {
+ titleExtensionDataRef,
+} from '@backstage/plugin-home/alpha';
+
import {
+ coreExtensionData,
+ createExtension,
createExtensionOverrides,
createPageExtension,
} from '@backstage/frontend-plugin-api';
import { entityRouteRef } from '@backstage/plugin-catalog-react';
import techdocsPlugin from '@backstage/plugin-techdocs/alpha';
import { convertLegacyRouteRef } from '@backstage/core-plugin-api/alpha';
+import { homePage } from './HomePage';
/*
@@ -64,6 +71,18 @@ const entityPageExtension = createPageExtension({
loader: async () =>
Just a temporary mocked entity page
,
});
+const homePageExtension = createExtension({
+ id: 'myhomepage',
+ attachTo: { id: 'home', input: 'props' },
+ output: {
+ children: coreExtensionData.reactElement,
+ title: titleExtensionDataRef,
+ },
+ factory({ bind }) {
+ bind({ children: homePage, title: 'just a title' });
+ },
+});
+
const app = createApp({
features: [
graphiqlPlugin,
@@ -71,8 +90,9 @@ const app = createApp({
techRadarPlugin,
techdocsPlugin,
userSettingsPlugin,
+ homePlugin,
createExtensionOverrides({
- extensions: [entityPageExtension],
+ extensions: [entityPageExtension, homePageExtension],
}),
],
/* Handled through config instead */
diff --git a/packages/app-next/src/HomePage.tsx b/packages/app-next/src/HomePage.tsx
new file mode 100644
index 0000000000..cb31beb34a
--- /dev/null
+++ b/packages/app-next/src/HomePage.tsx
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ ClockConfig,
+ CustomHomepageGrid,
+ HeaderWorldClock,
+ HomePageCompanyLogo,
+ HomePageRandomJoke,
+ HomePageStarredEntities,
+ HomePageToolkit,
+ HomePageTopVisited,
+ HomePageRecentlyVisited,
+ WelcomeTitle,
+} from '@backstage/plugin-home';
+import { Content, Header, Page } from '@backstage/core-components';
+import { HomePageCalendar } from '@backstage/plugin-gcalendar';
+import { MicrosoftCalendarCard } from '@backstage/plugin-microsoft-calendar';
+import React from 'react';
+import HomeIcon from '@material-ui/icons/Home';
+import { HomePagePagerDutyCard } from '@backstage/plugin-pagerduty';
+
+const clockConfigs: ClockConfig[] = [
+ {
+ label: 'NYC',
+ timeZone: 'America/New_York',
+ },
+ {
+ label: 'UTC',
+ timeZone: 'UTC',
+ },
+ {
+ label: 'STO',
+ timeZone: 'Europe/Stockholm',
+ },
+ {
+ label: 'TYO',
+ timeZone: 'Asia/Tokyo',
+ },
+];
+
+const timeFormat: Intl.DateTimeFormatOptions = {
+ hour: '2-digit',
+ minute: '2-digit',
+ hour12: false,
+};
+
+const defaultConfig = [
+ {
+ component: 'CompanyLogo',
+ x: 0,
+ y: 0,
+ width: 12,
+ height: 1,
+ movable: false,
+ resizable: false,
+ deletable: false,
+ },
+ {
+ component: 'WelcomeTitle',
+ x: 0,
+ y: 1,
+ width: 12,
+ height: 1,
+ },
+ {
+ component: 'HomePageSearchBar',
+ x: 0,
+ y: 2,
+ width: 12,
+ height: 2,
+ },
+];
+
+export const homePage = (
+
+ } pageTitleOverride="Home">
+
+
+
+
+
+
+
+
+
+
+
+ ,
+ },
+ ]}
+ />
+
+
+
+
+
+);
diff --git a/packages/app-next/src/examples/pagesPlugin.tsx b/packages/app-next/src/examples/pagesPlugin.tsx
index 6e040c2faf..1e9409a5e4 100644
--- a/packages/app-next/src/examples/pagesPlugin.tsx
+++ b/packages/app-next/src/examples/pagesPlugin.tsx
@@ -48,6 +48,9 @@ const IndexPage = createPageExtension({
Page 1
+
+ Home
+
GraphiQL
diff --git a/plugins/home/alpha-api-report.md b/plugins/home/alpha-api-report.md
new file mode 100644
index 0000000000..35ce0bb86c
--- /dev/null
+++ b/plugins/home/alpha-api-report.md
@@ -0,0 +1,17 @@
+## API Report File for "@backstage/plugin-home"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+import { BackstagePlugin } from '@backstage/frontend-plugin-api';
+import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api';
+
+// @alpha (undocumented)
+const _default: BackstagePlugin<{}, {}>;
+export default _default;
+
+// @alpha (undocumented)
+export const titleExtensionDataRef: ConfigurableExtensionDataRef;
+
+// (No @packageDocumentation comment for this package)
+```
diff --git a/plugins/home/package.json b/plugins/home/package.json
index 07e895c243..edb7e6542d 100644
--- a/plugins/home/package.json
+++ b/plugins/home/package.json
@@ -6,9 +6,7 @@
"types": "src/index.ts",
"license": "Apache-2.0",
"publishConfig": {
- "access": "public",
- "main": "dist/index.esm.js",
- "types": "dist/index.d.ts"
+ "access": "public"
},
"backstage": {
"role": "frontend-plugin"
@@ -23,6 +21,21 @@
"backstage",
"homepage"
],
+ "exports": {
+ ".": "./src/index.ts",
+ "./alpha": "./src/alpha.tsx",
+ "./package.json": "./package.json"
+ },
+ "typesVersions": {
+ "*": {
+ "alpha": [
+ "src/alpha.tsx"
+ ],
+ "package.json": [
+ "package.json"
+ ]
+ }
+ },
"sideEffects": false,
"scripts": {
"build": "backstage-cli package build",
@@ -39,6 +52,7 @@
"@backstage/core-app-api": "workspace:^",
"@backstage/core-components": "workspace:^",
"@backstage/core-plugin-api": "workspace:^",
+ "@backstage/frontend-plugin-api": "workspace:^",
"@backstage/plugin-catalog-react": "workspace:^",
"@backstage/plugin-home-react": "workspace:^",
"@backstage/theme": "workspace:^",
diff --git a/plugins/home/src/alpha.tsx b/plugins/home/src/alpha.tsx
new file mode 100644
index 0000000000..c8308f7c0a
--- /dev/null
+++ b/plugins/home/src/alpha.tsx
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2023 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+
+import {
+ coreExtensionData,
+ createExtensionDataRef,
+ createExtensionInput,
+ createPageExtension,
+ createPlugin,
+ createRouteRef,
+} from '@backstage/frontend-plugin-api';
+
+const rootRouteRef = createRouteRef();
+
+/**
+ * @alpha
+ */
+export const titleExtensionDataRef = createExtensionDataRef('title');
+
+const HomepageCompositionRootExtension = createPageExtension({
+ id: 'home',
+ defaultPath: '/home',
+ routeRef: rootRouteRef,
+ inputs: {
+ props: createExtensionInput(
+ {
+ children: coreExtensionData.reactElement.optional(),
+ title: titleExtensionDataRef.optional(),
+ },
+
+ {
+ singleton: true,
+ optional: true,
+ },
+ ),
+ },
+ loader: ({ inputs }) =>
+ import('./components/').then(m => (
+
+ )),
+});
+
+/**
+ * @alpha
+ */
+export default createPlugin({
+ id: 'home',
+ extensions: [HomepageCompositionRootExtension],
+});
diff --git a/yarn.lock b/yarn.lock
index adcd02c577..0fe4bb7768 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7200,6 +7200,7 @@ __metadata:
"@backstage/core-components": "workspace:^"
"@backstage/core-plugin-api": "workspace:^"
"@backstage/dev-utils": "workspace:^"
+ "@backstage/frontend-plugin-api": "workspace:^"
"@backstage/plugin-catalog-react": "workspace:^"
"@backstage/plugin-home-react": "workspace:^"
"@backstage/test-utils": "workspace:^"